#include <cmath>
#include <fstream>
#include <vector>
class aint {
private:
struct aint_node {
int pref = 0;
int sol = 0;
int suf = 0;
int lazy = 1; // 0 - update 0, 1 - update 1, -1 - clear
};
int size;
std::vector <aint_node> vec;
void propag (int nod, int st, int mid, int dr) {
if (vec[nod].lazy != -1 && 2 * nod + 2 < vec.size()) {
int len_st = mid - st + 1;
int len_dr = dr - mid;
if (vec[nod].lazy == 1) {
len_st = len_dr = 0;
}
vec[2 * nod + 1].pref = len_st;
vec[2 * nod + 1].sol = len_st;
vec[2 * nod + 1].suf = len_st;
vec[2 * nod + 1].lazy = vec[nod].lazy;
vec[2 * nod + 2].pref = len_dr;
vec[2 * nod + 2].sol = len_dr;
vec[2 * nod + 2].suf = len_dr;
vec[2 * nod + 2].lazy = vec[nod].lazy;
vec[nod].lazy = -1;
}
}
aint_node merge (const aint_node &nod_st, const aint_node &nod_dr, int st, int mid, int dr) {
aint_node par;
int len_st = mid - st + 1;
int len_dr = dr - mid;
par.pref = (nod_st.pref == len_st ? nod_st.pref + nod_dr.pref : nod_st.pref);
par.suf = (nod_dr.suf == len_dr ? nod_dr.suf + nod_st.suf : nod_dr.suf);
par.sol = std::max(std::max(nod_st.sol, nod_dr.sol), nod_st.suf + nod_dr.pref);
par.lazy = -1;
return par;
}
void update_priv (int nod, int st, int dr, int pos1, int pos2, bool state) {
if (st == pos1 && dr == pos2) {
int len = (state ? 0 : st - dr + 1);
vec[nod].pref = len;
vec[nod].sol = len;
vec[nod].suf = len;
vec[nod].lazy = (state ? 1 : 0);
}
else {
int mid = (st + dr) / 2;
propag(nod, st, mid, dr);
if (pos1 <= mid) {
update_priv(2 * nod + 1, st, mid, pos1, std::min(pos2, mid), state);
}
if (mid < pos2) {
update_priv(2 * nod + 2, mid + 1, dr, std::max(pos1, mid + 1), pos2, state);
}
vec[nod] = merge(vec[2 * nod + 1], vec[2 * nod + 2], st, mid, dr);
}
}
aint_node query_priv (int nod, int st, int dr, int pos1, int pos2) {
if (st == pos1 && dr == pos2) {
return vec[nod];
}
else {
int mid = (st + dr) / 2;
propag(nod, st, mid, dr);
aint_node sol_st, sol_dr;
if (pos1 <= mid) {
sol_st = query_priv(2 * nod + 1, st, mid, pos1, std::min(pos2, mid));
}
if (mid < pos2) {
sol_dr = query_priv(2 * nod + 2, mid + 1, dr, std::max(pos1, mid + 1), pos2);
}
return merge(sol_st, sol_dr, st, mid, dr);
}
}
public:
void reset (bool state) {
int len = (state ? 0 : size);
vec[0].pref = len;
vec[0].sol = len;
vec[0].suf = len;
vec[0].lazy = (state ? 1 : 0);
}
aint (int set_size) {
size = set_size;
vec.resize(4 * size);
reset(0);
}
int query () {
return query_priv(0, 0, size - 1, 0, size - 1).sol;
}
void update (int pos1, int pos2, bool state) {
update_priv(0, 0, size - 1, pos1, pos2, state);
}
};
int main () {
std::ifstream fin("hotel.in");
std::ofstream fout("hotel.out");
int n, p;
fin >> n >> p;
aint solve(n);
int cer, pos, len;
for (int i = 0; i < p; i++) {
fin >> cer;
if (cer == 3) {
fout << solve.query() << '\n';
}
else {
fin >> pos >> len;
pos--;
solve.update(pos, pos + len - 1, cer == 1);
}
}
}
/*
12 10
000000000000
3
1 2 3
011100000000
1 9 4
011100001111
3
2 2 1
001100001111
3
2 9 2
001100000011
3
2 3 2
000000000011
3
*/