#include <fstream>
using namespace std;
ifstream cin("hotel.in");
ofstream cout("hotel.out");
int n,q;
struct nod
{
int pre,suf,s,mx;
};
nod aint[400005];
int lazy[400005];
void propagate(int node,int st,int dr)
{
if(lazy[node]==0)
return;
if(lazy[node]==-1)
{
int sz=(dr-st+1);
aint[node]={sz,sz,0,sz};
}
else
aint[node]={0,0,dr-st+1,0};
if(st==dr)
{
lazy[node]=0;
return;
}
lazy[2*node]=lazy[node];
lazy[2*node+1]=lazy[node];
lazy[node]=0;
}
void combine(nod &a,nod l,nod r)
{
if(l.s==0)
a.pre=l.mx+r.pre;
else
a.pre=l.pre;
if(r.s==0)
a.suf=l.suf+r.mx;
else
a.suf=r.suf;
a.s=l.s+r.s;
a.mx=max(max(l.mx,r.mx),l.suf+r.pre);
}
void update(int node,int st,int dr,int x,int y,int v)
{
propagate(node,st,dr);
if(st>=x && dr<=y)
{
lazy[node]=v;
propagate(node,st,dr);
return;
}
if(st>y || dr<x)
return;
int mij=(st+dr)>>1;
update(2*node,st,mij,x,y,v);
update(2*node+1,mij+1,dr,x,y,v);
combine(aint[node],aint[2*node],aint[2*node+1]);
}
nod query(int node,int st,int dr,int x,int y,int v)
{
propagate(node,st,dr);
if(st>=x && dr<=y)
return aint[node];
if(st>y || dr<x)
return {0,0,0,0};
int mij=(st+dr)>>1;
nod ans,l,r;
l=query(2*node,st,mij,x,y,v);
r=query(2*node+1,mij+1,dr,x,y,v);
combine(ans,l,r);
return ans;
}
int main()
{
cin>>n>>q;
update(1,1,n,1,n,-1);
int op,x,y;
while(q--)
{
cin>>op;
if(op<=2)
{
cin>>x>>y;
y=x+y-1;
}
if(op==1)
update(1,1,n,x,y,1);
if(op==2)
update(1,1,n,x,y,-1);
if(op==3)
cout<<aint[1].mx<<"\n";
}
return 0;
}