// Matteo Verzotti - C++
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <ctime>
#include <map>
#include <chrono>
#include <cmath>
#define INF 0x3f3f3f3f
#define MAX(a,b) a>b ? a:b
#define MIN(a,b) a<b ? a:b
using namespace std;
const int N = 100000;
struct nod {
int maxim, st, dr;
} aint[4 * N];
int v[5 + N];
void Build(int nod, int st,int dr) {
aint[nod].maxim = dr - st + 1;
aint[nod].st = dr - st + 1;
aint[nod].dr = dr - st + 1;
if(dr - st > 0) {
int mid;
mid = (st + dr) >> 1;
Build(nod * 2, st, mid);
Build(nod * 2 + 1, mid + 1, dr);
}
}
void Update(int nod, int st, int dr, int x, int y, int tip) {
if(st == dr) {
aint[nod].maxim = tip;
aint[nod].st = tip;
aint[nod].dr = tip;
} else {
int mid;
mid = (st + dr) >> 1;
if(x <= st && dr <= y) {
aint[nod].maxim = aint[nod].st = aint[nod].dr = tip * (dr - st + 1);
} else {
if(aint[nod].maxim == 0) {
aint[2 * nod].maxim = aint[2 * nod].st = aint[2 * nod].dr = 0;
aint[2 * nod + 1].maxim = aint[2 * nod + 1].st = aint[2 * nod + 1].dr = 0;
}
if(aint[nod].maxim == dr - st + 1) {
aint[2 * nod].maxim = aint[2 * nod].st = aint[2 * nod].dr = mid - st + 1;
aint[2 * nod + 1].maxim = aint[2 * nod + 1].st = aint[2 * nod + 1].dr = dr - mid;
}
if(x <= mid)
Update(nod * 2, st, mid, x, y, tip);
if(y > mid)
Update(nod * 2 + 1, mid + 1, dr, x, y, tip);
aint[nod].st = aint[2 * nod].st;
aint[nod].dr = aint[2 * nod + 1].dr;
if(aint[nod].st == mid - st + 1) aint[nod].st += aint[2 * nod + 1].st;
if(aint[nod].dr == dr - mid) aint[nod].dr += aint[2 * nod].dr;
aint[nod].maxim = max(aint[2 * nod].dr + aint[2 * nod + 1].st, max(aint[2 * nod].maxim, aint[2 * nod + 1].maxim));
}
}
}
int main() {
freopen("hotel.in","r",stdin);
freopen("hotel.out","w",stdout);
int n, m, i, p, x, y;
scanf("%d%d", &n, &m);
Build(1,1,n);
for(i = 1; i <= m; i++) {
scanf("%d", &p);
if(p == 3) printf("%d\n",aint[1].maxim);
else {
scanf("%d%d", &x, &y);
Update(1, 1, n, x, x + y - 1, p - 1);
}
}
return 0;
}