#include <fstream>
#include <vector>
#define int long long
using namespace std;
ifstream cin("hotel.in");
ofstream cout("hotel.out");
int n,q;
struct idk
{
int s,pre,suf,mx;
};
idk bad;
idk aint[400005];
int lazy[400005];
idk combine(idk l,idk r)
{
idk ans;
ans.s=l.s+r.s;
ans.pre=max(l.pre,l.s+r.pre);
ans.suf=max(r.suf,l.suf+r.s);
ans.mx=max(max(l.mx,r.mx),l.suf+r.pre);
return ans;
}
void build(int node,int st,int dr)
{
if(st==dr)
{
aint[node]={1,1,1,1};
return;
}
int mij=(st+dr)>>1;
build(2*node,st,mij);
build(2*node+1,mij+1,dr);
aint[node]=combine(aint[2*node],aint[2*node+1]);
}
void propagate(int node,int st,int dr)
{
if(!lazy[node])
return;
int sz=dr-st+1;
int tot=sz*lazy[node];
aint[node]={tot,max(0LL,tot),max(0LL,tot),max(0LL,tot)};
if(st==dr)
{
lazy[node]=0;
return;
}
lazy[2*node]=lazy[node];
lazy[2*node+1]=lazy[node];
lazy[node]=0;
}
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);
aint[node]=combine(aint[2*node],aint[2*node+1]);
}
idk query(int node,int st,int dr,int x,int y)
{
propagate(node,st,dr);
if(st>=x && dr<=y)
return aint[node];
if(st>y || dr<x)
return bad;
int mij=(st+dr)>>1;
idk l=query(2*node,st,mij,x,y);
idk r=query(2*node+1,mij+1,dr,x,y);
return combine(l,r);
}
signed main()
{
cin>>n>>q;
build(1,1,n);
int op,x,y;
while(q--)
{
cin>>op;
if(op==1)
{
cin>>x>>y;
update(1,1,n,x,x+y-1,-1e9);
}
if(op==2)
{
cin>>x>>y;
update(1,1,n,x,x+y-1,1);
}
if(op==3)
{
cout<<aint[1].mx<<"\n";
}
}
return 0;
}