#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;
node() {
a = b = c = 0;
}
};
node arb[NMAX*3 + 10];
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);
}
inline void updateSons(int v,int l,int r) {
int mid = (l + r)>>1;
int leftSon = v<<1;
int rightSon = leftSon + 1;
if(arb[v].c == r - l + 1) {
arb[leftSon].a = arb[leftSon].b = arb[leftSon].c = mid - l + 1;
arb[rightSon].a = arb[rightSon].b = arb[rightSon].c = r - mid;
}
else
if(arb[v].c == 0) {
arb[leftSon].a = arb[leftSon].b = arb[leftSon].c = 0;
arb[rightSon].a = arb[rightSon].b = arb[rightSon].c = 0;
}
}
void update(int v,int Left,int Right,int lB, int rB,int t){
if(Right < lB || Left > rB) return;
if(Right - Left > 0) updateSons(v,Left,Right);
if(lB <= Left && Right <= rB) {
arb[v].a = arb[v].b = arb[v].c = t == 0 ? 0 : Right - Left + 1;
return;
}
if(Left == Right) return;
int mid = (Left + Right)>>1;
int leftSon = v<<1;
int rightSon = leftSon + 1;
update(leftSon,Left,mid,lB,rB,t);
update(rightSon,mid + 1,Right,lB,rB,t);
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);
}
int main() {
cin>>N>>P;
buildTree(1,1,N);
for(int t, pos, num;P;P--) {
cin>>t;
if(t == 1) {
cin>>pos>>num;
update(1,1,N,pos,pos + num - 1,0);
} else
if(t == 2) {
cin>>pos>>num;
update(1,1,N,pos,pos + num - 1,1);
} else {
cout<<arb[1].c<<"\n";
}
}
return 0;
}