#include<fstream>
using namespace std;
ifstream f("hotel.in"); ofstream g("hotel.out");
struct {int st,dr,t;} A[300003];
void build(int k, int st, int dr)
{ A[k].st=A[k].dr=A[k].t=dr-st+1;
if(st<dr)
{ int m=(st+dr)>>1, l=(k<<1);
build(l,st,m);
build(l+1,m+1,dr);
}
}
void update(int k,int st,int dr,int i,int j,int op)
// daca op=1 se ocupa camerele din intervalul i...j
// daca op=2 se elibereaza camerele din intervalul i...j
// modificarea se face pt. intervalul st...dr din Aore.
{ if (i<=st && dr<=j) // toate camerele din intervalul curent sunt ocupate sau eliberate
{ if(op==2) A[k].t=A[k].st=A[k].dr=dr-st+1;
else A[k].t=A[k].st=A[k].dr=0;
return;
}
// daca toate camerele erau in starea opusa (ocupate sau libere)
// transferam proprietatea nodurilor fii adica
// (st,dr) tot liber inseamna ca (st,m) liber si (m+1,dr) liber
// si updatam pe urma aceste subintervale
int l=(k<<1), m=(st+dr)>>1;
if(A[k].t==dr-st+1)
{ A[l].t=A[l].st=A[l].dr=m-st+1;
A[l+1].t=A[l+1].st=A[l+1].dr=dr-m;
}
else
if(A[k].t==0)
A[l].t=A[l].st=A[l].dr=A[l+1].t=A[l+1].st=A[l+1].dr=0;
if(i<=m) update(l,st,m,i,j,op);
if(m<j) update(l+1,m+1,dr,i,j,op);
A[k].t=max(A[l].t,A[l].dr+A[l+1].st);
A[k].t=max(A[k].t,A[l+1].t);
if(A[l].t==m-st+1) A[k].st=A[l].t+A[l+1].st; else A[k].st=A[l].st;
if(A[l+1].t==dr-m) A[k].dr=A[l].dr+A[l+1].t; else A[k].dr=A[l+1].dr;
}
int main()
{ int n,p,op,s,nr;
f>>n>>p;
build(1,1,n);
while(p--)
{ f>>op;
if(op==3) g<<A[1].t<<"\n"; else f>>s>>nr, update(1,1,n,s,s+nr-1,op);
}
g.close(); return 0;
}