#include <stdio.h>
#define Nmax 100005
struct arbore { int li,ls; char v; };
struct maxheap { int key,lung; };
int N,P,a,b;
arbore arb[3*Nmax+10];
maxheap heap[Nmax];
int poz[Nmax],dimheap;
int limi,lims; //limita inferioara respectiv superioara de ocupare care contine [a,b]
//BINARY SEARCH TREE
void etichetare(int st,int dr,int nod)
{
int m=(st+dr)>>1;
arb[nod].li=st;
arb[nod].ls=dr;
if (st==dr) return;
etichetare(st,m,nod<<1);
etichetare(m+1,dr,(nod<<1)+1);
}
int liber(int st,int dr,int nod)
{
int m=(arb[nod].li+arb[nod].ls)>>1;
if ((st<=arb[nod].li)&&(arb[nod].ls<=dr))
return arb[nod].v;
if (arb[nod].v!=1) return arb[nod].v;
if (st<=m)
if (dr<=m) return liber(st,dr,nod<<1);
else return liber(st,dr,nod<<1)+liber(st,dr,(nod<<1)+1);
else return liber(st,dr,(nod<<1)+1);
}
int cauta_dreapta(int st,int nod)
{
int i,li=st,m,dr=N+1;
while (dr-st>0)
{
m=(dr+st)>>1;
if (liber(st,m,1)==0) st=m+1;
else dr=m-1;
}
if (dr+5<N) i=dr+5;
else i=N;
while (i>=li)
{
if (liber(li,i,1)==0) return i;
--i;
}
return li-1;
/* int i;
for (i=N;i>=st;--i)
if (liber(st,i,1)==0) return i;
return st-1;*/
}
int cauta_stanga(int dr,int nod)
{
int i,ls=dr,m,st=0;
while (dr-st>0)
{
m=(dr+st)>>1;
if (liber(m,dr,1)==0) dr=m-1;
else st=m+1;
}
if (st-5<1) i=1;
else i=st-5;
while (i<=ls)
{
if (liber(i,ls,1)==0) return i;
++i;
}
return ls+1;
/* int i;
for (i=1;i<=dr;++i)
if (liber(i,dr,1)==0) return i;
return dr+1;*/
}
void cazare(int st,int dr,int nod)
{
int m=(arb[nod].li+arb[nod].ls)>>1;
if ((st<=arb[nod].li)&&(arb[nod].ls<=dr))
{
arb[nod].v=2;
return;
}
if (arb[nod].v==0) { arb[nod<<1].v=0;arb[(nod<<1)+1].v=0; }
if (st<=m)
if (dr<=m) cazare(st,dr,nod<<1);
else {
cazare(st,dr,nod<<1);
cazare(st,dr,(nod<<1)+1);
}
else cazare(st,dr,(nod<<1)+1);
if ((arb[nod<<1].v==2)&&(arb[(nod<<1)+1].v==2)) arb[nod].v=2;
else arb[nod].v=1;
}
void evacuare(int st,int dr,int nod)
{
int m=(arb[nod].li+arb[nod].ls)>>1;
if ((st<=arb[nod].li)&&(arb[nod].ls<=dr))
{
arb[nod].v=0;
return;
}
if (arb[nod].v==2)
{
arb[nod<<1].v=2;
arb[(nod<<1)+1].v=2;
}
if (st<=m)
if (dr<=m) evacuare(st,dr,nod<<1);
else {
evacuare(st,dr,nod<<1);
evacuare(st,dr,(nod<<1)+1);
}
else evacuare(st,dr,(nod<<1)+1);
if ((arb[nod<<1].v==0)&&(arb[(nod<<1)+1].v==0)) arb[nod].v=0;
else arb[nod].v=1;
}
//MAX-HEAP
void go_down(int p)
{
int fs,fd;
maxheap aux;
while ((p<<1)<=dimheap)
{
fs=p<<1;
if (fs<dimheap) fd=fs+1;
else fd=fs;
if (heap[fs].lung>heap[fd].lung)
if (heap[fs].lung>heap[p].lung)
{
aux=heap[fs];
heap[fs]=heap[p];
heap[p]=aux;
poz[heap[fs].key]=fs;
poz[heap[p].key]=p;
p=fs;
}
else break;
else if (heap[fd].lung>heap[p].lung)
{
aux=heap[fd];
heap[fd]=heap[p];
heap[p]=aux;
poz[heap[fd].key]=fd;
poz[heap[p].key]=p;
p=fd;
}
else break;
}
}
void come_up(int p)
{
int t;
maxheap aux;
while (p>1)
{
t=p>>1;
if (heap[t].lung<heap[p].lung)
{
aux=heap[t];
heap[t]=heap[p];
heap[p]=aux;
poz[heap[p].key]=p;
poz[heap[t].key]=t;
p=t;
}
else return;
}
}
void heap_out(int p)
{
int who;
heap[p]=heap[dimheap--];
who=heap[p].key;
poz[who]=p;
come_up(poz[who]);
go_down(poz[who]);
}
void heap_in(int p,int lungime)
{
int who;
heap[++dimheap].key=p;
heap[dimheap].lung=lungime;
who=p;
poz[who]=dimheap;
come_up(poz[who]);
}
//MAIN
int main()
{
int cod;
freopen("hotel.in","r",stdin);
freopen("hotel.out","w",stdout);
scanf("%d %d",&N,&P);
etichetare(0,N+1,1);
cazare(0,0,1);
cazare(N+1,N+1,1);
poz[1]=1;
heap[dimheap=1].key=1;
heap[1].lung=N;
while (P)
{
scanf("%d",&cod);
if (cod==3) if (dimheap==0) printf("%d\n",0);
else printf("%d\n",heap[1].lung);
else
{
scanf("%d %d",&a,&b);
b=a+b-1;
if (cod==1)
{
cazare(a,b,1);
limi=cauta_stanga(a-1,1);
lims=cauta_dreapta(b+1,1);
heap_out(poz[limi]);
if (limi<a) heap_in(limi,a-limi);
if (lims>b) heap_in(b+1,lims-b);
}
else
{
evacuare(a,b,1);
limi=cauta_stanga(a-1,1);
lims=cauta_dreapta(b+1,1);
if (limi<a) heap_out(poz[limi]);
if (lims>b) heap_out(poz[b+1]);
heap_in(limi,lims-limi+1);
}
}
--P;
}
return 0;
}