#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <deque>
using namespace std;
ifstream f("hotel.in");
ofstream g("hotel.out");
#define nmax 100005
#define ll long long
struct Aint{
int incepe, termina ,best, add;
}aint[nmax*4];
int n, m;
void citeste(){
f >> n >> m;
}
void fa_aint(int nod, int st, int dr){
if (st == dr){
aint[nod].add = -1;
aint[nod].incepe = aint[nod].termina = aint[nod].best = (dr-st+1);
return;
}else{
int mij = (st + dr) / 2;
fa_aint(nod*2, st, mij);
fa_aint(nod*2+1, mij+1, dr);
aint[nod].add = -1;
aint[nod].incepe = aint[nod].termina = aint[nod].best = (dr-st+1);
}
}
void baga(int nod, int st, int dr, int val){
aint[nod].add = val;
aint[nod].incepe = aint[nod].termina = aint[nod].best = (dr - st+1) * val;
}
void udpate(int nod, int st, int dr, int a, int b, int val){
if (a <= st && dr <= b){// [a, [st, dr], b]
aint[nod].add = val;// ce valoarea am bagat
aint[nod].incepe = aint[nod].termina = aint[nod].best = (dr-st+1)*val;
return;
}else {
int mij = (st + dr) / 2;
if (aint[nod].add != -1){// am ceva informatie pe care vreau sa o trimit;
baga(nod*2, st, mij, aint[nod].add);
baga(nod*2+1, mij+1, dr, aint[nod].add);
aint[nod].add = -1;// il marchez ca el si-o trimis-o
}
if (a <= mij) udpate(nod*2, st, mij, a, b, val);
if (b > mij) udpate(nod*2+1, mij+1, dr, a, b, val);
if (aint[nod*2].incepe == mij-st+1) aint[nod].incepe = aint[nod*2].incepe + aint[nod*2+1].incepe;
else aint[nod].incepe = aint[nod*2].incepe;
if (aint[nod*2+1].termina == (dr-mij)) aint[nod].termina = aint[nod*2+1].termina + aint[nod*2].termina;
else aint[nod].termina = aint[nod*2+1].termina;
aint[nod].best = aint[nod*2].termina + aint[nod*2+1].incepe;
aint[nod].best = max(aint[nod].best, max( aint[nod*2].best, aint[nod*2+1].best ) );
}
}
void rezolva(){
// ideea ar fi ca tin un aint;
// si pt primele 2 cerinte e de ajuns un udpate pe interval pentru a 3 mai am nevoie inca de cateva informatii
// asa ca in fiecare nod din aint tin urmatoarele informatii
// nod.incepe = cea mai lunga secventa liberace incepe la inceputul intervalului
// nod.termina = cea mai lunga secventa libera ce se termina la sfarsitul intervalului
// nod.best = cea mai lunga secventa din interval
fa_aint(1, 1, n);
for(int i=1; i<=m; ++i){
int tip; f >> tip;
switch (tip){
case 1:{// le ocupa
int x, y; f >> x >> y;
udpate(1, 1, n, x, x+y-1, 0);
break;
}
case 2:{//se golesc
int x, y; f >> x >> y;
udpate(1, 1, n, x, x+y-1, 1);
break;
}
case 3:{
//cout << aint[1].best << "\n";
g << aint[1].best << "\n";
break;
}
}
}
}
int main(){
citeste();
rezolva();
f.close();
g.close();
return 0;
}