#include<cstdio>
#include<vector>
using namespace std;
struct INTE{
int a, b, oc, po, no; //[a,b], ocupate, prima ocupata, max(neocupate)
bool os, od;
};
vector <INTE> c(2);
int n, p, ctrl, x, y, l;
inline int maxi(int a, int b) { return (a > b) ? a : b; }
void build(int a, int b, int poz){
c[poz].a = a;
c[poz].b = b;
c[poz].oc = c[poz].po = c[poz].os = c[poz].od = 0;
if (a < b-2){
c.resize(2*poz+2);
build(a, (a+b)/2, 2*poz);
build((a+b)/2+1, b, 2*poz+1);
}
}
void update_sus(int poz){
if (poz > 1){//l++;
INTE *tata = &c[poz/2], *st = &c[(poz/2)*2], *dr = &c[(poz/2)*2+1];
if (st->oc > 0 && dr->oc > 0){
int stanga = (st->po - st->a),
mijloc = (st->b - st->po - st->oc + 1) + (dr->po - dr->a),
dreapta = (dr->b - dr->po - dr->oc + 1);
st->no = maxi(stanga, (st->b - st->po - st->oc + 1));
dr->no = maxi(dreapta, dr->po - dr->a);
tata->no = maxi(maxi(stanga, mijloc), dreapta);
}
else if (st->oc > 0 && dr->oc == 0){
int stanga = (st->po - st->a),
mijloc = (st->b - st->po - st->oc + 1) + (dr->b - dr->a + 1),
dreapta = (dr->b - dr->a + 1);
st->no = maxi(stanga, (st->b - st->po - st->oc + 1));
dr->no = dr->b - dr->a + 1;
tata->no = maxi(maxi(stanga, mijloc), dreapta);
}
else if (st->oc == 0 && dr->oc > 0){
int stanga = (st->b - st->a + 1),
mijloc = (st->b - st->a + 1) + (dr->po - dr->a),
dreapta = (dr->b - dr->po - dr->oc + 1);
st->no = st->b - st->a + 1;
dr->no = maxi(dreapta, dr->po - dr->a);
tata->no = maxi(maxi(stanga, mijloc), dreapta);
}
update_sus(poz/2);
}
}
int query_i(int poz, int x, int y){//l++;
if (x >= c[poz].a && x+y-1 <= c[poz].b && y >= (c[poz].b - c[poz].a + 1)/2) return poz;
else {
if (x >= c[poz].a && x+y-1 <= (c[poz].a + c[poz].b) / 2) {
//c[poz].os = 1;
return query_i(2*poz, x, y);
}
else if (x >= (c[poz].a + c[poz].b) / 2 + 1 && x+y-1 <= c[poz].b) {
//c[poz].od = 1;
return query_i(2*poz+1, x, y);
}
else return -1;
}
}
int query_d(int poz, int x, int y){//l++;
if (x >= c[poz].a && x+y-1 <= c[poz].b && x <= c[poz].po + c[poz].oc) return poz;
else {
if (x >= c[poz].a && x+y-1 <= (c[poz].a + c[poz].b) / 2) return query_d(2*poz, x, y);
else if (x >= (c[poz].a + c[poz].b) / 2 + 1 && x+y-1 <= c[poz].b) return query_d(2*poz+1, x, y);
else return -1;
}
}
void ins(int cam, int cati){
int poz = query_i(1, cam, cati);
if (poz != -1) c[poz].oc += cati, c[poz].po = cam;
update_sus(poz);
}
void del(int cam, int cati){
int poz = query_d(1, cam, cati);
if (poz != -1) {
c[poz].oc -= cati;
if (c[poz].oc == 0) {
c[poz].po = 0;
if (poz % 2 == 0) c[poz/2].os = 0;
else c[poz/2].od = 0;
}
else c[poz].po += cati;
}
update_sus(poz);
}
int main(){
FILE *in = fopen("hotel.in", "r"), *out = fopen("hotel.out", "w");
if (in && out) {
fscanf(in, "%d %d\n", &n, &p);
build(1, n, 1);
//for(int i = 1; i < c.size(); i++) printf("[%d %d]: ocupate: %d prima: %d\n", c[i].a, c[i].b, c[i].oc, c[i].po);
for(int i = 0; i < p; i++){
fscanf (in, "%d", &ctrl);
//l=0;
if (ctrl == 3) fprintf(out, "%d\n", (c[1].no == 0) ? n : c[1].no);
else {
fscanf(in, "%d %d", &x, &y);
if (ctrl == 1) ins(x, y);
else if (ctrl == 2) del(x, y);
}
//printf("operatia %d in %d pasi\n",ctrl, l);
//for(int i = 1; i < c.size(); i++) printf("[%d %d]: ocupate: %d prima: %d max_neocupate:%d\n", c[i].a, c[i].b, c[i].oc, c[i].po, c[i].no);
}
fclose(in), fclose(out);
}
return 0;
}