rt
#include <bits/stdc++.h>
#define INF 0x7fffffff
#define RE register
#define pii pair<int,int>
#define kp make_pair
#define pb push_back
#define fi first
#define se second
#define IT iterator
#define root 1, n, 1
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define lowbit(x) x & -x
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int N = 5e4 + 10;
const int M = 1e5 + 10;
const int LOG = 20;
const LL MOD = 998244353;
LL read()
{
LL x = 0, f = 1; char ch = getchar();
while (ch < '0' || ch > '9')
{
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
x = (x << 3) + (x << 1) + (LL)(ch - '0'), ch = getchar();
return x * f;
}
void write(LL n)
{
if (n < 0)
putchar('-'),
n = -n;
if (n >= 10)
write(n / 10);
putchar(n % 10 + '0');
}
inline void writee(LL n)
{
write(n); puts("");
}
inline void writes(LL n)
{
write(n); putchar(' ');
}
int n, m;
int rt, tot;
int K, L, R, V;
int wei[N], siz[N], ch[N][2]; LL val[N], vall[N], maxx[N];
bool lazy1[N]; LL lazy2[N];
inline int newnode(LL v)
{
wei[++tot] = rand();
val[tot] = v;
siz[tot] = 1;
maxx[tot] = vall[tot] = 0;
return tot;
}
inline void pushup(int p)
{
siz[p] = siz[ch[p][0]] + siz[ch[p][1]] + 1;
maxx[p] = vall[p];
if (ch[p][0])
maxx[p] = max(maxx[p], vall[ch[p][0]]);
if (ch[p][1])
maxx[p] = max(maxx[p], vall[ch[p][1]]);
}
inline void pushdown1(int p)
{
swap(ch[p][0], ch[p][1]);
if (ch[p][0])
lazy1[ch[p][0]] ^= 1;
if (ch[p][1])
lazy1[ch[p][1]] ^= 1;
lazy1[p] = 0;
}
inline void pushdown2(int p)
{
if (ch[p][0])
{
vall[ch[p][0]] += lazy2[p];
lazy2[ch[p][0]] += lazy2[p];
}
if (ch[p][1])
{
vall[ch[p][1]] += lazy2[p];
lazy2[ch[p][1]] += lazy2[p];
}
lazy2[p] = 0;
}
int merge(int x, int y)
{
if (!x || !y)
return x + y;
if (wei[x] < wei[y])
{
if (lazy1[x])
pushdown1(x);
if (lazy2[x])
pushdown2(x);
ch[x][1] = merge(ch[x][1], y);
pushup(x);
return x;
}
else
{
if (lazy1[y])
pushdown1(y);
if (lazy2[y])
pushdown2(y);
ch[y][0] = merge(x, ch[y][0]);
pushup(y);
return y;
}
}
void split(int p, LL v, int &x, int &y)
{
if (!p)
{
x = y = 0;
return;
}
if (lazy1[p])
pushdown1(p);
if (lazy2[p])
pushdown2(p);
if (v <= siz[ch[p][0]])
{
y = p;
split(ch[p][0], v, x, ch[p][0]);
}
else
{
x = p;
split(ch[p][1], v - siz[ch[p][0]] - 1, ch[p][1], y);
}
pushup(p);
}
int main()
{
srand(time(0));
n = read(); m = read();
for (int i = 1; i <= n; ++i)
{
int x, y;
split(rt, i, x, y);
rt = merge(merge(x, newnode(i)), y);
}
for (int _ = 1; _ <= m; ++_)
{
K = read(); L = read(); R = read();
int x, y, z;
split(rt, L - 1, x, y);
split(y, R - L + 1, y, z);
if (K == 1)
{
V = read();
vall[y] += V;
lazy2[y] += V;
}
else if (K == 2)
lazy1[y] ^= 1;
else
writee(maxx[y]);
rt = merge(x, merge(y, z));
}
return 0;
}