#include <iostream>
#include <fstream>
using namespace std;
ifstream fin("hotel.in");
ofstream fout("hotel.out");
const int N = 1e5;
int lazy[4 * N + 1];
bool dirty[4 * N + 1];
struct node{
int S, L, R;
}seg[4 * N + 1];
void build(int nod, int st, int dr){
seg[nod].S = seg[nod].L = seg[nod].R = dr - st + 1;
if(st == dr)
return;
int mij = (st + dr) / 2;
build(2 * nod, st, mij);
build(2 * nod + 1, mij + 1, dr);
}
void join(int nod, int st, int dr){
int mij = (st + dr) / 2;
seg[nod].L = seg[2 * nod].L;
if(seg[2 * nod].S == mij - st + 1)
seg[nod].L = max(seg[nod].L, mij - st + 1 + seg[2 * nod + 1].L);
seg[nod].R = seg[2 * nod + 1].R;
if(seg[2 * nod + 1].S == dr - mij)
seg[nod].R = max(seg[nod].R, dr - mij + seg[2 * nod].R);
seg[nod].S = max(seg[nod].L, seg[nod].R);
seg[nod].S = max(seg[2 * nod].S, max(seg[2 * nod + 1].S, seg[2 * nod].R + seg[2 * nod + 1].L));
}
void propag(int nod, int st, int dr){
if(!dirty[nod])
return;
seg[nod].S = seg[nod].L = seg[nod].R = lazy[nod] * (dr - st + 1);
if(st != dr){
lazy[2 * nod] = lazy[nod], lazy[2 * nod + 1] = lazy[nod];
dirty[2 * nod] = dirty[2 * nod + 1] = true;
}
lazy[nod] = 0;
dirty[nod] = false;
}
void update(int nod, int st, int dr, int Ust, int Udr, int val){
propag(nod, st, dr);
if(st != dr){
propag(2 * nod, st, (st + dr) / 2);
propag(2 * nod + 1, (st + dr) / 2 + 1, dr);
}
if(Ust <= st && dr <= Udr){
lazy[nod] = val, dirty[nod] = true;
propag(nod, st, dr);
return;
}
int mij = (st + dr) / 2;
if(Ust <= mij)
update(2 * nod, st, mij, Ust, Udr, val);
if(mij + 1 <= Udr)
update(2 * nod + 1, mij + 1, dr, Ust, Udr, val);
join(nod, st, dr);
}
int main(){
int n, q;
fin >> n >> q;
build(1, 1, n);
while(q--){
int type;
fin >> type;
if(type == 1){
int st, dr;
fin >> st >> dr;
dr = st + dr - 1;
update(1, 1, n, st, dr, 0);
}else if(type == 2){
int st, dr;
fin >> st >> dr;
dr = st + dr - 1;
update(1, 1, n, st, dr, 1);
}else
fout << seg[1].S << '\n';
}
return 0;
}