#include <fstream>
#include <algorithm>
using namespace std;
ifstream fin("hotel.in");
ofstream fout("hotel.out");
struct camere
{
int st, dr, maxim;
};
void init(int nod, int x, int y);
void update(int nod, int x, int y, int a, int b, int tip);
int n, m;
camere aint[500005];
int main()
{
int tip, x, y, i;
fin >> n >> m;
init(1,1,n);
for (i = 1; i <= m; i++)
{
fin >> tip;
if (tip == 3)
fout << aint[1].maxim << '\n';
else
{
fin >> x >> y;
if (tip == 1)
update(1, 1, n, x, x + y - 1, 1);
else
update(1, 1, n, x, x + y - 1, 2);
}
}
return 0;
}
void update(int nod, int x, int y, int a, int b, int tip)
{
int mij;
if (a <= x && y <= b)
{
if (tip == 1) //dispar toate camerele din intervalul curent
aint[nod].maxim = aint[nod].st = aint[nod].dr = 0;
else
aint[nod].maxim = aint[nod].st = aint[nod].dr = y - x + 1;
}
else
{
mij = (x + y) / 2;
if (aint[nod].maxim == 0)
{
aint[2*nod].maxim = aint[2*nod].st = aint[2*nod].dr = 0;
aint[2*nod+1].maxim = aint[2*nod+1].st = aint[2*nod+1].dr = 0;
}
if (aint[nod].maxim == y - x + 1)
{
aint[2 * nod].maxim = aint[2 * nod].st = aint[2 * nod].dr = mij - x + 1;
aint[2 * nod + 1].maxim = aint[2 * nod + 1].st = aint[2 * nod + 1].dr = y-mij;
}
if (a <= mij)
update(2 * nod, x, mij, a, b, tip);
if (b > mij)
update(2 * nod + 1, mij + 1, y, a, b, tip);
aint[nod].maxim = max(aint[2 * nod].maxim, max(aint[2 * nod + 1].maxim, aint[2 * nod].dr + aint[2 * nod + 1].st));
aint[nod].st = aint[2 * nod].st;
if (aint[nod].st == mij - x + 1) //pot sa iau si de la nodul drept
aint[nod].st += aint[2 * nod + 1].st;
aint[nod].dr = aint[2 * nod + 1].dr;
if (aint[nod].dr == y - mij) //pot sa iau si de la nodul stang
aint[nod].dr += aint[2 * nod].dr;
}
}
void init(int nod, int x, int y)
{
int mij = (x + y) / 2;
if (x < y)
{
init(2 * nod, x, mij);
init(2 * nod + 1, mij + 1, y);
}
aint[nod].maxim = aint[nod].st = aint[nod].dr = y-x+1;
}