#include <iostream>
#include <fstream>
using namespace std;
ifstream fin("hotel.in");
ofstream fout("hotel.out");
const int NMAX = 2e5 + 5;
struct Node {
int pref, suff, maxim;
int lazy;
} aint[4 * NMAX];
void combine(int nod, int st, int dr) {
int mid = (st + dr) / 2;
if (aint[2 * nod].pref == mid - st + 1) {
aint[nod].pref = mid - st + 1 + aint[2 * nod + 1].pref;
} else {
aint[nod].pref = aint[2 * nod].pref;
}
if (aint[2 * nod + 1].suff == dr - mid) {
aint[nod].suff = dr - mid + aint[2 * nod].suff;
} else {
aint[nod].suff = aint[2 * nod + 1].suff;
}
aint[nod].maxim = max(aint[2 * nod].suff + aint[2 * nod + 1].pref, max(aint[2 * nod].pref, aint[2 * nod + 1].suff));
}
void propagate(int nod, int st, int dr) {
if (aint[nod].lazy == 1) { // devin ocupate
aint[nod].pref = 0;
aint[nod].suff = 0;
aint[nod].maxim = 0;
if (st != dr) {
aint[2 * nod].lazy = 1;
aint[2 * nod + 1].lazy = 1;
}
aint[nod].lazy = 0;
} else if (aint[nod].lazy == 2) { // se elibereaza
aint[nod].pref = dr - st + 1;
aint[nod].suff = dr - st + 1;
aint[nod].maxim = dr - st + 1;
if (st != dr) {
aint[2 * nod].lazy = 2;
aint[2 * nod + 1].lazy = 2;
}
aint[nod].lazy = 0;
}
}
void update(int nod, int st, int dr, int a, int b, int stare) {
propagate(nod, st, dr);
if (a <= st && dr <= b) {
aint[nod].lazy = stare;
propagate(nod, st, dr);
return;
}
int mid = (st + dr) / 2;
if (a <= mid) {
update(2 * nod, st, mid, a, b, stare);
}
if (mid + 1 <= b) {
update(2 * nod + 1, mid + 1, dr, a, b, stare);
}
propagate(2 * nod, st, mid);
propagate(2 * nod + 1, mid + 1, dr);
combine(nod, st, dr);
}
int main() {
int n, q;
fin >> n >> q;
update(1, 1, n, 1, n, 2);
while (q--) {
int c;
fin >> c;
if (c == 1) {
int a, m;
fin >> a >> m;
int b = a + m - 1;
update(1, 1, n, a, b, 1);
} else if (c == 2) {
int a, m;
fin >> a >> m;
int b = a + m - 1;
update(1, 1, n, a, b, 2);
} else {
fout << aint[1].maxim << '\n';
}
}
return 0;
}