#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
ifstream fin("hotel.in");
ofstream fout("hotel.out");
struct node {
int mx,st,dr,lazy,len;
}tree[400005];
node combine(node a,node b) {
node c;
c.len=a.len+b.len;
if (a.st==a.len) {
c.st=b.st+a.len;
}else {
c.st=a.st;
}
if (b.dr==b.len) {
c.dr=a.dr+b.len;
}else {
c.dr=b.dr;
}
c.mx=max(a.mx,max(b.mx,a.dr+b.st));
c.lazy=0;
return c;
}
void build(int l,int r,int node) {
if (l==r) {
tree[node].st = 1;
tree[node].dr = 1;
tree[node].mx = 1;
tree[node].len = 1;
return;
}
int mij=(l+r)/2;
build(l,mij,node*2);
build(mij+1,r,node*2+1);
tree[node]=combine(tree[2*node],tree[2*node+1]);
}
void assign(int node, int val) {
if (val==1) {
tree[node].st = tree[node].dr = tree[node].mx = 0;
tree[node].lazy = 1;
}else if (val==2) {
tree[node].st = tree[node].dr = tree[node].mx = tree[node].len;
tree[node].lazy = 2;
}
}
void push_down(int l,int r,int node) {
if (tree[node].lazy) {
assign(2*node,tree[node].lazy);
assign(2*node+1,tree[node].lazy);
tree[node].lazy = 0;
}
}
void update(int l,int r,int val,int st,int dr,int node) {
if (l<=st && dr<=r) {
assign(node,val);
return;
}
int mij=(st+dr)/2;
push_down(l,r,node);
if (l<=mij) {
update(l,r,val,st,mij,node*2);
}
if (r>mij) {
update(l,r,val,mij+1,dr,node*2+1);
}
tree[node]=combine(tree[2*node],tree[2*node+1]);
}
int main() {
int n,q;
fin >> n >> q;
build(1,n,1);
while(q--) {
int cer;
fin >> cer;
if (cer==1) {
int a,b;
fin >> a >> b;
update(a,a+b-1,1,1,n,1);
}else if (cer==2) {
int a,b;
fin >> a >> b;
update(a,a+b-1,2,1,n,1);
}else {
fout << tree[1].mx << "\n";
}
}
return 0;
}