#include <fstream>
using namespace std;
const int Nmax = 100005;
ifstream cin("hotel.in");
ofstream cout("hotel.out");
struct chestie
{
int sol, pre,suf;
}arbore[Nmax * 4];
int n ,m, a, b ;
void build(int,int,int);
void update(int,int,int,int,int,int);
int query(int,int,int,int);
int main() {
int tip;
cin >> n >> m;
build(1,1,n);
while(m--)
{
cin >> tip;
if(tip == 3)
cout << arbore[1].sol << '\n';
else
{
cin >> a >> b;
if(tip == 1)
update(1,1,n,a, a + b - 1, 0);
else
update(1,1,n,a, a + b- 1, 1);
}
}
return 0;
}
void build(int nod, int x, int y)
{
if(x == y)
arbore[nod] = {1,1,1};
else
{
int mij = (x + y) / 2;
build(nod * 2, x, mij);
build(nod * 2 + 1, mij + 1, y);
int rez = arbore[nod * 2].sol + arbore[nod * 2 + 1].sol;
arbore[nod] = {rez,rez,rez};
}
}
void update(int nod, int st, int dr, int l, int r, int val)
{
if (l <= st && dr <= r)
arbore[nod].sol = arbore[nod].pre = arbore[nod].suf = (dr - st + 1) * val;
else
{
int mid = (st + dr) / 2;
if (arbore[nod].sol == (1 - val) * (dr - st + 1))
{
arbore[2 * nod].sol = arbore[2 * nod].pre = arbore[2 * nod].suf = (mid - st + 1) * (1 - val);
arbore[2 * nod + 1].sol = arbore[2 * nod + 1].pre = arbore[2 * nod + 1].suf = (dr - mid) * (1 - val);
}
if (l <= mid)
update(2 * nod, st, mid, l, r, val);
if (r > mid)
update(2 * nod + 1, mid + 1, dr, l, r, val);
if (arbore[2 * nod].sol == mid - st + 1)
arbore[nod].pre = arbore[2 * nod].sol + arbore[2 * nod + 1].pre;
else
arbore[nod].pre = arbore[2 * nod].pre;
if (arbore[2 * nod + 1].sol == dr - mid)
arbore[nod].suf = arbore[2 * nod + 1].sol + arbore[2 * nod].suf;
else
arbore[nod].suf = arbore[2 * nod + 1].suf;
arbore[nod].sol = max(arbore[nod * 2].sol, arbore[nod * 2 + 1].sol);
arbore[nod].sol = max(arbore[nod].sol, arbore[nod * 2].suf + arbore[nod * 2 + 1].pre);
}
}
void update1(int nod, int x, int y, int a ,int b, int val)
{
if(a <=x and y <=b)
{
int rez = (y - x + 1) *val;
arbore[nod]={rez, rez, rez};
}
else
{
/// de creat prefix si sufix la fiecare nod tin minte sucventa consecutiva
/// de la nod ori in stanga(prefix) or in dreapta(sufix)
int mij = (x + y ) / 2;
if(arbore[nod].sol == val * (x -y + 1))
{
arbore[2 * nod].sol = arbore[2 * nod].pre = arbore[2 * nod].suf = (mij - x + 1) * val;
arbore[2 * nod + 1].sol = arbore[2 * nod + 1].pre = arbore[2 * nod + 1].suf = val *(y - mij);
}
if(a <= mij)
update(nod * 2, x, mij, a ,b, val);
if(b > mij)
update(nod * 2 + 1, mij + 1, y, a, b, val);
if(arbore[2 * nod].sol == mij - x + 1)
arbore[nod].pre = arbore[2 * nod].sol + arbore[2 * nod + 1].pre;
else
arbore[nod].pre = arbore[nod * 2].pre;
if(arbore[2* nod + 1].sol == y - mij)
{
arbore[nod].suf = arbore[2 * nod + 1].sol + arbore[2* nod].suf;
}
else
arbore[nod].suf = arbore[2 * nod + 1].suf;
arbore[nod].sol = max( arbore[nod * 2].sol , arbore[nod * 2 + 1].sol);
arbore[nod].sol = max(arbore[nod].sol, arbore[nod * 2].suf + arbore[nod *2 +1].pre);
}
}