#include <stdio.h>
#define N 1<<18
struct interv
{
int st,dr,best;
};
interv arb[N];
int n,p,tip,inc,sf;
char flag;
/*
st=nr de camere libere consecutive care incep din st
dr=nr de camere libere consecutive care se termin in dr
best=nr maxim de camere consecutiv la nodul curent
*/
void op(int nod,int val)
{
arb[nod].st=arb[nod].dr=arb[nod].best=val;
}
inline int max(int a,int b)
{
return a>b ? a : b;
}
void cstr(int nod,int x,int y)
{
op(nod,y-x+1);
if (x==y)
return;
int mij=(x+y)/2;
cstr(nod*2,x,mij);
cstr(nod*2+1,mij+1,y);
}
void update(int nod,int x,int y)
{
if (inc<=x && y<=sf)
{
int val=(!flag) ? 0 : y-x+1;
op(nod,val);
return;
}
if (x==y)
return ;
int mij=(x+y)/2;
if (!arb[nod].best)//intervalul (x,mij)
{
op(nod*2,0);
op(nod*2+1,0);
}
if (arb[nod].best==y-x+1)//intervalul (mij+1,dr)
{
op(nod*2,mij-x+1);
op(nod*2+1,y-mij);
}
if (sf<x || inc>y)//intervalele nu se intersecteaza
return;
if (inc<=mij)
update(2*nod,x,mij);
if (sf>mij)
update(2*nod+1,mij+1,y);
if (arb[2*nod].st==mij-x+1)
arb[nod].st=arb[2*nod].st+arb[2*nod+1].st;
else
arb[nod].st=arb[2*nod].st;
if (arb[2*nod+1].dr==y-mij)
arb[nod].dr=arb[2*nod+1].dr+arb[2*nod].dr;
else
arb[nod].dr=arb[2*nod+1].dr;
arb[nod].best=max(arb[2*nod].best,arb[2*nod+1].best);
arb[nod].best=max(arb[nod].best,arb[2*nod].dr+arb[nod*2+1].st);
}
int main()
{
freopen("hotel.in","r",stdin);
freopen("hotel.out","w",stdout);
scanf("%d%d",&n,&p);
int i;
cstr(1,1,n);
for (i=1; i<=p; i++)
{
scanf("%d",&tip);
if (tip==1 || tip==2)
{
scanf("%d%d",&inc,&sf);
sf=inc+sf-1;
flag= (tip==1) ? 0 : 1;
update(1,1,n);
}
if (tip==3)
printf("%d\n",arb[1].best);
}
return 0;
}