#include <bits/stdc++.h>
using namespace std;
int n,m;
struct types{
int maxim;int rightmax;int leftmax;
};
vector<types> arb;
vector<int> lazy;
void nodeUpd(int pos,int val){
arb[pos].maxim = arb[pos].leftmax = arb[pos].rightmax = val;
}
void arbVerif(int l,int r,int pos){
arb[pos].maxim = max({arb[pos*2].maxim,arb[pos*2+1].maxim,arb[pos*2].rightmax + arb[pos*2+1].leftmax});
arb[pos].leftmax = arb[pos*2].leftmax;
arb[pos].rightmax = arb[pos*2+1].rightmax;
int mid=(l+r)/2;
if(arb[pos*2].maxim == mid-l+1)
arb[pos].leftmax = max(arb[pos].leftmax, arb[pos*2].maxim + arb[pos*2+1].leftmax);
if(arb[pos*2+1].maxim == r-(mid+1)+1)
arb[pos].rightmax = max(arb[pos].rightmax, arb[pos*2].rightmax + arb[pos*2+1].maxim);
}
void lazyCheck(int l,int r,int pos){
if(lazy[pos]!=0){
if(lazy[pos] == 1)
nodeUpd(pos,0);
if(lazy[pos] == 2)
nodeUpd(pos,r-l+1);
if(l!=r)
lazy[pos*2] = lazy[pos*2+1] = lazy[pos];
lazy[pos] = 0;
}
}
void create(int l,int r,int pos){
if(l==r){
nodeUpd(pos,1);
return;
}
int mid = (l+r)/2;
create(l,mid,pos*2);
create(mid+1,r,pos*2+1);
arbVerif(l,r,pos);
}
void upd(int l,int r,int pos,int fl,int fr,int c){
lazyCheck(l,r,pos);
if(l>=fl and r<=fr){
lazy[pos] = c;
lazyCheck(l, r, pos);
return;
}
int mid = (l+r)/2;
if(mid>=fl)
upd(l,mid,pos*2,fl,fr,c);
if(mid+1<=fr)
upd(mid+1,r,pos*2+1,fl,fr,c);
lazyCheck(l,mid,pos*2);
lazyCheck(mid+1,r,pos*2+1);
arbVerif(l,r,pos);
}
int main() {
ifstream cin("hotel.in");
ofstream cout("hotel.out");
cin>>n>>m;
arb.resize(n*4+1);
lazy.resize(n*4+1,0);
create(1,n,1);
for(int i=1;i<=m;i++){
int c;
cin>>c;
if(c==1 or c==2){
int fl,fr,x;
cin>>fl>>x;
fr = (fl + x) - 1;
upd(1,n,1,fl,fr,c);
}else
cout<<arb[1].maxim<<"\n";
}
}