#include <bits/stdc++.h>
#define LS (2 * Node)
#define RS ((2 * Node) + 1)
using namespace std;
const int NM = 100005;
struct Node
{
int Best,Left,Right;
};
int N,M,Pos;
Node Tree[3 * NM];
void Update(int Node,int L,int R,int Lt,int Rt,int Val)
{
if (L > Rt || R < Lt)
return;
if (Lt <= L && R <= Rt)
{
Tree[Node].Best = Tree[Node].Left = Tree[Node].Right = (Val == 2 ? R - L + 1 : 0);
return;
}
int Middle = (L + R) / 2;
if (!Tree[Node].Best)
Tree[LS].Best = Tree[LS].Left = Tree[LS].Right = 0,
Tree[RS].Best = Tree[RS].Left = Tree[RS].Right = 0;
if (Tree[Node].Best == R - L + 1)
Tree[LS].Best = Tree[LS].Left = Tree[LS].Right = Middle - L + 1,
Tree[RS].Best = Tree[RS].Left = Tree[RS].Right = R - Middle;
Update(LS,L,Middle,Lt,Rt,Val);
Update(RS,Middle + 1,R,Lt,Rt,Val);
Tree[Node].Best = max(max(Tree[LS].Best,Tree[RS].Best),Tree[LS].Right + Tree[RS].Left);
Tree[Node].Left = Tree[LS].Left;
if (Tree[LS].Best == Middle - L + 1)
Tree[Node].Left += Tree[RS].Left;
Tree[Node].Right = Tree[RS].Right;
if (Tree[RS].Best == R - Middle)
Tree[Node].Right += Tree[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,Nr,L,R;
scanf("%d",&Q);
if (Q == 3)
printf("%d\n",Tree[1].Best);
else
{
scanf("%d %d",&L,&Nr);
R = L + Nr - 1;
Update(1,1,N,L,R,Q);
}
}
return 0;
}