#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 50010;
int n, m;
int root, idx;
int x, y, z;
struct Tree
{
int s[2], size, v;
int dat;
int add, rev;
int maxn;
}tr[N];
void pushup(int u)
{
tr[u].size = tr[tr[u].s[0]].size + tr[tr[u].s[1]].size + 1;
tr[u].maxn = max(tr[tr[u].s[1]].maxn, tr[tr[u].s[0]].maxn);
}
void pushdown(int u)
{
if (tr[u].add)
{
tr[tr[u].s[0]].v += tr[u].add, tr[tr[u].s[1]].v += tr[u].add;
tr[tr[u].s[0]].add += tr[u].add, tr[tr[u].s[1]].add += tr[u].add;
tr[tr[u].s[0]].maxn += tr[u].add, tr[tr[u].s[1]].maxn += tr[u].add;
tr[u].add = 0;
}
if (tr[u].rev)
{
swap(tr[u].s[0], tr[u].s[1]);
tr[tr[u].s[0]].rev ^= 1, tr[tr[u].s[1]].rev ^= 1;
tr[u].rev = 0;
}
}
void split(int u, int sz, int &x, int &y)
{
if (!u) x = y = 0;
else
{
pushdown(u);
if (tr[tr[u].s[0]].size + 1 <= sz) x = u, split(tr[u].s[1], sz - tr[tr[u].s[0]].size - 1, tr[u].s[1], y);
else y = u, split(tr[u].s[0], sz, x, tr[u].s[0]);
pushup(u);
}
}
int merge(int a, int b)
{
if (!a || !b) return a + b;
if (tr[a].dat < tr[b].dat)
{
pushdown(a);
tr[a].s[1] = merge(tr[a].s[1], b);
pushup(a);
return a;
}
else
{
pushdown(b);
tr[b].s[0] = merge(a, tr[b].s[0]);
pushup(b);
return b;
}
}
void insert(int v)
{
tr[ ++ idx].v = v, tr[idx].size = 1, tr[idx].dat = rand(), tr[idx].maxn = v;
root = merge(root, idx);
}
void reverse_interval(int l, int r)
{
split(root, l - 1, x, y), split(y, r - l + 1, y, z);
tr[y].rev ^= 1;
root = merge(x, merge(y, z));
}
void add_interval(int l, int r, int v)
{
split(root, l - 1, x, y), split(y, r - l + 1, y, z);
tr[y].add += v;
tr[y].maxn += v;
root = merge(x, merge(y, z));
}
int query(int l, int r)
{
split(root, l - 1, x, y), split(y, r - l + 1, y, z);
int res = tr[y].maxn;
root = merge(x, merge(y, z));
return res;
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i ++ ) insert(0);
while (m -- )
{
int opt, l, r, v;
scanf("%d%d%d", &opt, &l, &r);
if (opt == 1)
{
scanf("%d", &v);
add_interval(l, r, v);
}
else if (opt == 2) reverse_interval(l, r);
else printf("%d\n", query(l, r));
}
return 0;
}