#include <fstream>
using namespace std;
ifstream cin ("hotel.in");
ofstream cout ("hotel.out");
const int Nmax = 400005;
struct hotel
{
int maxim, start, finish, ocupat;
};
struct Aint
{
hotel aint[Nmax];
void build(int nod, int st, int dr)
{
if (st == dr)
{
aint[nod] = {1, 1, 1, -1};
return;
}
int mid = (st + dr) / 2;
build(2 * nod, st, mid);
build(2 * nod + 1, mid + 1, dr);
aint[nod] = {dr - st + 1, dr - st + 1, dr - st + 1, -1};
}
void propagate(int nod, int st, int dr)
{
if (aint[nod].ocupat != -1)
{
int mid = (st + dr) / 2;
aint[2 * nod].ocupat = aint[nod].ocupat;
aint[2 * nod + 1].ocupat = aint[nod].ocupat;
if (aint[nod].ocupat == 1)
{
aint[2 * nod] = {0, 0, 0, 1};
aint[2 * nod + 1] = {0, 0, 0, 1};
}
else
{
aint[2 * nod] = {mid - st + 1, mid - st + 1, mid - st + 1, 0};
aint[2 * nod + 1] = {dr - mid, dr - mid, dr - mid, 0};
}
aint[nod].ocupat = -1;
}
}
void baga(int nod, int st, int dr, int x, int y)
{
if (x > dr || y < st)
return;
if (x <= st && dr <= y)
{
aint[nod] = {0, 0, 0, 1};
aint[nod].ocupat = 1;
return;
}
propagate(nod, st, dr);
int mid = (st + dr) / 2;
baga(2 * nod, st, mid, x, y);
baga(2 * nod + 1, mid + 1, dr, x, y);
aint[nod].maxim = max(max(aint[2 * nod].maxim, aint[2 * nod + 1].maxim), aint[2 * nod].finish + aint[2 * nod + 1].start);
if (aint[2 * nod].start == mid - st + 1)
aint[nod].start = aint[2 * nod].start + aint[2 * nod + 1].start;
else
aint[nod].start = aint[2 * nod].start;
if (aint[2 * nod + 1].finish == dr - mid)
aint[nod].finish = aint[2 * nod].finish + aint[2 * nod + 1].finish;
else
aint[nod].finish = aint[2 * nod + 1].finish;
}
void scoate(int nod, int st, int dr, int x, int y)
{
if (x > dr || y < st)
return;
if (x <= st && dr <= y)
{
aint[nod] = {dr - st + 1, dr - st + 1, dr - st + 1, 0};
aint[nod].ocupat = 0;
return;
}
propagate(nod, st, dr);
int mid = (st + dr) / 2;
scoate(2 * nod, st, mid, x, y);
scoate(2 * nod + 1, mid + 1, dr, x, y);
aint[nod].maxim = max(max(aint[2 * nod].maxim, aint[2 * nod + 1].maxim), aint[2 * nod].finish + aint[2 * nod + 1].start);
if (aint[2 * nod].start == mid - st + 1)
aint[nod].start = aint[2 * nod].start + aint[2 * nod + 1].start;
else
aint[nod].start = aint[2 * nod].start;
if (aint[2 * nod + 1].finish == dr - mid)
aint[nod].finish = aint[2 * nod].finish + aint[2 * nod + 1].finish;
else
aint[nod].finish = aint[2 * nod + 1].finish;
}
int query()
{
return aint[1].maxim;
}
} aint;
int main()
{
int n, p, op, x, y;
cin >> n >> p;
aint.build(1, 1, n);
for (int i = 1; i <= p; i++)
{
cin >> op;
if (op == 3)
cout << aint.query() << endl;
else
{
cin >> x >> y;
if (op == 1)
aint.baga(1, 1, n, x, x + y - 1);
else
aint.scoate(1, 1, n, x, x + y - 1);
}
}
return 0;
}