#include <iostream>
#include <vector>
#include <algorithm>
#include <fstream>
using namespace std;
struct Node {
int max_free;
int left_free;
int right_free;
int total_free;
};
vector<Node> tree;
vector<int> lazy;
int n;
void apply_lazy(int node, int start, int end) {
if (lazy[node] != -1) {
int value = lazy[node];
tree[node] = {value * (end - start + 1), value * (end - start + 1), value * (end - start + 1), value * (end - start + 1)};
if (start != end) {
lazy[2 * node] = value;
lazy[2 * node + 1] = value;
}
lazy[node] = -1;
}
}
void merge(int node, int start, int end) {
int mid = (start + end) / 2;
int left_child = 2 * node;
int right_child = 2 * node + 1;
apply_lazy(left_child, start, mid);
apply_lazy(right_child, mid + 1, end);
tree[node].left_free = tree[left_child].left_free;
tree[node].right_free = tree[right_child].right_free;
if (tree[left_child].total_free == mid - start + 1) {
tree[node].left_free += tree[right_child].left_free;
}
if (tree[right_child].total_free == end - mid) {
tree[node].right_free += tree[left_child].right_free;
}
tree[node].total_free = tree[left_child].total_free + tree[right_child].total_free;
tree[node].max_free = max({tree[left_child].max_free, tree[right_child].max_free, tree[left_child].right_free + tree[right_child].left_free});
}
void build(int node, int start, int end) {
if (start == end) {
tree[node] = {1, 1, 1, 1};
} else {
int mid = (start + end) / 2;
build(2 * node, start, mid);
build(2 * node + 1, mid + 1, end);
merge(node, start, end);
}
}
void update(int node, int start, int end, int l, int r, int value) {
apply_lazy(node, start, end);
if (start > end || start > r || end < l) return;
if (start >= l && end <= r) {
lazy[node] = value;
apply_lazy(node, start, end);
} else {
int mid = (start + end) / 2;
update(2 * node, start, mid, l, r, value);
update(2 * node + 1, mid + 1, end, l, r, value);
merge(node, start, end);
}
}
void occupy(int l, int r) {
update(1, 0, n - 1, l, r, 0);
}
void free(int l, int r) {
update(1, 0, n - 1, l, r, 1);
}
int getMaxFreeSegment() {
apply_lazy(1, 0, n - 1);
return tree[1].max_free;
}
int main() {
ifstream fin("hotel.in");
ofstream fout("hotel.out");
int P;
fin >> n >> P;
tree.resize(4 * n);
lazy.assign(4 * n, -1);
build(1, 0, n - 1);
vector<int> results;
for (int p = 0; p < P; ++p) {
int c;
fin >> c;
if (c == 1) {
int i, M;
fin >> i >> M;
occupy(i - 1, i + M - 2);
} else if (c == 2) {
int i, M;
fin >> i >> M;
free(i - 1, i + M - 2);
} else if (c == 3) {
results.push_back(getMaxFreeSegment());
}
}
for (int res : results) {
fout << res << endl;
}
fin.close();
fout.close();
return 0;
}