#include <fstream>
using namespace std;
ifstream fin("hotel.in");
ofstream fout("hotel.out");
const int NMAX = 100005;
struct nod_arb
{
int st; //numarul de camere libere consecutive incepand cu st
int best; //numarul de camere libere consecutive in total
int dr; //numarul de camere libere consecutive care se termina pe dr
};
//1 reprezinta pozitie libera
int n,q,i,qt,x,y,caz;
nod_arb arb[4*NMAX];
void buildArb(int nod, int start ,int end)
{
//fout << nod <<" ";
if(start == end)
{
arb[nod].st = arb[nod].best = arb[nod].dr = 1;
return;
}
int mij = (start + end) / 2;
buildArb(2 * nod, start, mij);
buildArb(2 * nod + 1, mij + 1,end);
arb[nod].best = arb[nod].st = arb[nod].dr = (end - start + 1);
}
void update(int nod, int start, int end, int x, int y, int caz)
{
///fara intersectie
if(start > end || start > y || end < x)
return;
///interval inclus
if(start >= x && end<=y)
{
///au venit
if(caz == 1)
{
arb[nod].best = arb[nod].st = arb[nod].dr = 0;
}
else
{
//fout<<"intra\n";
arb[nod].best = arb[nod].st = arb[nod].dr = end - start + 1;
//fout << end << " "<< start<<"\n";
}
///au plecat
return;
}
int mij = (start + end) / 2;
if(arb[nod].best == 0) {
arb[2 * nod].best = arb[2 * nod].st = arb[2 * nod].dr = 0;
arb[2 * nod + 1].best = arb[2 * nod + 1].st = arb[2 * nod + 1].dr = 0;
}
if(arb[nod].best == end - start + 1) {
arb[2 * nod].best = arb[2 * nod].st = arb[2 * nod].dr = mij - start + 1;
arb[2 * nod + 1].best = arb[2 * nod + 1].st = arb[2 * nod + 1].dr = end - mij;
}
update(2 * nod, start, mij, x, y, caz);
update(2 * nod + 1, mij + 1, end, x, y, caz);
//update(int nod, int start, int finish, int x, int y, int caz)
//update(m+1,dr,DR);
///luam maximul din cele doua intervale
arb[nod].best = max(arb[2 * nod].best, arb[2 * nod + 1].best);
arb[nod].best = max(arb[nod].best, arb[2 * nod].dr + arb[2 * nod + 1].st);
arb[nod].st = arb[2 * nod].st;
///daca intervalul din stanga e complet adaugam si partea din stanga din al doilea interval
if (arb[2 * nod].st == mij - start + 1)
{
arb[nod].st += arb[2 * nod + 1].st;
}
arb[nod].dr = arb[2 * nod + 1].dr;
if (arb[nod * 2 + 1].dr == end - mij)
{
arb[nod].dr += arb[2 * nod].dr;
}
/*if(arb[2*nod].vst == m - st + 1)
arb[nod].vst += arb[DR].vst;
arb[nod].v = max(max(arb[ST].v , arb[DR].v) , arb[ST].vdr + arb[DR].vst);
arb[nod].vdr = arb[DR].vdr;
if(arb[nod].vdr == dr - m)
arb[nod].vdr += arb[ST].vdr;*/
}
int main()
{
fin >> n >> q;
buildArb(1,1,n);
//fout << arb[1].best << "\n";
while(q--)
{
fin >> caz;
if(caz == 1)
{
fin >> x >> y;
y = x + y - 1;
// fout << x << " " << y << "\n";
update(1, 1, n, x, y, caz);
}
if(caz == 2)
{
fin >> x >> y;
y = x + y - 1;
//fout << x << " " << y << "\n";
update(1, 1, n, x, y, caz);
}
if(caz == 3)
{
fout << arb[1].best << "\n";
}
}
}