#include <fstream>
#include <vector>
using namespace std;
ifstream fin("hotel.in");
ofstream fout("hotel.out");
enum LazyPropagationStatus {
INSERT,
DELETE,
NOTHING
};
struct SegTreeNode {
int prefix;
int suffix;
int answer;
int length;
LazyPropagationStatus status;
SegTreeNode()
: prefix(0), suffix(0), answer(0), length(0), status(LazyPropagationStatus::NOTHING) {}
SegTreeNode(int prefix, int suffix, int answer, int length, LazyPropagationStatus status)
: prefix(prefix), suffix(suffix), answer(answer), length(length), status(status) {}
SegTreeNode(const SegTreeNode& left, const SegTreeNode& right) {
this->length = left.length + right.length;
this->prefix = (left.prefix == left.length) ? left.prefix + right.suffix : left.prefix;
this->suffix = (right.suffix == right.length) ? right.suffix + left.suffix : right.suffix;
this->answer = max(max(left.answer, right.answer), left.suffix + right.prefix);
this->status = LazyPropagationStatus::NOTHING;
}
friend ostream &operator<<(ostream &os, const SegTreeNode &node) {
os << node.answer;
return os;
}
};
vector<SegTreeNode> segTree;
void build(int node, int left, int right) {
if (left == right) {
segTree[node] = SegTreeNode(1, 1, 1, 1, LazyPropagationStatus::NOTHING);
return;
}
int mid = (left + right) / 2;
build(2 * node, left, mid);
build(2 * node + 1, mid + 1, right);
segTree[node] = SegTreeNode(segTree[2 * node], segTree[2 * node + 1]);
}
void lazyUpdate(int node, int left, int right) {
if (segTree[node].status == LazyPropagationStatus::DELETE) {
segTree[node].prefix = segTree[node].suffix = segTree[node].answer = 0;
segTree[2 * node].status = segTree[2 * node + 1].status = LazyPropagationStatus::DELETE;
} else if (segTree[node].status == LazyPropagationStatus::INSERT) {
segTree[node].prefix = segTree[node].suffix = right - left + 1;
segTree[2 * node].status = segTree[2 * node + 1].status = LazyPropagationStatus::INSERT;
}
segTree[node].status = LazyPropagationStatus::NOTHING;
}
void propagateToChildren(int node, int left, int right) {
int mid = (left + right) / 2;
lazyUpdate(2 * node, left, mid);
lazyUpdate(2 * node + 1, mid + 1, right);
}
void update(int node, int left, int right, int a, int b, LazyPropagationStatus status) {
lazyUpdate(node, left, right);
if (left > b || right < a)
return;
if (left >= a && right <= b) {
segTree[node].status = status;
return;
}
int mid = (left + right) / 2;
update(2 * node, left, mid, a, b, status);
update(2 * node + 1, mid + 1, right, a, b, status);
propagateToChildren(node, left, right);
segTree[node] = SegTreeNode(segTree[2 * node], segTree[2 * node + 1]);
}
int main() {
int n, p;
fin >> n >> p;
segTree.resize(4 * n + 1);
build(1, 1, n);
while (p--) {
int q;
fin >> q;
if (q == 1) {
int i, m;
fin >> i >> m;
update(1, 1, n, i, i + m - 1, LazyPropagationStatus::DELETE);
} else if (q == 2) {
int i, m;
fin >> i >> m;
update(1, 1, n, i, i + m - 1, LazyPropagationStatus::INSERT);
} else {
lazyUpdate(1, 1, n);
fout << segTree[1] << '\n';
}
}
return 0;
}