#pragma once
#include<fstream>
#include<iostream>
#define dim 400000
using namespace std;
/*
nod.leftSeqMax = lungimea maxima de camere libere ce incepe din stanga intervalului
nod.rightSeqMax = --||-- dreapta
nod.seqMax = secventa maxima pe interval
*/
class Nod {
public:
int seqMax, leftSeqMax, rightSeqMax;
public:
Nod() {};
Nod(int seqMax, int leftSeqMax, int rightSeqMax) {
this->seqMax = seqMax;
this->rightSeqMax = rightSeqMax;
this->leftSeqMax = leftSeqMax;
}
};
Nod arbintMAX[dim];
int lazy[dim];
// lazy 1 - interval should be freed, lazy 2 - interval should be occupied, lazy 0 - no pending update
void manageNode(int nod, int st, int dr) {
if (lazy[nod] != 0) {
if (lazy[nod] == 1) {
arbintMAX[nod] = Nod(dr - st + 1, dr - st + 1, dr - st + 1);
}
if (lazy[nod] == 2) {
arbintMAX[nod] = Nod(0,0,0);
}
if (st != dr) {
lazy[2 * nod] = lazy[nod];
lazy[2 * nod + 1] = lazy[nod]; // propagate
}
lazy[nod] = 0; // updated and propagated
}
}
int max(int a, int b) {
if (a > b)
return a;
return b;
}
void build(int nod, int st, int dr) {
arbintMAX[nod] = Nod(dr - st + 1, dr - st + 1, dr-st + 1);
if (st == dr) {
return;
}
int mid = st + (dr - st) / 2;
build(2 * nod, st, mid);
build(2 * nod + 1, mid + 1, dr);
}
void update(int nod, int st, int dr, int uStart, int uEnd, int ocupat) {
manageNode(nod, st, dr);
if (uStart <= st && uEnd >= dr) {
if (ocupat == 1) { // se ocupa
arbintMAX[nod] = Nod(0, 0, 0);
lazy[2 * nod] = 2;
lazy[2 * nod + 1] = 2;
}
else {
arbintMAX[nod] = Nod(dr - st + 1, dr - st + 1, dr - st + 1);
lazy[2 * nod] = 1;
lazy[2 * nod + 1] = 1;
}
return;
}
int mid = st + (dr - st) / 2;
if (uStart <= mid)
update(2 * nod, st, mid, uStart, uEnd, ocupat);
if (uEnd > mid)
update(2 * nod + 1, mid + 1, dr, uStart, uEnd, ocupat);
manageNode(2*nod, st, mid);
manageNode(2*nod+1, mid+1, dr);
// seqMax
int longestStandalone = max(arbintMAX[2 * nod].seqMax, arbintMAX[2 * nod + 1].seqMax);
int longestConnected = arbintMAX[2 * nod].rightSeqMax + arbintMAX[2 * nod + 1].leftSeqMax;
arbintMAX[nod].seqMax = max(longestStandalone, longestConnected);
// leftSeqMax
if (arbintMAX[2 * nod].leftSeqMax == arbintMAX[2 * nod].seqMax && arbintMAX[2 * nod].seqMax == mid-st+1) { // the interval is all emplty, the left starting longest of the right child will also contribute
arbintMAX[nod].leftSeqMax = arbintMAX[2 * nod].leftSeqMax + arbintMAX[2 * nod + 1].leftSeqMax;
}
else { // intervals "disconnected"
arbintMAX[nod].leftSeqMax = arbintMAX[2 * nod].leftSeqMax;
}
// rightSeqMax
if (arbintMAX[2 * nod + 1].rightSeqMax == arbintMAX[2 * nod + 1].seqMax && arbintMAX[2 * nod + 1].seqMax == dr-mid) {
arbintMAX[nod].rightSeqMax = arbintMAX[2 * nod + 1].rightSeqMax + arbintMAX[2 * nod].rightSeqMax;
}
else {
arbintMAX[nod].rightSeqMax = arbintMAX[2 * nod + 1].rightSeqMax;
}
}
int main() {
ifstream fin("hotel.in");
ofstream fout("hotel.out");
int N, P, c, poz, nr;
fin >> N >> P;
build(1, 1, N);
while (P) {
fin >> c;
if (c == 1) {
fin >> poz >> nr;
update(1, 1, N, poz, poz + nr - 1, 1);
}
if (c == 2) {
fin >> poz >> nr;
update(1, 1, N, poz, poz + nr - 1, 0);
}
if (c == 3) {
fout << arbintMAX[1].seqMax<<"\n";
}
P--;
}
return 0;
}