#include<bits/stdc++.h>
#define maxN 100005
using namespace std;
int n,p,c,p1,p2,m;
typedef struct tip
{
int val;
int st;
int dr;
};
tip A[4*maxN+5];
void build(int nod,int st,int dr)
{
A[nod].val=(dr-st+1);
A[nod].st=(dr-st+1);
A[nod].dr=(dr-st+1);
if(st==dr) return;
int mid=(st+dr)>>1;
build(2*nod,st,mid);
build(2*nod+1,mid+1,dr);
}
void update(int nod,int st,int dr,int a,int b,int x)
{
if(a<=st && dr<=b)
{
if(x==1)
{
A[nod].val=0;
A[nod].st=0;
A[nod].dr=0;
}
else
{
A[nod].val=(dr-st+1);
A[nod].st=(dr-st+1);
A[nod].dr=(dr-st+1);
}
}
else
{
if(!A[nod].val)
{
A[2*nod]={0,0,0};
A[2*nod+1]={0,0,0};
}
int mid=(st+dr)>>1;
if(a<=mid) update(2*nod,st,mid,a,b,x);
if(b>mid) update(2*nod+1,mid+1,dr,a,b,x);
int l=mid-st+1;
int l2=dr-mid;
////MergeINfo
A[nod].val=max(max(A[2*nod].val,A[2*nod+1].val),A[2*nod].dr+A[2*nod+1].st);
if(A[2*nod].val==l)
{
A[nod].st=A[2*nod].val+A[2*nod+1].st;
}
else A[nod].st=A[2*nod].st;
if(A[2*nod+1].val==l2)
{
A[nod].dr=A[2*nod+1].val+A[2*nod].dr;
}
else A[nod].dr=A[2*nod+1].dr;
////
}
}
int main()
{
freopen("hotel.in","r",stdin);
freopen("hotel.out","w",stdout);
scanf("%d%d",&n,&p);
build(1,1,n);
for(int i=1;i<=p;i++)
{
scanf("%d",&c);
if(c==1)
{
scanf("%d%d",&p1,&m);
p2=p1+m-1;
update(1,1,n,p1,p2,1);
}
else
if(c==2)
{
scanf("%d%d",&p1,&m);
p2=p1+m-1;
update(1,1,n,p1,p2,-1);
}
else
{
printf("%d\n",A[1].val);
}
}
return 0;
}