#include <bits/stdc++.h>
using namespace std;
ifstream fin("hotel.in");
ofstream fout("hotel.out");
int n;
class AINT
{
private:
static const int NAint=1<<19;
struct nod
{
int lmax=0,prefix=0,sufix=0,l=0;
};
void combinNod(nod& out, const nod& st, const nod& dr)
{
out.l=st.l+dr.l;
out.prefix=st.prefix+(st.prefix==st.l)*dr.prefix;
out.sufix=dr.sufix+(dr.sufix==dr.l)*st.sufix;
out.lmax=max(st.lmax, dr.lmax);
out.lmax=max(out.lmax, st.sufix+dr.prefix);
}
public:
void build(int node=0, int st=1, int dr=n)
{
data[node].l=data[node].lmax=data[node].prefix=data[node].sufix=(dr-st+1);
if(st==dr)
return;
int mij=(st+dr)/2;
build(2*node+1, st, mij);
build(2*node+2, mij+1, dr);
}
void add(const int& qst, const int& qdr, int node=0, int st=1, int dr=n)
{
if(dr<qst || qdr<st)
return;
if(qst<=st && dr<=qdr)
{
data[node].lmax=data[node].prefix=data[node].sufix=0;
}
if(st==dr)
return;
int mij=(st+dr)/2;
add(qst, qdr, 2*node+1, st, mij);
add(qst, qdr, 2*node+2, mij+1, dr);
combinNod(data[node], data[2*node+1], data[2*node+2]);
}
void free(const int& qst, const int& qdr, int node=0, int st=1, int dr=n)
{
if(dr<qst || qdr<st)
return;
if(qst<=st && dr<=qdr)
{
data[node].lmax=data[node].prefix=data[node].sufix=(dr-st+1);
}
if(st==dr)
return;
int mij=(st+dr)/2;
free(qst, qdr, 2*node+1, st, mij);
free(qst, qdr, 2*node+2, mij+1, dr);
combinNod(data[node], data[2*node+1], data[2*node+2]);
}
int query()
{
return data[0].lmax;
}
private:
nod data[NAint];
};
AINT aint;
int main()
{
int m;
fin>>n>>m;
aint.build();
for(int q=1; q<=m; q++)
{
int C;
fin>>C;
if(C==3)
{
fout<<aint.query()<<'\n';
}
else
{
int a,b;
fin>>a>>b; b=a+b-1;
if(C==1)
aint.add(a, b);
else aint.free(a, b);
}
}
return 0;
}