#include <iostream>
#include <cstdio>
using namespace std;
struct nod {
int st, dr, best;
bool lazy;
nod operator = (int val) {
this->best = this->st = this->dr = val;
this->lazy = false;
return *this;
}
nod operator = (nod rhs) {
this->best = rhs.best;
this->st = rhs.st;
this->dr = rhs.dr;
this->lazy = rhs.lazy;
return *this;
}
};
const int NMAX = 100000;
int n, p;
nod aint[4 * NMAX + 5];
void push_lazy(int poz, int nst, int ndr) {
if(!aint[poz].lazy)
return;
aint[poz].lazy = false;
int val = (aint[poz].best > 0) ? 1 : 0, mij = (nst + ndr) >> 1;
aint[poz >> 1] = val * (mij - nst + 1);
aint[poz >> 1 | 1] = val * (ndr - mij);
aint[poz >> 1 | 1].lazy = aint[poz >> 1 | 1].lazy = true;
}
void recalc(int poz, int nst, int ndr) {
int mij = (ndr + nst) >> 1, lst = mij - nst + 1, ldr = ndr - mij;
nod st = aint[poz >> 1], dr = aint[poz >> 1 | 1];
aint[poz].st = st.st + ((st.st == lst) ? dr.st : 0);
aint[poz].dr = dr.dr + ((dr.dr == ldr) ? st.dr : 0);
aint[poz].best = max(st.dr + dr.st, max(aint[poz].st, aint[poz].dr));
aint[poz].best = max(aint[poz].best, max(st.best, dr.best));
}
void update(int poz, int nst, int ndr, int ust, int udr, int val) {
if(ndr < ust || nst > udr)
return;
if(nst >= ust && ndr <= udr) {
aint[poz] = val * (ndr - nst + 1);
if(ndr > nst)
aint[poz].lazy = true;
return;
}
push_lazy(poz, nst, ndr);
int mij = (nst + ndr) >> 1;
update(poz >> 1, nst, mij, ust, udr, val);
update(poz >> 1 | 1, mij + 1, ndr, ust, udr, val);
recalc(poz, nst, ndr);
}
int main() {
freopen("hotel.in", "r", stdin);
freopen("hotel.out", "w", stdout);
scanf("%d %d", &n, &p);
aint[1] = n;
aint[1].lazy = true;
for(int i = 1; i <= p; i++) {
int tip, prima, nr;
scanf("%d", &tip);
if(tip == 3)
printf("%d\n", aint[1].best);
else {
scanf("%d %d", &prima, &nr);
update(1, 1, n, prima, prima + nr - 1, tip - 1);
}
}
return 0;
}