#include <fstream>
#include <cmath>
#define MAX_N 100005
struct nod {
int pref;
int max;
int suff;
} v[4 * MAX_N];
struct lazy_nod {
bool will_propag;
bool set_val;
} lazy[4 * MAX_N];
void propag(int n, int siz) {
if (lazy[n].will_propag) {
if(siz > 1){
if(lazy[n].set_val) {
// Toate sunt egale cu 0
v[2 * n].pref = v[2 * n].max = v[2 * n].suff = 0;
v[2 * n + 1].pref = v[2 * n + 1].max = v[2 * n + 1].suff = 0;
}
else {
// Toate sunt egale cu marimea copilului respectiv
v[2 * n].pref = v[2 * n].max = v[2 * n].suff = siz / 2 + siz % 2;
v[2 * n + 1].pref = v[2 * n + 1].max = v[2 * n + 1].suff = siz / 2;
}
lazy[2 * n].will_propag = lazy[2 * n + 1].will_propag = true;
lazy[2 * n].set_val = lazy[2 * n + 1].set_val = lazy[n].set_val;
}
lazy[n].will_propag = false;
}
}
nod merge(nod ch1, int siz1, nod ch2, int siz2) {
nod ans;
ans.max = std::max(std::max(ch1.max, ch2.max), ch1.suff + ch2.pref);
ans.pref = (ch1.pref == siz1 ? ch1.pref + ch2.pref : ch1.pref);
ans.suff = (ch2.suff == siz2 ? ch1.suff + ch2.suff : ch2.suff);
return ans;
}
void update(int n, int st, int dr, int pos1, int pos2, bool state) {
propag(n, dr - st + 1);
if(st == pos1 && dr == pos2) {
lazy[n].will_propag = true;
lazy[n].set_val = state;
if(state) {
v[n].pref = v[n].max = v[n].suff = 0;
}
else {
v[n].pref = v[n].max = v[n].suff = dr - st + 1;
}
}
else {
int mij = (st + dr) / 2;
if(pos1 <= mij) {
update(2 * n, st, mij, pos1, std::min(pos2, mij), state);
}
if(mij < pos2) {
update(2 * n + 1, mij + 1, dr, std::max(pos1, mij + 1), pos2, state);
}
v[n] = merge(v[2 * n], mij - st + 1, v[2 * n + 1], dr - mij);
}
}
int main() {
std::ifstream fin("hotel.in");
std::ofstream fout("hotel.out");
int n, p, m, c;
int i, j;
fin >> n >> p;
update(1, 1, n, 1, n, false);
for (i = 0; i < p; i++) {
fin >> c;
if (c == 1) {
fin >> j >> m;
update(1, 1, n, j, j + m - 1, true);
} else if (c == 2) {
fin >> j >> m;
update(1, 1, n, j, j + m - 1, false);
} else {
fout << v[1].max << '\n';
}
}
}