#include <fstream>
#include <algorithm>
using namespace std;
ifstream cin("hotel.in");
ofstream cout("hotel.out");
const int NMAX = int(1e5) + 2;
int N, P;
struct node {
int a, b, c;
int needUpdate;
node() {
needUpdate = 0;
a = b = c = 0;
}
};
node arb[NMAX*3];
void buildTree(int v,int l,int r) {
arb[v].a = arb[v].b = arb[v].c = r - l + 1;
if(l == r) return;
int mid = (l + r)>>1;
buildTree(v<<1,l,mid);
buildTree((v<<1) + 1,mid + 1,r);
}
void update2(int v,int Left,int Right,int lB,int rB);
void update1(int v,int Left,int Right,int lB,int rB){
if(Right < lB || Left > rB) return;
if(arb[v].needUpdate != 0) {
arb[v].needUpdate == -1 ? update1(v,Left,Right,Left,Right) : update2(v,Left,Right,Left,Right);
arb[v].needUpdate = 0;
}
if(lB <= Left && Right <= rB) {
arb[v].a = arb[v].b = arb[v].c = 0;
arb[v].needUpdate = -1;
return;
}
if(Left == Right) return;
int mid = (Left + Right)>>1;
int leftSon = v<<1;
int rightSon = leftSon + 1;
update1(leftSon,Left,mid,lB,rB);
update1(rightSon,mid + 1,Right,lB,rB);
arb[v].a = arb[leftSon].a;
if(arb[leftSon].a == mid - Left + 1) {
arb[v].a += arb[rightSon].a;
}
arb[v].b = arb[rightSon].b;
if(arb[rightSon].b == Right - mid) {
arb[v].b += arb[leftSon].b;
}
arb[v].c = arb[leftSon].b + arb[rightSon].a;
arb[v].c = max(max(arb[v].c,arb[v].a),arb[v].b);
arb[v].c = max(max(arb[v].c,arb[leftSon].c),arb[rightSon].c);
}
void update2(int v,int Left,int Right,int lB,int rB){
if(Right < lB || Left > rB) return;
if(arb[v].needUpdate != 0) {
arb[v].needUpdate == -1 ? update1(v,Left,Right,Left,Right) : update2(v,Left,Right,Left,Right);
arb[v].needUpdate = 0;
}
if(lB <= Left && Right <= rB) {
arb[v].a = arb[v].b = arb[v].c = Right - Left + 1;
arb[v].needUpdate = 1;
return;
}
if(Left == Right) return;
int leftSon = v<<1;
int rightSon = leftSon + 1;
int mid = (Left + Right)>>1;
update2(leftSon,Left,mid,lB,rB);
update2(rightSon,mid + 1,Right,lB,rB);
arb[v].a = arb[leftSon].a;
if(arb[leftSon].a == mid - Left + 1) {
arb[v].a += arb[rightSon].a;
}
arb[v].b = arb[rightSon].b;
if(arb[rightSon].b == Right - mid) {
arb[v].b += arb[leftSon].b;
}
arb[v].c = arb[leftSon].b + arb[rightSon].a;
arb[v].c = max(max(arb[v].c,arb[v].a),arb[v].b);
arb[v].c = max(max(arb[v].c,arb[leftSon].c),arb[rightSon].c);
}
inline int query() {
return arb[1].c;
}
int main() {
cin>>N>>P;
buildTree(1,1,N);
for(int t, pos, num;P;P--) {
cin>>t;
if(t == 1) {
cin>>pos>>num;
update1(1,1,N,pos,pos + num - 1);
} else
if(t == 2) {
cin>>pos>>num;
update2(1,1,N,pos,pos + num - 1);
} else {
cout<<query()<<"\n";
}
}
return 0;
}