#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define ll long long
#define INF 0x3f3f3f3f
#define re register
#define il inline
#define gc getchar
#define int ll
inline int read()
{
int f=1,k=0;
char c = getchar();
while (c <'0' || c > '9')
{
if (c=='-') f=-1;
c=getchar();
}
while(c >= '0' && c <= '9') k = (k << 1)+(k << 3)+(c^48),c=getchar();
return k*f;
}
const int N = 50005;
struct node
{
int l,r,add,tag,dat,size,val,maxn;
}t[N];
int root,idx;
void pushup(int u)
{
t[u].size = t[t[u].l].size + t[t[u].r].size + 1;
t[u].maxn = t[u].val;
if (t[u].l) t[u].maxn = max(t[t[u].l].maxn,t[u].maxn);
if (t[u].r) t[u].maxn = max(t[t[u].r].maxn,t[u].maxn);
}
void pushdown(int u)
{
if (t[u].add)
{
if (t[u].l)
{
t[t[u].l].val += t[u].add;
t[t[u].l].add += t[u].add;
t[t[u].l].maxn += t[u].add;
}
else
{
t[t[u].r].val += t[u].add;
t[t[u].r].maxn += t[u].add;
t[t[u].r].add += t[u].add;
}
t[u].add = 0;
pushup(u);
}
if (t[u].tag)
{
if (t[u].l) t[t[u].l].tag ^= 1;
if (t[u].r) t[t[u].r].tag ^= 1;
t[u].tag = 0;
swap(t[u].l,t[u].r);
}
}
int New(int x)
{
idx++;
t[idx].l = t[idx].r = 0;
t[idx].add = t[idx].tag = 0;
t[idx].dat = rand();
t[idx].size = 1;
t[idx].val = x;
t[idx].maxn = x;
return idx;
}
void split(int u,int siz,int &l,int &r)
{
if (u == 0){l = r = 0;return ;}
pushdown(u);
if (siz > t[t[u].l].size) l = u,split(t[u].r,siz-t[t[u].l].size-1,t[u].r,r);
else r = u,split(t[u].l,siz,l,t[u].l);
pushup(u);
}
int merge(int l,int r)
{
if (l) pushdown(l);
if (r) pushdown(r);
if (!l || ! r) return l + r;
if (t[l].dat < t[r].dat)
{
t[l].r = merge(t[l].r,r);
pushup(l);
return l;
}
else
{
t[r].l = merge(l,t[r].l);
pushup(r);
return r;
}
}
void rot(int l,int r)
{
int L,R,M;
split(root,r,L,R);
split(L,l-1,L,M);
t[M].tag ^= 1;
root = merge(merge(L,M),R);
}
int qmax(int l,int r)
{
int L,R,M;
split(root,r,L,R);
split(L,l-1,L,M);
int res = t[M].maxn;
root = merge(merge(L,M),R);
return res;
}
void modify(int l,int r,int v)
{
int L,R,M,C;
split(root,r,L,R);
split(L,l-1,C,M);
t[M].add += v;t[M].val += v,t[M].maxn += v;
root = merge(merge(C,M),R);
}
int n,m;
signed main()
{
cin >> n >> m;
t[0].maxn = -1e18;
for (int i = 1;i <= n;i++)
{
root = merge(root,New(0));
}
while (m--)
{
int op,l,r,v;
cin >> op >> l >> r;
if (op == 1)
{
cin >> v;
modify(l,r,v);
}
else if (op == 2)
{
rot(l,r);
}
else
{
cout << qmax(l,r) << endl;
}
}
return 0;
}