#include <bits/stdc++.h>
using namespace std;
ifstream in("hotel.in");
ofstream out("hotel.out");
#define Nmax 100013
int nquery,n,op,a,b,i,j,k;
struct arbore {
int pref;
int suf;
int ans;
};
arbore Stree[Nmax*4];
void assign(int nod, int value)
{
Stree[nod].ans=Stree[nod].suf=Stree[nod].pref=value;
}
void update (int nod,int st,int dr,int x, int y,int value)
{
if(st>dr || st>y || dr<x) return ;
if (st>=x && dr<=y)
{
if (value==0) assign(nod,dr-st+1);
else assign(nod,0);
return ;
}
int middle=(st+dr)/2;
if (Stree[nod].ans==0)
{
assign(nod*2,0);
assign(nod*2+1,0);
}
if (Stree[nod].ans==dr-st+1)
{
assign(nod*2,middle-st+1);
assign(nod*2+1,dr-middle);
}
update(nod*2,st,middle,x,y,value);
update(nod*2+1,middle+1,dr,x,y,value);
Stree[nod].ans=max(Stree[nod*2].ans,Stree[nod*2+1].ans);
Stree[nod].ans=max(Stree[nod*2].suf+Stree[nod*2+1].pref,Stree[nod].ans);
Stree[nod].suf=Stree[nod*2+1].suf;
Stree[nod].pref=Stree[nod*2].pref;
if (Stree[nod*2].pref==middle-st+1) Stree[nod].pref+=Stree[nod*2+1].pref;
if (Stree[nod*2+1].suf==dr-middle) Stree[nod].suf+=Stree[nod*2].suf;
}
int main(void)
{
in>>n>>nquery;
for (i=1;i<=n;++i)
update(1,1,n,i,i,0);
while(nquery--)
{
in>>op;
if (op==3) out<<Stree[1].ans<<"\n";
if (op==2)
{
in>>a>>b;
update(1,1,n,a,a+b-1,0);
}
if (op==1)
{
in>>a>>b;
update(1,1,n,a,a+b-1,1);
}
}
return 0;
}