#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define Nmax 100010
#define LeftSon (2 * Node)
#define RightSon (2 * Node + 1)
struct SegTree
{
int Left, Right, Best, Used;
}Aint[4 * Nmax];
int N, M, Type, Start, Lg;
void Build(int Node, int Left, int Right)
{
Aint[Node].Left = Aint[Node].Right = Aint[Node].Best = Right - Left + 1;
Aint[Node].Used = 2;
if(Left == Right) return ;
int Mid = (Left + Right) / 2;
Build(LeftSon, Left, Mid);
Build(RightSon, Mid + 1, Right);
}
void Update(int Node, int Left, int Right, int LeftBound, int RightBound, int Used)
{
if(LeftBound <= Left && Right <= RightBound)
{
Aint[Node].Used = Used;
Aint[Node].Left = Aint[Node].Right = Aint[Node].Best = Used * (Right - Left + 1);
return ;
}
int Mid = (Left + Right) / 2;
if(Aint[Node].Used != 2)
{
Update(LeftSon, Left, Mid, Left, Mid, Aint[Node].Used);
Update(RightSon, Mid + 1, Right, Mid + 1, Right, Aint[Node].Used);
Aint[Node].Used = 2;
}
if(LeftBound <= Mid) Update(LeftSon, Left, Mid, LeftBound, RightBound, Used);
if(Mid < RightBound) Update(RightSon, Mid + 1, Right, LeftBound, RightBound, Used);
Aint[Node].Best = max(max(Aint[LeftSon].Best, Aint[RightSon].Best), Aint[LeftSon].Right + Aint[RightSon].Left);
if(Aint[LeftSon].Left == Mid - Left + 1) Aint[Node].Left = Aint[LeftSon].Left + Aint[RightSon].Left;
else Aint[Node].Left = Aint[LeftSon].Left;
if(Aint[RightSon].Right == Right - Mid) Aint[Node].Right = Aint[RightSon].Right + Aint[LeftSon].Right;
else Aint[Node].Right = Aint[RightSon].Right;
}
int main()
{
freopen("hotel.in", "r", stdin);
freopen("hotel.out", "w", stdout);
scanf("%i %i", &N, &M);
Build(1, 1, N);
for(int i = 1; i <= M; ++ i)
{
scanf("%i", &Type);
if(Type < 3)
{
scanf("%i %i", &Start, &Lg);
Update(1, 1, N, Start, Start + Lg - 1, Type - 1);
}else printf("%i\n", Aint[1].Best);
}
return 0;
}