#include <cstdio>
#include <algorithm>
using namespace std;
const int NMAX = 100005;
struct Node
{
int Best, Left, Right;
};
int N, M, Pos;
Node ArbInt[4*NMAX + 5];
void Update(int Node, int L, int R, int X, int Y, int Val)
{
if (L > Y || R < X)
return;
if (X <= L && R <= Y)
{
ArbInt[Node].Best = ArbInt[Node].Left = ArbInt[Node].Right = (Val == 2 ? R - L + 1 : 0);
return;
}
int Middle = (L + R) / 2;
int LS = 2 * Node;
int RS = 2 * Node + 1;
if (!ArbInt[Node].Best)
ArbInt[LS].Best = ArbInt[LS].Left = ArbInt[LS].Right = 0,
ArbInt[RS].Best = ArbInt[RS].Left = ArbInt[RS].Right = 0;
if (ArbInt[Node].Best == R - L + 1)
ArbInt[LS].Best = ArbInt[LS].Left = ArbInt[LS].Right = Middle - L + 1,
ArbInt[RS].Best = ArbInt[RS].Left = ArbInt[RS].Right = R - Middle;
Update(LS, L, Middle, X, Y, Val);
Update(RS, Middle + 1, R, X, Y, Val);
ArbInt[Node].Best = max(max(ArbInt[LS].Best, ArbInt[RS].Best), ArbInt[LS].Right + ArbInt[RS].Left);
ArbInt[Node].Left = ArbInt[LS].Left;
if (ArbInt[LS].Best == Middle - L + 1)
ArbInt[Node].Left += ArbInt[RS].Left;
ArbInt[Node].Right = ArbInt[RS].Right;
if (ArbInt[RS].Best == R - Middle)
ArbInt[Node].Right += ArbInt[LS].Right;
}
int main()
{
freopen("hotel.in", "r", stdin);
freopen("hotel.out", "w", stdout);
scanf("%d%d", &N, &M);
Update(1, 1, N, 1, N, 2);
while(M--)
{
int Q;
scanf("%d", &Q);
if (Q == 3)
printf("%d\n", ArbInt[1].Best);
else
{
int L, Nr;
scanf("%d%d", &L, &Nr);
int R = L + Nr - 1;
Update(1, 1, N, L, R, Q);
}
}
return 0;
}