#include<cstdio>
using namespace std;
int val,poz,n,m,maxim;
int type;
const int INF=1e10;
struct mytype
{
int lt,ldr,lst;
};
mytype t[1<<18];
int inline maxi(int d,int c)
{
if(d<c)
return c;
return d;
}
void inline calc(int p)
{
t[p].lst=t[2*p].lst;
t[p].ldr=t[2*p+1].ldr;
if(t[2*p].lst==t[2*p].ldr)
{
t[p].lst+=t[2*p+1].lst;
}
if(t[2*p+1].lst==t[2*p+1].ldr)
{
t[p].ldr+=t[2*p].ldr;
}
t[p].lt=maxi(maxi(t[p].lst,t[p].ldr),maxi(t[2*p].lt,t[2*p+1].lt));
}
void inline query()
{
printf("%d\n",t[1].lt);
}
void inline update(int p,int st,int dr,int a,int b)
{
int m;
if(st==dr)
{
t[p].lt=0;
t[p].lst=0;
t[p].ldr=0;
return;
}
m=(st+dr)/2;
if(b<=m)
update(2*p,st,m,a,b);
else
if(a>m)
{
update(2*p+1,m+1,dr,a,b);
}
else
{
update(2*p,st,m,a,m);
update(2*p+1,m+1,dr,m+1,b);
}
calc(p);
}
void inline clear(int p,int st,int dr,int a,int b)
{
int m;
if(st==dr)
{
t[p].lt=1;
t[p].lst=1;
t[p].ldr=1;
return;
}
m=(st+dr)/2;
if(st<=a&&b<=m)
clear(2*p,st,m,a,b);
else
if(m<a&&b<=dr)
clear(2*p+1,m+1,dr,a,b);
else
{
clear(2*p,st,m,a,m);
clear(2*p+1,m+1,dr,m+1,b);
}
calc(p);
}
int main()
{
int i,a=0,b=0;
freopen("hotel.in","r",stdin);
freopen("hotel.out","w",stdout);
scanf("%d%d",&n,&m);
a=1;
b=n;
clear(1,1,n,1,n);
for(i=1;i<=m;i++)
{
scanf("%d",&type);
if(type==3)
{
query();
}
else
if(type==1)
{
scanf("%d%d",&a,&b);
update(1,1,n,a,b);
}
else
{
scanf("%d%d",&a,&b);
clear(1,1,n,a,b);
}
}
return 0;
}