#include <stdio.h>
#define NMAX 32000
int MAX[NMAX], STG[NMAX], DRE[NMAX], NEGRU[NMAX];
int N, Q, i, t, a, b;
void populate(int nod, int st, int dr)
{
if (st == dr)
{
MAX[nod] = STG[nod] = DRE[nod] = 1;
}
else
{
int m = (st+dr)>>1;
populate(nod<<1, st, m);
populate(nod<<1|1, m+1, dr);
MAX[nod] = STG[nod] = DRE[nod] = dr-st+1;
}
}
void insert(int nod, int st, int dr, int a, int b)
{
if (a <= st && dr <= b)
{
NEGRU[nod] = 1;
MAX[nod] = STG[nod] = DRE[nod] = 0;
}
else
{
int m = (st+dr)>>1;
if (a <= m)
insert(nod<<1, st, m, a, b);
if (b > m)
insert(nod<<1|1, m+1, dr, a, b);
STG[nod] = STG[nod<<1];
if (STG[nod<<1] == m-st+1)
STG[nod] += STG[nod<<1|1];
DRE[nod] = DRE[nod<<1|1];
if (DRE[nod<<1|1] == dr-m)
DRE[nod] += DRE[nod<<1];
MAX[nod] = MAX[nod<<1] > MAX[nod<<1|1]? MAX[nod<<1]: MAX[nod<<1|1];
MAX[nod] = STG[nod] > MAX[nod]? STG[nod]: MAX[nod];
MAX[nod] = DRE[nod] > MAX[nod]? DRE[nod]: MAX[nod];
if (DRE[nod<<1]+STG[nod<<1|1] > MAX[nod])
MAX[nod] = DRE[nod<<1]+STG[nod<<1|1];
if (MAX[nod] == 0)
NEGRU[nod] = 1;
}
}
void remove(int nod, int st, int dr, int a, int b, int mostenire)
{
if (mostenire == 1)
{
NEGRU[nod] = 1;
MAX[nod] = STG[nod] = DRE[nod] = 0;
}
int m = (st+dr)>>1;
if (a <= st && dr <= b)
{
NEGRU[nod<<1] = NEGRU[nod<<1|1] = 0;
MAX[nod<<1] = STG[nod<<1] = DRE[nod<<1] = m-st+1;
MAX[nod<<1|1] = STG[nod<<1|1] = DRE[nod<<1|1] = dr-m;
NEGRU[nod] = 0;
MAX[nod] = STG[nod] = DRE[nod] = dr-st+1;
}
else
{
// incearca la stanga
int r0 = 0, r1 = 0;
if (a <= m)
{
r0 = 1;
remove(nod<<1, st, m, a, b, NEGRU[nod]);
}
if (m < b)
{
r1 = 1;
remove(nod<<1|1, m+1, dr, a, b, NEGRU[nod]);
}
// era nod negru
if (NEGRU[nod] == 1)
{
// am mers in ambele rezultate, ambele sunt 0
if (r0 == 1 && r1 == 1)
{
STG[nod] = STG[nod<<1];
if (STG[nod<<1] == m-st+1)
STG[nod] += STG[nod<<1|1];
DRE[nod] = DRE[nod<<1|1];
if (DRE[nod<<1|1] == dr-m)
DRE[nod] += DRE[nod<<1];
MAX[nod] = MAX[nod<<1] > MAX[nod<<1|1]? MAX[nod<<1]: MAX[nod<<1|1];
MAX[nod] = STG[nod] > MAX[nod]? STG[nod]: MAX[nod];
MAX[nod] = DRE[nod] > MAX[nod]? DRE[nod]: MAX[nod];
if (DRE[nod<<1]+STG[nod<<1|1] > MAX[nod])
MAX[nod] = DRE[nod<<1]+STG[nod<<1|1];
NEGRU[nod] = 0;
}
else if (r0 == 1)
{
// am mers doar in partea stanga, fac partea dreapta neagra!
NEGRU[nod<<1|1] = 1;
MAX[nod<<1|1] = STG[nod<<1|1] = DRE[nod<<1|1] = 0;
STG[nod] = STG[nod<<1];
DRE[nod] = 0;
MAX[nod] = MAX[nod<<1];
NEGRU[nod] = 0;
}
else
{
// am mers doar in partea dreapta, fac partea stanga neagra!
NEGRU[nod<<1] = 1;
MAX[nod<<1] = STG[nod<<1] = DRE[nod<<1] = 0;
STG[nod] = 0;
DRE[nod] = DRE[nod<<1|1];
MAX[nod] = MAX[nod<<1|1];
NEGRU[nod] = 0;
}
}
else
{
// era nod normal
STG[nod] = STG[nod<<1];
if (STG[nod<<1] == m-st+1)
STG[nod] += STG[nod<<1|1];
DRE[nod] = DRE[nod<<1|1];
if (DRE[nod<<1|1] == dr-m)
DRE[nod] += DRE[nod<<1];
MAX[nod] = MAX[nod<<1] > MAX[nod<<1|1]? MAX[nod<<1]: MAX[nod<<1|1];
MAX[nod] = STG[nod] > MAX[nod]? STG[nod]: MAX[nod];
MAX[nod] = DRE[nod] > MAX[nod]? DRE[nod]: MAX[nod];
if (DRE[nod<<1]+STG[nod<<1|1] > MAX[nod])
MAX[nod] = DRE[nod<<1]+STG[nod<<1|1];
NEGRU[nod] = 0; // ca sa ajung aici!
}
}
}
int main()
{
freopen("hotel.in", "r", stdin);
freopen("hotel.out", "w", stdout);
scanf("%d%d", &N, &Q);
populate(1, 1, N);
for (i = 1; i <= Q; ++i)
{
scanf("%d", &t);
switch(t)
{
case 1:
{
scanf("%d%d", &a, &b);
insert(1, 1, N, a, a+b-1);
break;
}
case 2:
{
scanf("%d%d", &a, &b);
remove(1, 1, N, a, a+b-1, NEGRU[1]);
break;
}
default:
{
printf("%d\n", MAX[1]);
break;
}
}
}
return 0;
}