#include <bits/stdc++.h>
using namespace std;
const int NMax = 100005;
inline int dist(int a, int b) {
return b - a + 1;
}
inline int dist(pair<int, int> p) {
return dist(p.first, p.second);
}
struct room {
int free_prefix, free_max, free_suffix;
bool lazy;
using interval = pair<int, int>;
using room_interval = pair<interval, const room&>;
room(int free_prefix, int free_max, int free_suffix, bool lazy = false) :
free_prefix(free_prefix),
free_max(free_max),
free_suffix(free_suffix),
lazy(lazy) {}
room(int elements, bool lazy = true): room(elements, elements, elements, lazy) {}
room() = default;
} rooms[4 * NMax];
room mconcat(const room::room_interval& a, const room::room_interval& b) {
auto [left_interval, left_rooms] = a;
auto [right_interval, right_rooms] = b;
auto left_size = dist(left_interval);
auto right_size = dist(right_interval);
int free_prefix = left_rooms.free_prefix, free_suffix = right_rooms.free_suffix, free_max;
if (free_prefix == left_size)
free_prefix += right_rooms.free_prefix;
if (free_suffix == right_size)
free_suffix += left_rooms.free_suffix;
free_max = ranges::max({free_prefix, free_suffix, left_rooms.free_max, right_rooms.free_max, left_rooms.free_suffix + right_rooms.free_prefix});
return room(free_prefix, free_max, free_suffix);
}
int x, y;
void set_rooms(int node, int l, int r) {
if (y < l || r < x)
return;
if (x <= l && r <= y) {
rooms[node] = room(0);
return;
}
int mij = (l + r) / 2;
if (rooms[node].lazy) {
rooms[node].lazy = false;
bool empty = rooms[node].free_max != 0;
int left_elements = dist(l, mij) * empty;
int right_elements = dist(mij + 1, r) * empty;
rooms[node * 2] = room(left_elements);
rooms[node * 2 + 1] = room(right_elements);
}
set_rooms(node * 2, l, mij);
set_rooms(node * 2 + 1, mij + 1, r);
rooms[node] = mconcat({{l, mij}, rooms[node * 2]}, {{mij + 1, r}, rooms[node * 2 + 1]});
}
void empty_rooms(int node, int l, int r) {
if (y < l || r < x)
return;
if (x <= l && r <= y) {
rooms[node] = room(dist(l, r));
return;
}
int mij = (l + r) / 2;
if (rooms[node].lazy) {
rooms[node].lazy = false;
bool empty = rooms[node].free_max != 0;
int left_elements = dist(l, mij) * empty;
int right_elements = dist(mij + 1, r) * empty;
rooms[node * 2] = room(left_elements);
rooms[node * 2 + 1] = room(right_elements);
}
empty_rooms(node * 2, l, mij);
empty_rooms(node * 2 + 1, mij + 1, r);
rooms[node] = mconcat({{l, mij}, rooms[node * 2]}, {{mij + 1, r}, rooms[node * 2 + 1]});
}
int main() {
ifstream cin("hotel.in");
ofstream cout("hotel.out");
int n, m;
cin >> n >> m;
rooms[1] = room(n);
for (int i = 0; i < m; i++) {
int op;
cin >> op;
if (op == 3) {
cout << rooms[1].free_max << endl;
continue;
}
cin >> x >> y;
y += x - 1;
if (op == 1)
set_rooms(1, 1, n);
else
empty_rooms(1, 1, n);
}
}