#include <cstdio>
#include <algorithm>
#define NMax 100005
using namespace std;
struct ArbInt
{
int L, R, M, V;
int Length;
};
ArbInt AI[3*NMax];
int N;
inline ArbInt Merge (ArbInt A, ArbInt B)
{
ArbInt Result;
Result.L=A.L;
if (A.L==A.Length)
{
Result.L+=B.L;
}
Result.R=B.R;
if (B.R==B.Length)
{
Result.R+=A.R;
}
Result.M=A.R+B.L;
Result.M=max (Result.M, A.M);
Result.M=max (Result.M, B.M);
Result.M=max (Result.M, Result.L);
Result.M=max (Result.M, Result.R);
Result.Length=A.Length+B.Length;
Result.V=-1;
if (A.V==B.V)
{
Result.V=A.V;
}
return Result;
}
inline void Build (int K, int L, int R)
{
int Mid=(L+R)/2;
if (L==R)
{
AI[K].V=0;
AI[K].L=AI[K].R=AI[K].M=AI[K].Length=1;
return;
}
Build (2*K, L, Mid);
Build (2*K+1, Mid+1, R);
AI[K]=Merge (AI[2*K], AI[2*K+1]);
}
inline void Update (int K, int L, int R, int UL, int UR, int V)
{
int Mid=(L+R)/2;
if (UL<=L and R<=UR)
{
AI[K].L=AI[K].R=AI[K].R=AI[K].Length*(1-V);
AI[K].V=V;
return;
}
if (AI[K].V!=-1)
{
Update (2*K, L, Mid, L, Mid, AI[K].V);
Update (2*K+1, Mid+1, R, Mid+1, R, AI[K].V);
AI[K].V=-1;
}
if (UL<=Mid)
{
Update (2*K, L, Mid, UL, UR, V);
}
if (UR>Mid)
{
Update (2*K+1, Mid+1, R, UL, UR, V);
}
AI[K]=Merge (AI[2*K], AI[2*K+1]);
}
int main()
{
freopen ("hotel.in", "r", stdin);
freopen ("hotel.out", "w", stdout);
int NQ;
scanf ("%d %d", &N, &NQ);
Build (1, 1, N);
for (; NQ>0; --NQ)
{
int Type, X, Y;
scanf ("%d", &Type);
if (Type==3)
{
printf ("%d\n", AI[1].M);
continue;
}
scanf ("%d %d", &X, &Y);
Y=X+Y-1;
Update (1, 1, N, X, Y, 2-Type);
}
return 0;
}