#include <fstream>
using namespace std;
ifstream in("hotel.in");
ofstream out("hotel.out");
struct tree
{
long long pref, suf, smax, lazy;
};
tree segtree[400005];
int n, m;
void update_node(int node, int left, int right)
{
int m = (left + right) / 2;
tree left_node = segtree[2*node];
tree right_node = segtree[2*node+1];
//int left_node = 2*node;
//int right_node = 2*node+1;
if(left_node.pref == m - left + 1)
{
segtree[node].pref = m - left + 1 + right_node.pref;
}
else
{
segtree[node].pref = left_node.pref;
}
if(right_node.suf == right - m)
{
segtree[node].suf = right - m + left_node.suf;
}
else
{
segtree[node].suf = right_node.suf;
}
segtree[node].smax = max(left_node.suf + right_node.pref, max(left_node.smax, right_node.smax));
/*segtree[node].pref =
(segtree[left_node].pref == m - left + 1) ?
(m - left + 1) + segtree[right_node].pref :
segtree[left_node].pref;
segtree[node].suf =
(segtree[right_node].suf == right - m) ?
(right - m) + segtree[left_node].suf :
segtree[right_node].suf;
segtree[node].smax =
max(segtree[left_node].suf + segtree[right_node].pref,
max(segtree[left_node].smax,
segtree[right_node].smax));*/
}
void build(int node, int left, int right)
{
if(left == right)
{
segtree[node].pref = 1;
segtree[node].suf = 1;
segtree[node].smax = 1;
}
else
{
int m = (left + right) / 2;
build(2*node, left, m);
build(2*node+1, m+1, right);
update_node(node, left, right);
}
}
void update_lazy(int node, int left, int right)
{
if(segtree[node].lazy == 1)
{
segtree[node].smax = 0;
segtree[node].pref = 0;
segtree[node].suf = 0;
if(left != right)
{
segtree[2*node].lazy = 1;
segtree[2*node+1].lazy = 1;
}
segtree[node].lazy = 0;
}
else if(segtree[node].lazy == 2)
{
segtree[node].smax = right - left + 1;
segtree[node].pref = right - left + 1;
segtree[node].suf = right - left + 1;
if(left != right)
{
segtree[2*node].lazy = 2;
segtree[2*node+1].lazy = 2;
}
segtree[node].lazy = 0;
}
}
void update(int node, int left, int right, int qleft, int qright, int val)
{
if(qleft <= left && right <= qright)
{
segtree[node].lazy = val;
}
else
{
int m = (left + right) / 2;
update_lazy(node, left, right);
if(qleft <= m)
{
update(2*node, left, m, qleft, qright, val);
}
if(m+1 <= qright)
{
update(2*node+1, m+1, right, qleft, qright, val);
}
update_lazy(2*node, left, m);
update_lazy(2*node+1, m+1, right);
update_node(node, left, right);
}
}
long long query(int node, int left, int right)
{
update_lazy(node, left, right);
return segtree[node].smax;
}
int main()
{
in>>n>>m;
build(1, 1, n);
//segtree[1].lazy = 2;
int c, x, y, z;
while(m--)
{
in>>c;
if(c == 3)
{
out<<query(1, 1, n)<<'\n';
}
else
{
in>>x>>z;
y = z + x - 1;
update(1, 1, n, x, y, c);
}
}
return 0;
}