#include <iostream>
#include <fstream>
using namespace std;
ifstream fin("hotel.in");
ofstream fout("hotel.out");
struct Nod
{
int prefix, sufix, summax, sum;
};
Nod aint[800005];
int n, m;
int lazy[800005];
Nod ConstructNod(Nod st, Nod dr)
{
Nod ph;
ph.prefix = max(st.prefix, (st.prefix == st.sum) * (st.sum + dr.prefix));
ph.sufix = max(dr.sufix, (dr.sufix == dr.sum) * (dr.sum + st.sufix));
int summax = max(st.summax, dr.summax);
ph.summax = max(summax, st.sufix + dr.prefix);
ph.sum = st.sum + dr.sum;
return ph;
}
void Build(int nod, int st, int dr)
{
if (st == dr)
{
aint[nod] = { 1,1,1,1 };
return;
}
int mij = (st + dr) / 2;
Build(2 * nod, st, mij);
Build(2 * nod + 1, mij + 1, dr);
aint[nod] = ConstructNod(aint[2 * nod], aint[2 * nod + 1]);
lazy[nod] = -1;
}
void LazyUpdate(int nod, int st, int dr)
{
if (lazy[nod] == 0)
aint[nod].prefix = aint[nod].sufix = aint[nod].summax = dr - st + 1;
else if (lazy[nod] == 1) aint[nod].prefix = aint[nod].sufix = aint[nod].summax = 0;
if (st != dr && lazy[nod] >= 0) lazy[2 * nod] = lazy[2 * nod + 1] = lazy[nod];
lazy[nod] = -1;
}
void Update(int nod, int st, int dr, int x, int y, int val)
{
if (st > y || dr < x) return;
if (x <= st && dr <= y)
{
lazy[nod] = val;
return;
}
LazyUpdate(nod, st, dr);
int mij = (st + dr) / 2;
Update(2 * nod, st, mij, x, y, val);
Update(2 * nod + 1, mij + 1, dr, x, y, val);
LazyUpdate(2 * nod, st, mij);
LazyUpdate(2 * nod + 1, mij + 1, dr);
aint[nod] = ConstructNod(aint[2 * nod], aint[2 * nod + 1]);
lazy[nod] = -1;
}
Nod Query(int nod, int st, int dr, int x, int y)
{
if (x <= st && dr <= y) return aint[nod];
if (dr < x || st>y) return { 0,0,0,0 };
int mij = (st + dr) / 2;
return ConstructNod(Query(2 * nod, st, mij, x, y), Query(2 * nod + 1, mij + 1, dr, x, y));
}
int main()
{
fin >> n >> m;
for (int i = 1; i <= 4 * n; i++)
lazy[i] = -1;
Build(1, 1, n);
for (int i = 1; i <= m; i++)
{
int op, x, y;
fin >> op;
if (op <= 2)
{
fin >> x >> y;
Update(1, 1, n, x, x + y - 1, op == 1);
}
else
{
LazyUpdate(1, 1, n);
fout << aint[1].summax << "\n";
}
}
}