#include <bits/stdc++.h>
using namespace std;
#define int long long
struct node{
int ras;
int pref;
int suf;
int sum;
}aint[400005];
int lazy[400005];
int v[100005];
void propagate(int node, int st, int dr){
if(lazy[node]==1000001){
aint[node].pref=dr-st+1;
aint[node].suf=dr-st+1;
aint[node].sum=dr-st+1;
aint[node].ras=dr-st+1;
lazy[2*node]=lazy[node];
lazy[2*node+1]=lazy[node];
lazy[node]=0;
}
else if(lazy[node]==-1000001){
aint[node].pref=-1000001;
aint[node].suf=-1000001;
aint[node].sum=-1000001;
aint[node].ras=-1000001;
lazy[2*node]=lazy[node];
lazy[2*node+1]=lazy[node];
lazy[node]=0;
}
}
void build(int node, int st, int dr){
if(st==dr){
aint[node].sum=v[st];
aint[node].pref=v[st];
aint[node].suf=v[st];
aint[node].ras=v[st];
}
else{
int mid=(st+dr)/2;
build(2*node, st, mid);
build(2*node+1, mid+1, dr);
aint[node].pref=max(aint[2*node].pref, max(aint[2*node].sum, max(aint[2*node].sum+aint[2*node+1].pref, aint[2*node].sum+aint[2*node+1].sum)));
aint[node].suf=max(aint[2*node+1].suf, max(aint[2*node+1].sum, max(aint[2*node+1].sum+aint[2*node].suf, aint[2*node].sum+aint[2*node+1].sum)));
aint[node].ras=max(aint[2*node].pref, max(aint[2*node].sum, max(aint[2*node].sum+aint[2*node+1].pref, aint[2*node].sum+aint[2*node+1].sum)));
aint[node].ras=max(aint[node].ras, max(aint[2*node+1].suf, max(aint[2*node+1].sum, aint[2*node+1].sum+aint[2*node].suf)));
aint[node].ras=max(aint[node].ras, max(aint[2*node].ras, aint[2*node+1].ras));
aint[node].ras=max(aint[node].ras, aint[2*node].suf+aint[2*node+1].pref);
aint[node].sum=aint[2*node].sum+aint[2*node+1].sum;
}
}
void update(int node, int st, int dr, int a, int b, int val){
propagate(node, st, dr);
if(a<=st && dr<=b)
lazy[node]=val;
else{
int mid=(st+dr)/2;
if(a<=mid)
update(2*node, st, mid, a, b, val);
if(mid+1<=b)
update(2*node+1, mid+1, dr, a, b, val);
propagate(2*node, st, mid);
propagate(2*node+1, mid+1, dr);
aint[node].pref=max(aint[2*node].pref, max(aint[2*node].sum, max(aint[2*node].sum+aint[2*node+1].pref, aint[2*node].sum+aint[2*node+1].sum)));
aint[node].suf=max(aint[2*node+1].suf, max(aint[2*node+1].sum, max(aint[2*node+1].sum+aint[2*node].suf, aint[2*node].sum+aint[2*node+1].sum)));
aint[node].ras=max(aint[2*node].pref, max(aint[2*node].sum, max(aint[2*node].sum+aint[2*node+1].pref, aint[2*node].sum+aint[2*node+1].sum)));
aint[node].ras=max(aint[node].ras, max(aint[2*node+1].suf, max(aint[2*node+1].sum, aint[2*node+1].sum+aint[2*node].suf)));
aint[node].ras=max(aint[node].ras, max(aint[2*node].ras, aint[2*node+1].ras));
aint[node].ras=max(aint[node].ras, aint[2*node].suf+aint[2*node+1].pref);
aint[node].sum=aint[2*node].sum+aint[2*node+1].sum;
}
}
node max1;
int ok=0;
void query(int node, int st, int dr, int a, int b){
propagate(node, st, dr);
if(a<=st && dr<=b){
if(ok==1){
max1.ras=max(max1.ras, max(aint[node].ras, max(max1.sum, max(aint[node].sum, max1.sum+aint[node].sum))));
max1.ras=max(max1.ras, max(max1.pref, max1.sum+aint[node].pref));
max1.ras=max(max1.ras, max(aint[node].suf, aint[node].sum+max1.suf));
max1.ras=max(max1.ras, max1.suf+aint[node].pref);
max1.pref=max(max1.pref, max(max1.sum, max(max1.sum+aint[node].pref, max1.sum+aint[node].sum)));
max1.suf=max(aint[node].suf, max(aint[node].sum, max(aint[node].sum+max1.suf, aint[node].sum+max1.sum)));
max1.sum=max1.sum+aint[node].sum;
}
else{
ok=1;
max1.pref=aint[node].pref;
max1.suf=aint[node].suf;
max1.sum=aint[node].sum;
max1.ras=aint[node].ras;
}
}
else{
int mid=(st+dr)/2;
if(a<=mid)
query(2*node, st, mid, a, b);
if(mid+1<=b)
query(2*node+1, mid+1, dr, a, b);
}
}
int32_t main(){
ifstream cin ("hotel.in");
ofstream cout ("hotel.out");
int n, q, a, b, c;
cin >> n >> q;
for(int i=1; i<=n; i++)
v[i]=1;
build(1, 1, n);
for(int i=1; i<=q; i++){
cin >> c;
if(c!=3){
cin >> a >> b;
if(c==1)
update(1, 1, n, a, a+b-1, -1000001);
else
update(1, 1, n, a, a+b-1, 1000001);
}
else{
int z=0;
ok=0;
max1.ras=max1.pref=max1.suf=-1e18;
max1.sum=0;
query(1, 1, n, 1, n);
cout << max(max1.ras, z) << '\n';
}
}
return 0;
}