#include<stdio.h>
#include<algorithm>
#include<utility>
typedef long long ll;
const int N=4e5+5;
const ll inf=1e18;
struct line{
ll k,b;
line(ll _k=0,ll _b=0):k(_k),b(_b){}
line operator + (const line &x) const{return line(k+x.k,b+x.b);}
void add(ll x){b+=k*x;}
};
auto max = [](line a,line b) -> std::pair<line,ll> {
if(a.k<b.k||(a.k==b.k&&a.b<b.b)) std::swap(a,b);
return a.b>=b.b? std::make_pair(a,inf):std::make_pair(b,(b.b-a.b)/(a.k-b.k));
};
struct ktt{
line sum,lmax,rmax,totmax;
ll x,lazy;
ktt(line _sum=line(),line _lmax=line(),line _rmax=line(),line _totmax=line(),ll _x=0,ll _lazy=0):sum(_sum),lmax(_lmax),rmax(_rmax),totmax(_totmax),x(_x),lazy(_lazy){}
ktt operator + (const ktt &a) const{
ktt res;
std::pair<line,ll> tmp;
res.x=std::min(x,a.x);
res.sum=sum+a.sum;
tmp=max(lmax,sum+a.lmax);
res.lmax=tmp.first;
res.x=std::min(res.x,tmp.second);
tmp=max(a.rmax,rmax+a.sum);
res.rmax=tmp.first;
res.x=std::min(res.x,tmp.second);
tmp=max(totmax,a.totmax);
res.x=std::min(res.x,tmp.second);
tmp=max(tmp.first,rmax+a.lmax);
res.totmax=tmp.first;
res.x=std::min(res.x,tmp.second);
return res;
}
}s[N<<2];
int n,m;
ll a[N];
auto pushup = [](int k) -> void {
ktt res=s[k<<1]+s[k<<1|1];
res.lazy=s[k].lazy;
s[k]=res;
};
auto addtag = [](int k,ll val) -> void {
s[k].lazy+=val;
s[k].sum.add(val);
s[k].lmax.add(val);
s[k].rmax.add(val);
s[k].totmax.add(val);
s[k].x-=val;
};
auto pushdown = [](int k) -> void {
if(s[k].lazy!=0){
addtag(k<<1,s[k].lazy);
addtag(k<<1|1,s[k].lazy);
s[k].lazy=0;
}
};
auto re = [](auto &&self,int k,ll val) -> void {
if(val>s[k].x){
val+=s[k].lazy,s[k].lazy=0;
self(self,k<<1,val),self(self,k<<1|1,val);
pushup(k);
}
else addtag(k,val);
};
auto build = [](auto &&self,int k,int l,int r) -> void {
if(l==r){s[k]=ktt(line(1,a[l]),line(1,a[l]),line(1,a[l]),line(1,a[l]),inf,0);return;}
int mid=l+(r-l>>1);
self(self,k<<1,l,mid),self(self,k<<1|1,mid+1,r);
pushup(k);
};
auto change = [](auto &&self,int k,int l,int r,int x,int y,ll val) -> void {
if(x<=l&&r<=y){re(re,k,val);return;}
pushdown(k);
int mid=l+(r-l>>1);
if(y<=mid) self(self,k<<1,l,mid,x,y,val);
else if(x>mid) self(self,k<<1|1,mid+1,r,x,y,val);
else self(self,k<<1,l,mid,x,y,val),self(self,k<<1|1,mid+1,r,x,y,val);
pushup(k);
};
auto query = [](auto &&self,int k,int l,int r,int x,int y) -> ktt {
if(x<=l&&r<=y) return s[k];
pushdown(k);
int mid=l+(r-l>>1);
if(y<=mid) return self(self,k<<1,l,mid,x,y);
else if(x>mid) return self(self,k<<1|1,mid+1,r,x,y);
else return self(self,k<<1,l,mid,x,y)+self(self,k<<1|1,mid+1,r,x,y);
};
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
build(build,1,1,n);
int opt,x,y;
ll z;
while(m--){
scanf("%d",&opt);
if(opt==1) scanf("%d%d%lld",&x,&y,&z),change(change,1,1,n,x,y,z);
else scanf("%d%d",&x,&y),printf("%lld\n",std::max(0ll,query(query,1,1,n,x,y).totmax.b));
}
return 0;
}