#include <fstream>
using namespace std;
ifstream in("hotel.in");
ofstream out("hotel.out");
const int N=100005;
int v[3*N],n,p,l[3*N],r[3*N];//v- numarul maxim de camere libere din [st,dr], l numara maxim libere ce incepe din stanga, r din dreapta
void BuildTree(int st,int dr,int nod){
if(st==dr){
v[nod]=1;
l[nod]=1;
r[nod]=1;
return;
}
int m=(st+dr)>>1;
BuildTree(st,m,2*nod);
BuildTree(m+1,dr,2*nod+1);
v[nod]=dr-st+1;
l[nod]=dr-st+1;
r[nod]=dr-st+1;
}
inline int max(int a,int b){return a>b? a:b;}
void Update1(int st,int dr,int x,int y,int nod){
if(x<=st && dr<=y){
v[nod]=0;
l[nod]=0;
r[nod]=0;
return;
}
int m=(st+dr)>>1;
if(v[nod]==dr-st+1){
l[2*nod]=r[2*nod]=v[2*nod]=m-st+1;
l[2*nod+1]=r[2*nod+1]=v[2*nod+1]=dr-m;
}
if(v[nod]==0){
l[2*nod]=r[2*nod]=v[2*nod]=0;
l[2*nod+1]=r[2*nod+1]=v[2*nod+1]=0;
}
if(x<=m){
Update1(st,m,x,y,2*nod);
}
if(y>m){
Update1(m+1,dr,x,y,2*nod+1);
}
l[nod]=l[2*nod];
r[nod]=r[2*nod+1];
if(r[2*nod+1]==dr-m){
r[nod]=r[2*nod+1]+r[2*nod];
}
if(l[2*nod]==m-st+1){
l[nod]=l[2*nod]+l[2*nod+1];
}
v[nod]=max(max(v[2*nod],v[2*nod+1]),r[2*nod]+l[2*nod+1]);
}
void Update2(int st,int dr,int x,int y,int nod){
if(x<=st && dr<=y){
v[nod]=dr-st+1;
l[nod]=dr-st+1;
r[nod]=dr-st+1;
return;
}
int m=(st+dr)>>1;
if(v[nod]==dr-st+1){
l[2*nod]=r[2*nod]=v[2*nod]=m-st+1;
l[2*nod+1]=r[2*nod+1]=v[2*nod+1]=dr-m;
}
if(v[nod]==0){
l[2*nod]=r[2*nod]=v[2*nod]=0;
l[2*nod+1]=r[2*nod+1]=v[2*nod+1]=0;
}
if(x<=m){
Update2(st,m,x,y,2*nod);
}
if(y>m){
Update2(m+1,dr,x,y,2*nod+1);
}
l[nod]=l[2*nod];
r[nod]=r[2*nod+1];
if(r[2*nod+1]==dr-m){
r[nod]=r[2*nod+1]+r[2*nod];
}
if(l[2*nod]==m-st+1){
l[nod]=l[2*nod]+l[2*nod+1];
}
v[nod]=max(max(v[2*nod],v[2*nod+1]),r[2*nod]+l[2*nod+1]);
}
void Read(){
int i,op,x,y;
for(i=1;i<=p;++i){
in>>op;
if(op==3){
out<<v[1]<<"\n";
continue;
}
if(op==1){
in>>x>>y;
y=x+y-1;
Update1(1,n,x,y,1);
continue;
}
if(op==2){
in>>x>>y;
y=y+x-1;
Update2(1,n,x,y,1);
continue;
}
}
}
int main(){
in>>n>>p;
BuildTree(1,n,1);
Read();
return 0;
}