#include <fstream>
#include <algorithm>
#define int long long
using namespace std;
ifstream cin ("hotel.in");
ofstream cout ("hotel.out");
struct Node {
int max_s,pref,suff;
};
Node tree[400005];
int lazy[400005];
void build(int node,int st,int dr) {
lazy[node]=-1;
int len=dr-st+1;
tree[node].max_s=len;
tree[node].pref=len;
tree[node].suff=len;
if (st==dr) {
return;
}
int mid=(st+dr)/2;
build(2*node,st,mid);
build(2*node+1,mid+1,dr);
}
void apply_val(int node,int st,int dr,int val) {
lazy[node]=val;
if (val==1) {
int len=dr-st+1;
tree[node].max_s=len;
tree[node].pref=len;
tree[node].suff=len;
} else {
tree[node].max_s=0;
tree[node].pref=0;
tree[node].suff=0;
}
}
void push(int node,int st,int dr) {
if (lazy[node]!=-1) {
int mid=(st+dr)/2;
apply_val(2*node,st,mid,lazy[node]);
apply_val(2*node+1,mid+1,dr,lazy[node]);
lazy[node]=-1;
}
}
void combine(int node,int st,int dr) {
int mid=(st+dr)/2;
int len_l=mid-st+1;
int len_r=dr-mid;
tree[node].pref=tree[2*node].pref;
if (tree[2*node].pref==len_l) {
tree[node].pref+=tree[2*node+1].pref;
}
tree[node].suff=tree[2*node+1].suff;
if (tree[2*node+1].suff==len_r) {
tree[node].suff+=tree[2*node].suff;
}
tree[node].max_s=max({tree[2*node].max_s,tree[2*node+1].max_s,tree[2*node].suff+tree[2*node+1].pref});
}
void update(int node,int st,int dr,int l,int r,int val) {
if (l<=st && dr<=r) {
apply_val(node,st,dr,val);
return;
}
push(node,st,dr);
int mid=(st+dr)/2;
if (l<=mid) {
update(2*node,st,mid,l,r,val);
}
if (r>mid) {
update(2*node+1,mid+1,dr,l,r,val);
}
combine(node,st,dr);
}
int32_t main() {
int n,p;
cin>>n>>p;
build(1,1,n);
while (p--) {
int type;
cin>>type;
if (type==1) {
int i,m;
cin>>i>>m;
update(1,1,n,i,i+m-1,0);
} else if (type==2) {
int i,m;
cin>>i>>m;
update(1,1,n,i,i+m-1,1);
} else {
cout<<tree[1].max_s<<"\n";
}
}
}