#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<set>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#include<iostream>
#include<string>
#include<cmath>
#define FOR(i,a,b) for(i=(a);i<=(b);i++)
#define ROF(i,a,b) for(i=(a);i>=(b);i--)
#define N 100010
typedef long long LL;
using namespace std;
int swap(int &x,int &y){int t=x;x=y;y=t;}
int L=0,ans[N],a[N];
struct Splay
{
  //tp 0-lc 1-rc
  int lc[3*N],rc[3*N],tp[3*N],s[3*N],fa[3*N],key[3*N],ct[3*N],rev[3*N],lazy[3*N],Max[3*N];
  int root,len,cnt,inf,sta[N],top;
  void init(){root=len=cnt=0;inf=2e9;}
  void upd(int x)
  {
    if (x==0) return;
    Max[x]=key[x];
    if (lc[x]>0) Max[x]=max(Max[x],Max[lc[x]]);
    if (rc[x]>0) Max[x]=max(Max[x],Max[rc[x]]);
  }
  void lt(int x)
  {
    int y=fa[x];tp[x]=tp[y];fa[x]=fa[y];tp[y]=1;fa[y]=x;
    s[x]=s[y];s[y]=s[rc[y]]+s[rc[x]]+ct[y];
    if (rc[x]!=0) {fa[rc[x]]=y;tp[rc[x]]=0;}
    lc[y]=rc[x];rc[x]=y;
    if (fa[x]==0) root=x;
    upd(y);upd(x);
  }
  void rt(int x)
  {
    int y=fa[x];tp[x]=tp[y];fa[x]=fa[y];tp[y]=0;fa[y]=x;
    s[x]=s[y];s[y]=s[lc[y]]+s[lc[x]]+ct[y];
    if (lc[x]!=0) {fa[lc[x]]=y;tp[lc[x]]=1;}
    rc[y]=lc[x];lc[x]=y;
    if (fa[x]==0) root=x;
    upd(y);upd(x);
  }
  void rotate(int x)
  {
    pushdown(fa[x]); 
    pushdown(x);  
    if (tp[x]==0) lt(x);else rt(x);
  }
  void pushdown(int x)
  {
    if (rev[x]==1)
    {                                                
      swap(lc[x],rc[x]);
      tp[lc[x]]=0;tp[rc[x]]=1;
      rev[lc[x]]^=1;rev[rc[x]]^=1;
      rev[x]=0;
    }
    key[lc[x]]+=lazy[x];key[rc[x]]+=lazy[x];
    Max[lc[x]]+=lazy[x];Max[rc[x]]+=lazy[x];
    lazy[lc[x]]+=lazy[x];lazy[rc[x]]+=lazy[x];
    lazy[x]=0;
  }
  void splay(int x)
  {
    int t=x;
    while (t!=root) rotate(t);
  }
  void build(int x,int L,int R)
  {
    int mid=(L+R)>>1;
    key[x]=a[mid];s[x]=ct[x]=1;rev[x]=0;Max[x]=key[x];
    if (mid>L) 
    {
      lc[x]=++len;fa[lc[x]]=x;tp[lc[x]]=0;
      build(lc[x],L,mid-1);s[x]+=s[lc[x]];
    }
    if (mid<R)
    {
      rc[x]=++len;fa[rc[x]]=x;tp[rc[x]]=1;
      build(rc[x],mid+1,R);s[x]+=s[rc[x]];
    }
    upd(x);
  }
  int select(int x,int ks)
  {
    pushdown(x);
    int ls=s[lc[x]];
    if (ks<=ls) return select(lc[x],ks);
    if (ks<=ls+ct[x]) return x;
    return select(rc[x],ks-ls-ct[x]);
  }
  int getid(int L,int R)
  {
    int pL=select(root,L-1+1);
    splay(pL);
    int troot=root;
    int pR=select(root,R+1+1);
    root=rc[root];
    fa[root]=0;
    splay(pR);
    fa[root]=troot;tp[root]=1;rc[troot]=root;
    root=troot;upd(lc[root]);upd(root);
    return lc[rc[root]];
  }
  void reverse(int L,int R)
  {
    if (L>R) return;
    int id=getid(L,R);
    rev[id]^=1;//prt(root);
  }
  void change(int L,int R,int d)
  {
    if (L>R) return;
    int id=getid(L,R);
    lazy[id]+=d;key[id]+=d;Max[id]+=d;//prt(root);
    upd(fa[id]);upd(fa[fa[id]]);
  }
  int getmax(int L,int R)
  {
    int id=getid(L,R);
    return Max[id];
  }
}tree;
int main()
{
  tree.init();
  tree.root=1;tree.len=1;
  int i,n,m;
  scanf("%d%d",&n,&m);
  memset(a,0,sizeof(a));
  a[0]=a[n+1]=-1e9;
  tree.build(tree.root,0,n+1);
  FOR(i,1,m)
  {
    int op,t1,t2,t3;
    scanf("%d %d %d",&op,&t1,&t2);
    if (op==1) 
    {
      scanf("%d",&t3);
      tree.change(t1,t2,t3);
    }else if (op==2)
    {
      tree.reverse(t1,t2);
    }else
    {
      int ans=tree.getmax(t1,t2);
      printf("%d\n",ans);
    }   
  }
}