#include <fstream>
using namespace std;
ifstream cin ("hotel.in");
ofstream cout ("hotel.out");
const int MAX_N = 100000;
int n, Q;
struct Nod {
int best;
int max_left;
int max_right;
bool free;
bool full;
};
Nod ArbInt[4 * MAX_N];
Nod Create_Free(int st, int dr) {
int val = dr - st + 1;
return Nod {val, val, val, 1, 0};
}
Nod Create_Full() {
return {0, 0, 0, 0, 1};
}
Nod Join(Nod A, Nod B) {
Nod nod;
nod.best = max(max(A.best, B.best), A.max_right + B.max_left);
if (B.free)
nod.max_right = A.max_right + B.max_right;
else
nod.max_right = B.max_right;
if (A.free)
nod.max_left = A.max_left + B.max_left;
else
nod.max_left = A.max_left;
if(A.free && B.free)
nod.free = 1;
else
nod.free = 0;
if(A.full && B.full)
nod.full = 1;
else
nod.full = 0;
return nod;
}
void Build(int nod, int st, int dr) {
if (st == dr) {
ArbInt[nod] = Create_Free(st, dr);
return;
}
int mid = (st + dr) / 2;
Build(2 * nod, st, mid);
Build(2 * nod + 1, mid + 1, dr);
ArbInt[nod] = Join(ArbInt[2 * nod], ArbInt[2 * nod + 1]);
}
void Update(int nod, int st, int dr, int l, int r, bool Free) {
int mid = (st + dr) / 2;
if (ArbInt[nod].free) {
ArbInt[2 * nod] = Create_Free(st, mid);
ArbInt[2 * nod + 1] = Create_Free(mid + 1, dr);
}
if (ArbInt[nod].full) {
ArbInt[2 * nod] = Create_Full();
ArbInt[2 * nod + 1] = Create_Full();
}
if (l <= st && dr <= r) {
if(Free == 0)
ArbInt[nod] = Create_Free(st, dr);
else
ArbInt[nod] = Create_Full();
return;
}
if (l <= mid)
Update(2 * nod, st, mid, l, r, Free);
if (mid < r)
Update(2 * nod + 1, mid + 1, dr, l, r, Free);
ArbInt[nod] = Join(ArbInt[2 * nod], ArbInt[2 * nod + 1]);
}
int main() {
cin >> n >> Q;
Build(1, 1, n);
for(int i = 1; i <= Q; i++) {
int tip, x, y;
cin >> tip;
if (tip == 1) {
cin >> x >> y;
Update(1, 1, n, x, x + y - 1, 1);
} else if (tip == 2) {
cin >> x >> y;
Update(1, 1, n, x, x + y - 1, 0);
} else
cout << ArbInt[1].best << "\n";
}
return 0;
}