#include <bits/stdc++.h>
using namespace std;
ifstream fin("hotel.in");
ofstream fout("hotel.out");
struct nod
{
int lazy, st, dr, sol;
}t[1000000];
void build(int tp, int tl, int tr)
{
if(tl==tr) t[tp].st=t[tp].dr=t[tp].sol=1;
else
{
int m=(tl+tr)/2;
build(tp*2, tl, m);
build(tp*2+1, m+1, tr);
t[tp].st=t[tp].sol=t[tp].dr=(tr-tl+1);
}
}
void push(int tp, int tl, int tr)
{
if(t[tp].lazy==1)
{
t[tp*2].st=t[tp*2].dr=t[tp*2].sol=0;
t[tp*2].lazy=1;
t[tp*2+1].st=t[tp*2+1].dr=t[tp*2+1].sol=0;
t[tp*2+1].lazy=1;
}
else if(t[tp].lazy==2)
{
int m=(tl+tr)/2;
t[tp*2].st=t[tp*2].dr=t[tp*2].sol=m-tl+1;
t[tp*2].lazy=2;
t[tp*2+1].st=t[tp*2+1].dr=t[tp*2+1].sol=tr-m;
t[tp*2+1].lazy=2;
}
t[tp].lazy=0;
}
void update(int tp, int tl, int tr, int ti, int l, int r)
{
if(l>r) return;
if(tl==l&&tr==r)
{
if(ti==1)
{
t[tp].st=t[tp].dr=t[tp].sol=0;
t[tp].lazy=1;
}
else
{
t[tp].st=t[tp].dr=t[tp].sol=tr-tl+1;
t[tp].lazy=2;
}
}
else
{
push(tp, tl, tr);
int m=(tl+tr)/2;
update(tp*2, tl, m, ti, l, min(m, r));
update(tp*2+1, m+1, tr, ti, max(l, m+1), r);
t[tp].st=t[tp*2].st;
if(t[tp*2].st==m-tl+1) t[tp].st+=t[tp*2+1].st;
t[tp].dr=t[tp*2+1].dr;
if(t[tp*2+1].dr==tr-m) t[tp].dr+=t[tp*2].dr;
t[tp].sol=max(t[tp*2+1].sol, t[tp*2].sol);
t[tp].sol=max(t[tp].sol, t[tp*2].dr+t[tp*2+1].st);
}
}
int query()
{
return max(t[1].sol, max(t[1].st, t[1].dr));
}
int n, q;
int main()
{
fin>>n>>q;
build(1, 1, n);
int c;
while(q--)
{
fin>>c;
if(c==3) fout<<query()<<"\n";
else
{
int x, y;
fin>>x>>y;
update(1, 1, n, c, x, x+y-1);
}
}
return 0;
}