#include <iostream>
#include <fstream>
#define NMAX 100000
#define INACTIVE -1
#define TO_ZERO 0
#define TO_ONE 1
using namespace std;
ifstream fin("hotel.in");
ofstream fout("hotel.out");
struct Node {
int pre, suf, best, len, lazy;
};
Node ST[4 * NMAX];
void mergeChildren(int node, int l, int r) {
ST[node].len = ST[2 * node + 1].len + ST[2 * node + 2].len;
ST[node].pre = ST[2 * node + 1].pre == ST[2 * node + 1].len ? ST[2 * node + 1].len + ST[2 * node + 2].pre : ST[2 * node + 1].pre;
ST[node].suf = ST[2 * node + 2].suf == ST[2 * node + 2].len ? ST[2 * node + 2].len + ST[2 * node + 1].suf : ST[2 * node + 2].suf;
ST[node].best = max(max(ST[2 * node + 1].best, ST[2 * node + 2].best), ST[2 * node + 1].suf + ST[2 * node + 2].pre);
ST[node].lazy = INACTIVE;
}
void build(int node, int l, int r) {
if (l == r) {
ST[node] = {1, 1, 1, 1, TO_ZERO};
} else {
int middle = (l + r) / 2;
build(2 * node + 1, l, middle);
build(2 * node + 2, middle + 1, r);
mergeChildren(node, l, r);
}
}
void lazyUpdate(int node, int l, int r) {
if (ST[node].lazy == TO_ZERO) {
ST[node].pre = ST[node].suf = ST[node].best = r - l + 1;
if (l != r) {
ST[2 * node + 1].lazy = ST[2 * node + 2].lazy = TO_ZERO;
}
} else if (ST[node].lazy == TO_ONE) {
ST[node].pre = ST[node].suf = ST[node].best = 0;
if (l != r) {
ST[2 * node + 1].lazy = ST[2 * node + 2].lazy = TO_ONE;
}
}
ST[node].lazy = INACTIVE;
}
void update(int node, int l, int r, int queryLeft, int queryRight, int value) {
if (l > queryRight || r < queryLeft) {
return;
}
if (l >= queryLeft && queryRight >= r) {
ST[node].lazy = value;
} else {
lazyUpdate(node, l, r);
int middle = (l + r) / 2;
update(2 * node + 1, l, middle, queryLeft, queryRight, value);
update(2 * node + 2, middle + 1, r, queryLeft, queryRight, value);
lazyUpdate(2 * node + 1, l, middle);
lazyUpdate(2 * node + 2, middle + 1, r);
mergeChildren(node, l, r);
}
}
int main()
{
int n, m;
fin >> n >> m;
build(0, 0, n - 1);
while (m--) {
int op;
fin >> op;
if (op == 1) {
int l, sz;
fin >> l >> sz;
update(0, 0, n - 1, l - 1, l + sz - 2, TO_ONE);
} else if (op == 2) {
int l, sz;
fin >> l >> sz;
update(0, 0, n - 1, l - 1, l + sz - 2, TO_ZERO);
} else {
lazyUpdate(0, 0, n - 1);
fout << ST[0].best << '\n';
}
}
fin.close();
fout.close();
return 0;
}