#include <bits/stdc++.h>
std::ifstream fin("hotel.in");
std::ofstream fout("hotel.out");
const int MAX_N = 100'000;
struct Node {
int pref_max; /// cel mai lung prefix cu elemente de 0
int suff_max; /// cel mai lung sufix cu elemente de 0
int len_max; /// secventa de lungime maxima cu 0
int lazy; /// 0, daca operatia a fost trimisa fiilor nodului, 1, daca se ocupa camerele, 2, daca se elibereaza
};
Node segment_tree[MAX_N << 2 | 1];
int n, p, t, i, m;
void update_node(int node, int left, int right) {
int mid = (left + right) >> 1;
/// [left, mid] -> mid - left + 1 elemente
/// [mid + 1, right] -> right - mid elemente
segment_tree[node].pref_max = (segment_tree[node << 1].pref_max == mid - left + 1) ? segment_tree[node << 1].pref_max + segment_tree[node << 1 | 1].pref_max : segment_tree[node << 1].pref_max;
segment_tree[node].suff_max = (segment_tree[node << 1 | 1].suff_max == right - mid) ? segment_tree[node << 1].suff_max + segment_tree[node << 1 | 1].suff_max : segment_tree[node << 1 | 1].suff_max;
segment_tree[node].len_max = std::max({segment_tree[node << 1].len_max, segment_tree[node << 1 | 1].len_max, segment_tree[node << 1].suff_max + segment_tree[node << 1 | 1].pref_max});
}
void propagate(int node, int left, int right) {
if (segment_tree[node].lazy > 0) {
if (segment_tree[node].lazy == 1) {
/// avem interogare pentru a se ocupa camerele (se umple secventa cu 1)
segment_tree[node].pref_max = 0;
segment_tree[node].suff_max = 0;
segment_tree[node].len_max = 0;
if (left != right) { /// nodul nu este frunza
segment_tree[node << 1].lazy = segment_tree[node].lazy;
segment_tree[node << 1 | 1].lazy = segment_tree[node].lazy;
}
} else
if (segment_tree[node].lazy == 2) {
/// avem interogare pentru a se elibera camerele (se umple cu 0 secventa)
segment_tree[node].pref_max = right - left + 1;
segment_tree[node].suff_max = right - left + 1;
segment_tree[node].len_max = right - left + 1;
if (left != right) {
segment_tree[node << 1].lazy = segment_tree[node].lazy;
segment_tree[node << 1 | 1].lazy = segment_tree[node].lazy;
}
}
segment_tree[node].lazy = 0;
}
}
void update(int node, int left, int right, int q_left, int q_right, int task) {
if (q_left <= left && right <= q_right) {
segment_tree[node].lazy = task;
return;
}
propagate(node, left, right);
int mid = (left + right) >> 1;
if (q_left <= mid)
update(node << 1, left, mid, q_left, q_right, task);
if (q_right > mid)
update(node << 1 | 1, mid + 1, right, q_left, q_right, task);
propagate(node << 1, left, mid);
propagate(node << 1 | 1, mid + 1, right);
update_node(node, left, right);
}
int main() {
fin >> n >> p;
update(1, 1, n, 1, n, 2); /// starea initiala: 0, 0, ..., 0
while (p--) {
fin >> t;
if (t == 1) {
fin >> i >> m;
update(1, 1, n, i, i + m - 1, 1);
} else
if (t == 2) {
fin >> i >> m;
update(1, 1, n, i, i + m - 1, 2);
} else {
propagate(1, 1, n);
fout << segment_tree[1].len_max << "\n";
}
}
fin.close();
fout.close();
return 0;
}