#include <bits/stdc++.h>
using namespace std;
const int Lim = 1e6, Nmax = 1e5+1;
char s[Lim];
int n,q,ans,sum;
int st[4*Nmax],dr[4*Nmax],nr[4*Nmax];
int p = Lim-1;
struct nod{
int val;
bool lazy;
}adi[4*Nmax];
void next()
{
if(++p == Lim)
fread(s,1,Lim,stdin), p = 0;
}
void Get(int &x)
{
for(;!isdigit(s[p]);next());
for(x=0;isdigit(s[p]);next())
x = x*10+s[p]-'0';
}
void Update(int nod,int l,int r,int a,int b,int val)
{
if(a<=l&&r<=b)
{
if(val==0)
adi[nod].val = st[nod] = dr[nod] = nr[nod] = 0;
else
adi[nod].val = st[nod] = dr[nod] = nr[nod] = r-l+1;
adi[nod].lazy = true;
return;
}
if(adi[nod].lazy)
{
int mij = (l+r)/2;
if(adi[nod].val != 0)
{st[2*nod] = dr[2*nod] = nr[2*nod] = adi[2*nod].val = mij-l+1;
st[2*nod+1] = dr[2*nod+1] = nr[2*nod+1] = adi[2*nod+1].val = r-mij;}
else
{
st[2*nod] = dr[2*nod] = nr[2*nod] = adi[2*nod].val = 0;
st[2*nod+1] = dr[2*nod+1] = nr[2*nod+1] = adi[2*nod+1].val = 0;
}
adi[2*nod].lazy = adi[2*nod+1].lazy = true;
adi[nod].lazy = false;
}
int mij = (l+r)/2;
if(a<=mij)
Update(2*nod,l,mij,a,b,val);
if(mij<b)
Update(2*nod+1,mij+1,r,a,b,val);
st[nod] = st[2*nod];
dr[nod] = dr[2*nod+1];
nr[nod] = nr[2*nod]+nr[2*nod+1];
if(st[2*nod] == mij-l+1)
st[nod] += st[2*nod+1];
if(dr[2*nod+1] == r-mij)
dr[nod] += dr[2*nod];
adi[nod].val = max({adi[2*nod].val,adi[2*nod+1].val,st[nod],dr[nod],dr[2*nod]+st[2*nod+1]});
}
void Query(int nod,int l,int r,int a,int b)
{
if(a<=l&&r<=b)
{
ans = max(ans,max(adi[nod].val,sum+st[nod]));
sum = max(sum + st[nod], dr[nod]);
return;
}
if(adi[nod].lazy)
{
int mij = (l+r)/2;
if(adi[nod].val != 0)
{st[2*nod] = dr[2*nod] = nr[2*nod] = adi[2*nod].val = mij-l+1;
st[2*nod+1] = dr[2*nod+1] = nr[2*nod+1] = adi[2*nod+1].val = r-mij;}
else
{
st[2*nod] = dr[2*nod] = nr[2*nod] = adi[2*nod].val = 0;
st[2*nod+1] = dr[2*nod+1] = nr[2*nod+1] = adi[2*nod+1].val = 0;
}
adi[2*nod].lazy = adi[2*nod+1].lazy = true;
adi[nod].lazy = false;
}
int mij = (l+r)/2;
if(a<=mij)
Query(2*nod,l,mij,a,b);
if(mij<b)
Query(2*nod+1,mij+1,r,a,b);
st[nod] = st[2*nod];
dr[nod] = dr[2*nod+1];
nr[nod] = nr[2*nod]+nr[2*nod+1];
if(st[2*nod] == mij-l+1)
st[nod] += st[2*nod+1];
if(dr[2*nod+1] == r-mij)
dr[nod] += dr[2*nod];
adi[nod].val = max({adi[2*nod].val,adi[2*nod+1].val,st[nod],dr[nod],dr[2*nod]+st[2*nod+1]});
}
void Build(int nod,int l,int r)
{
if(l==r)
{
adi[nod].val = st[nod] = dr[nod] = nr[nod] = 1;
adi[nod].lazy = false;
return;
}
int mij = (l+r)/2;
Build(2*nod,l,mij);
Build(2*nod+1,mij+1,r);
adi[nod].val = st[nod] = dr[nod] = nr[nod] = nr[2*nod]+nr[2*nod+1];
}
int main()
{
freopen("hotel.in","r",stdin);
freopen("hotel.out","w",stdout);
Get(n);
Get(q);
Build(1,1,n);
for(int i=1;i<=q;i++)
{
int c;
Get(c);
if(c==1)
{
int a,b;
Get(a);
Get(b);
b += a-1;
Update(1,1,n,a,b,0);
}
else if(c==2)
{
int a,b;
Get(a);
Get(b);
b += a-1;
Update(1,1,n,a,b,1);
}
else
{
sum = ans = 0;
Query(1,1,n,1,n);
printf("%d\n",ans);
}
}
return 0;
}