#include <bits/stdc++.h>
#define NMAX 100001
using namespace std;
ifstream in("hotel.in");
ofstream out("hotel.out");
///salvam in aint pe prima pozitie a fiecarui interval de camere libere
int aint[NMAX*4]; ///arbore de intervale pentru maxime
void update(int poz, int val, int nod, int st, int dr) ///update aint
{
if(st==dr)
{
aint[nod]=val;
return;
}
int mij=st+(dr-st)/2;
if(poz<=mij) ///daca poz se afla in prima jumatate a intervalului
{
update(poz, val, nod*2, st, mij);
}
else ///daca poz se afla in a doua jumatate a intervalului
{
update(poz, val, nod*2+1, mij+1, dr);
}
aint[nod]=max(aint[nod*2], aint[nod*2+1]);
}
int main()
{
int n, p;
in >> n >> p;
set<pair<int, int>> camere={{1, n}}; ///intervalele de camere consecutive libere
update(1, n, 1, 1, n);
while(p--)
{
int c;
in >> c;
if(c==1) ///operatie de tip 1
{
int i, m;
in >> i >> m;
int st=i, dr=i+m-1; ///capetele intervalului care trebuie adaugat
auto interval=camere.lower_bound({st, dr});
if(interval==camere.end() || (*interval).first>st) --interval;
int st_int=(*interval).first, dr_int=(*interval).second; ///capetele intervalului din care face parte si intervalul [st, dr]
if(st_int<st)
{
camere.insert({st_int, st-1});
}
if(dr_int>dr)
{
camere.insert({dr+1, dr_int});
}
update(st_int, st-st_int, 1, 1, n);
update(dr+1, dr_int-dr, 1, 1, n);
camere.erase({st_int, dr_int});
}
else if(c==2)///operatie de tip 2
{
int i, m;
in >> i >> m;
int st=i, dr=i+m-1; ///capetele intervalului care trebuie eliminat
camere.insert({st, dr});
auto mai_mic=camere.lower_bound({st, dr}); ///intervalul situat fix inaintea intervalului [st, dr]
if(mai_mic!=camere.begin())
{
mai_mic--;
int st1=(*mai_mic).first, dr1=(*mai_mic).second;
if(dr1==st-1) ///incercam sa unim cele doua intervale
{
camere.erase(mai_mic);
camere.erase({st, dr});
camere.insert({st1, dr});
st=st1;
}
}
auto mai_mare=camere.upper_bound({st, dr}); ///intervalul situat fix dupa intervalul [st, dr]
if(mai_mare!=camere.end())
{
int st2=(*mai_mare).first, dr2=(*mai_mare).second;
if(dr+1==st2) ///incercam sa unim intervalele
{
camere.erase(mai_mare);
camere.erase({st, dr});
camere.insert({st, dr2});
dr=dr2;
update(st2, 0, 1, 1, n);
}
}
update(st, dr-st+1, 1, 1, n);
}
else ///operatie de tip 3
{
out << aint[1] << "\n"; ///in aint[1] este salvata lungimea maxima a unui interval de camere libere
}
}
return 0;
}