#include <bits/stdc++.h>
#define int long long
using namespace std;
struct Node {
int lungime;
int pref;
int suf;
int smax;
};
Node merge(Node b, Node c) {
Node a;
a.lungime = b.lungime + c.lungime;
a.pref = b.pref;
if(b.pref == b.lungime) {
a.pref += c.pref;
}
a.suf = c.suf;
if(c.suf == c.lungime) {
a.suf += b.suf;
}
a.smax = max(max(b.smax, c.smax), b.suf + c.pref);
return a;
}
const int NMAX = 1e5;
Node aint[4 * NMAX + 1];
int lazy[4 * NMAX + 1];
void build(int node, int st, int dr) {
if(st == dr) {
aint[node].lungime = 1;
aint[node].pref = 1;
aint[node].suf = 1;
aint[node].smax = 1;
} else {
int mid = (st + dr) / 2;
build(2 * node, st, mid);
build(2 * node + 1, mid + 1, dr);
aint[node] = merge(aint[2 * node], aint[2 * node + 1]);
}
}
void propagate(int node, int st, int dr) {
if(lazy[node] == 1) {
aint[node].pref = aint[node].lungime;
aint[node].suf = aint[node].lungime;
aint[node].smax = aint[node].lungime;
}
if(lazy[node] == -1) {
aint[node].pref = 0;
aint[node].suf = 0;
aint[node].smax = 0;
}
if(st != dr) {
lazy[2 * node] = lazy[node];
lazy[2 * node + 1] = lazy[node];
}
lazy[node] = 0;
}
void update(int node, int st, int dr, int x, int y, int val) {
propagate(node, st, dr);
if(x <= st && dr <= y) {
lazy[node] = val;
propagate(node, st, dr);
} else {
int mid = (st + dr) / 2;
if(x <= mid) {
update(2 * node, st, mid, x, y, val);
}
if(mid + 1 <= y) {
update(2 * node + 1, mid + 1, dr, x, y, val);
}
propagate(2 * node, st, mid);
propagate(2 * node + 1, mid + 1, dr);
aint[node] = merge(aint[2 * node], aint[2 * node + 1]);
}
}
signed main() {
ifstream cin("hotel.in");
ofstream cout("hotel.out");
int n, p;
cin >> n >> p;
build(1, 1, n);
for(int i = 1; i <= p; i++) {
int c;
cin >> c;
if(c == 3) {
cout << aint[1].smax << '\n';
} else {
int x, m;
cin >> x >> m;
if(c == 1) {
update(1, 1, n, x, x + m - 1, -1);
} else {
update(1, 1, n, x, x + m - 1, 1);
}
}
}
}