#include <fstream>
#define DIM 100002
using namespace std;
ifstream f("hotel.in");
ofstream g("hotel.out");
int n, m, flag[4 * DIM], tip, x, y, cobor[4 * DIM];
struct arbore{
int smij, sst, sdr, complet;
}aint[4 * DIM];
void update(int nod, int st, int dr, int a, int b, int val){
if(a <= st && b >= dr){
flag[nod] += val;
cobor[nod] = 1;
return;
}
int mid = (st + dr) / 2;
if(a <= mid)
update(2 * nod, st, mid, a, b, val);
if(b > mid)
update(2 * nod + 1, mid + 1, dr, a, b, val);
cobor[nod] = max(cobor[2 * nod], cobor[2 * nod + 1]);
}
void query(int nod, int st, int dr){
if(st == dr){
if(flag[nod] == 1){
aint[nod].smij = 1;
aint[nod].sst = 1;
aint[nod].sdr = 1;
aint[nod].complet = 1;
}
if(flag[nod] == -1){
aint[nod].smij = 0;
aint[nod].sst = 0;
aint[nod].sdr = 0;
aint[nod].complet = 0;
}
flag[nod] = 0;
return;
}
int mid = (st + dr) / 2;
if(cobor[nod] == 0)
return;
flag[2 * nod] += flag[nod];
flag[2 * nod + 1] += flag[nod];
flag[nod] = cobor[nod] = 0;
cobor[2 * nod] = cobor[2 * nod + 1] = 1;
query(2 * nod, st, mid);
query(2 * nod + 1, mid + 1, dr);
aint[nod].smij = max(max(aint[2 * nod].smij, aint[2 * nod + 1].smij), aint[2 * nod].sdr + aint[2 * nod + 1].sst);
if(aint[2 * nod].complet)
aint[nod].sst = aint[2 * nod].sst + aint[2 * nod + 1].sst;
else
aint[nod].sst = aint[2 * nod].sst;
if(aint[2 * nod + 1].complet)
aint[nod].sdr = aint[2 * nod].sdr + aint[2 * nod + 1].sdr;
else
aint[nod].sdr = aint[2 * nod + 1].sdr;
if(aint[nod].sst == aint[nod].sdr)
aint[nod].complet = 1;
else
aint[nod].complet = 0;
}
int main()
{
f>>n>>m;
flag[1] = 1;
cobor[1] = 1;
for(int i = 1; i <= m; ++ i){
f>>tip;
if(tip == 1){
f>>x>>y;
update(1, 1, n, x, x + y - 1, -1);
}
if(tip == 2){
f>>x>>y;
update(1, 1, n, x, x + y - 1, 1);
}
if(tip == 3){
query(1, 1, n);
g<<aint[1].smij<<'\n';
}
}
return 0;
}