#include <fstream>
using namespace std;
ifstream fin("hotel.in");
ofstream fout("hotel.out");
int arb[400001], n, m, lazy[800001];
int prefix[800005], sufix[800005], submax[800005], sumatotala[800005];
void combina_info_din_doua_noduri(int nod1, int nod2, int nod) //nodurile trb sa fie vecine!!
{
prefix[nod] = max(prefix[nod1], sumatotala[nod1]+prefix[nod2]);
sufix[nod] = max(sufix[nod2], sumatotala[nod2]+sufix[nod1]);
sumatotala[nod] = sumatotala[nod1] + sumatotala[nod2];
submax[nod] = max(max(submax[nod1], submax[nod2]), prefix[nod2] + sufix[nod1]);
}
void constr(int nod, int st, int dr)
{
if(st == dr)
{
prefix[nod] = sufix[nod] = submax[nod] = sumatotala[nod] = 1;
return;
}
int mij = (st+dr)/2;
constr(nod*2, st, mij);
constr(nod*2+1, mij+1, dr);
combina_info_din_doua_noduri(nod*2, nod*2+1, nod);
}
void update_lazy(int nod, int st, int dr)
{
if(lazy[nod] == 0) //o sg camera,
{
prefix[nod] = sufix[nod] = submax[nod] = sumatotala[nod] = dr-st+1;
}
else
{
if(lazy[nod] == 1) //sub sunt numai camere ocupate
}
if(st != dr && lazy[nod] >= 0) //daca mai are noduri urmatoare le dam aceeasi valoare
lazy[nod*2] = lazy[nod*2+1] = lazy[nod];
//marcam ca trecut
lazy[nod] = -1;
}
void update(int nod, int st, int dr, int a, int b, int val)
{
if(lazy[nod]!= 0) //nodul curent trebuie actualizat
{
arb[nod] += val; //adaugam cat trebuie la efectiv valoare maxima (ordinea valorilor ar trebui sa ramana aceeasi - cele maxime vor ramane maxime)
if(st != dr)
{
lazy[nod*2] += lazy[nod]; //adaugam la urmatoarele cu ce valoare vor trebui actualizate in viitor
lazy[nod*2+1] += lazy[nod];
}
lazy[nod] = 0; //am updatat,acum il facem din nou zero
}
if(a >dr || b < st || st > dr)
return;
if(a<=st && dr<=b)
{
arb[nod]+=val;
if(st != dr)
{
lazy[nod*2] += val;
lazy[nod*2+1] += val;
}
return;
}
int mij = (st + dr)/2;
adauga(nod*2, st, mij, a, b, val);
adauga(nod*2+1, mij+1, dr, a, b, val);
arb[nod] = max(arb[nod*2], arb[nod*2+1]);
}
int query(int nod, int st, int dr, int a, int b)
{
if(a<= st && dr<= b)
return submax[nod];
int mij = (st+dr)/2;
int aux = nod;
query(nod*2, st, mij, a, b);
query(nod*2+1, mij+1, dr, a, b);
combina_info_din_doua_noduri(nod*2, nod*2+1, aux);
return submax[aux];
}
int main()
{
int i, tip, a, b, val;
fin >> n >> m;
for (i = 1; i<= m; i++)
{
fin >> tip;
if(tip == 3)
fout << query(1, 1, n, a, b) << '\n';
else
{
fin >> a >> b
if(tip == 2)
{
update(1,1,n,a, b, 0);
}
else
{
update(1,1,n,a, b, 1);
}
}
}
}