#include <bits/stdc++.h>
using namespace std;
#define NMAX 100010 * 4
#define INF 1e9
#define int long long
struct node{
int lazy = 0, val = 0, nn = 0;
int pref, suf, ssm, suma;
};
node aint[NMAX];
int a[NMAX],n, Q;
node _merge(node left, node right){
node res;
res.nn = left.nn + right.nn;
res.ssm = max(max(right.ssm, left.ssm), right.pref + left.suf);
res.pref = max(left.pref, left.suma + right.pref);
res.suf = max(right.suf, right.suma+ left.suf);
res.suma = left.suma + right.suma;
return res;
}
void setNode(node &smt, int val){
int aux = val * smt.nn;
smt.suma = aux;
smt.suf = aux;
smt.pref = aux;
smt.ssm = aux;
}
void clearNode(node &smt){
smt.pref = INF, smt.suf = INF, smt.ssm = INF, smt.suma = INF;
}
void build(int nod, int st, int dr){
if(st == dr){
aint[nod].pref = aint[nod].suf = aint[nod].ssm = aint[nod].suma = 1;
aint[nod].nn = 1;
}else{
int mid = (st + dr ) / 2;
build(nod * 2, st, mid);
build(nod * 2 + 1, mid + 1, dr);
aint[nod] = _merge(aint[nod * 2], aint[nod * 2 + 1]);
}
}
void updateLazy(int nod){
if(aint[nod].lazy){
aint[nod].lazy = 0;
aint[2*nod].lazy = aint[2*nod+1].lazy = 1;
aint[2*nod].val = aint[2*nod+1].val = aint[nod].val;
setNode(aint[nod * 2], aint[nod].val);
setNode(aint[nod * 2 + 1], aint[nod].val);
}
}
void update(int nod, int st, int dr, int left, int right, int val){
if(st >= left && dr <= right){
aint[nod].lazy = 1;
aint[nod].val = val;
setNode(aint[nod], val);
}else{
updateLazy(nod);
int mid = (st + dr ) / 2;
if(left <= mid){
update(nod * 2, st, mid, left, right, val);
}
if(right > mid){
update(nod * 2 +1, mid + 1, dr, left,right, val);
}
aint[nod] = _merge(aint[nod * 2], aint[nod * 2 + 1]);
}
}
signed main(void){
ofstream cout("hotel.out");
ifstream cin("hotel.in");
cin >> n >> Q;
build(1,1,n);
while(Q--){
int T;
cin >> T;
if(T == 1){
int x, y;
cin >> x >> y;
y = x + y - 1;
update(1,1,n,x,y,-INF);
}else if(T == 2){
int x, y;
cin >> x >> y;
y = x + y - 1;
update(1,1,n,x,y,1);
}else{
cout << max(0ll, aint[1].ssm) << '\n';
}
}
}