#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
int res=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){res=(res<<1)+(res<<3)+(c^48);c=getchar();}
return res*f;
}
struct fhq{
int son[2],rnd,siz;
int val,tag,mx,f;
}tr[114514];
int root,cnt = 0;
int New(int val)
{
tr[++cnt].val = val;
tr[cnt].rnd = rand();
tr[cnt].siz = 1;
tr[cnt].son[0] = tr[cnt].son[1] = 0;
return cnt;
}
void pushup(int u){
tr[u].siz = tr[tr[u].son[0]].siz+tr[tr[u].son[1]].siz+1;
tr[u].mx = tr[u].val;
if (tr[u].son[0])
tr[u].mx = max(tr[u].mx,tr[tr[u].son[0]].mx);
if (tr[u].son[1])
tr[u].mx = max(tr[u].mx,tr[tr[u].son[1]].mx);
}
void pushdown(int u)
{
if (tr[u].f){
swap(tr[u].son[0],tr[u].son[1]);
if (tr[u].son[0])
tr[tr[u].son[0]].f ^= 1;
if (tr[u].son[1])
tr[tr[u].son[1]].f ^= 1;
tr[u].f = 0;
}
if (tr[u].tag)
{
if (tr[u].son[0]){
tr[tr[u].son[0]].mx += tr[u].tag;
tr[tr[u].son[0]].tag += tr[u].tag;
tr[tr[u].son[0]].val += tr[u].tag;
}
if (tr[u].son[1]){
tr[tr[u].son[1]].mx += tr[u].tag;
tr[tr[u].son[1]].tag += tr[u].tag;
tr[tr[u].son[1]].val += tr[u].tag;
}
tr[u].tag = 0;
pushup(u);
}
}
void split(int rt,int val,int &x,int &y)
{
if (!rt){
x = y = 0;
return ;
}
pushdown(rt);
if (tr[tr[rt].son[0]].siz < val){
x = rt;
split(tr[rt].son[1],val-tr[tr[rt].son[0]].siz-1,tr[rt].son[1],y);
}else{
y = rt;
split(tr[rt].son[0],val,x,tr[rt].son[0]);
}
pushup(rt);
}
int merge(int x,int y)
{
if (!x || !y) return x|y;
pushdown(x); pushdown(y);
if (tr[x].rnd < tr[y].rnd)
{
tr[x].son[1] = merge(tr[x].son[1],y);
pushup(x);
return x;
}
else
{
tr[y].son[0] = merge(x,tr[y].son[0]);
pushup(y);
return y;
}
}
void insert(int x){
root = merge(root,New(x));
return ;
}
void add(int l,int r,int v)
{
int a,b,c;
split(root,r,b,c);
split(root,l-1,a,b);
tr[b].tag += v;
tr[b].val += v;
tr[b].mx += v;
root = merge(a,merge(b,c));
}
void revs(int l,int r)
{
int a,b,c;
split(root,r,b,c);
split(root,l-1,a,b);
tr[b].f ^= 1;
root = merge(a,merge(b,c));
}
int MAX(int l,int r)
{
int a,b,c;
int res;
split(root,r,b,c);
split(root,l-1,a,b);
res = tr[b].mx;
root = merge(a,merge(b,c));
return res;
}
int n,m;
signed main()
{
n = read();
m = read();
for (int i = 1; i <= n; i++)
insert(0);
int opt,l,r,v;
while (m--)
{
opt = read();
l = read(); r = read();
if (opt == 1) v = read(),add(l,r,v);
if (opt == 2) revs(l,r);
if (opt == 3) printf("%lld\n",MAX(l,r));
}
return 0;
}