#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<ctime>
using namespace std;
const int N=200005;
int n,bit,q;
long long sum[N<<2],mn[N<<2],mx[N<<2],add[N<<2];
long long max(long long a,long long b){
return a>b?a:b;
}
long long min(long long a,long long b){
return a<b?a:b;
}
void build(){
for(bit=1;bit<=n;bit<<=1);
for(int i=bit+1;i<=bit+n;i++){
scanf("%lld",&mx[i]);
sum[i]=mn[i]=mx[i];
}
for(int i=bit-1;i;i--){
sum[i]=sum[i<<1]+sum[i<<1|1];
mn[i]=min(mn[i<<1],mn[i<<1|1]),
mn[i<<1]-=mn[i],mn[i<<1|1]-=mn[i];
mx[i]=max(mx[i<<1],mx[i<<1|1]),
mx[i<<1]-=mx[i],mx[i<<1|1]-=mx[i];
}
}
void update_node(int x,int val){
int a;
mx[x+bit]+=val,mn[x+bit]+=val;
for(x=x+bit;x;x>>=1){
sum[x]+=val;
a=max(mx[x<<1],mx[x<<1|1]),mx[x<<1]-=a,mx[x<<1|1]-=a,mx[x]+=a;
a=min(mn[x<<1],mn[x<<1|1]),mn[x<<1]-=a,mn[x<<1|1]-=a,mn[x]+=a;
}
}
void update_RMQ(int s,int t,int val){
int a;
if(s==t){
update_node(s,val);
return ;
}
mx[s+bit]+=val,mn[s+bit]+=val;
mx[t+bit]+=val,mn[t+bit]+=val;
for(s=s+bit,t=t+bit;s^t^1;s>>=1,t>>=1){
if(~s&1){
mx[s^1]+=val,mn[s^1]+=val;
}
if(t&1){
mx[t^1]+=val,mn[t^1]+=val;
}
a=max(mx[s<<1],mx[s<<1|1]),mx[s<<1]-=a,mx[s<<1|1]-=a,mx[s]+=a;
a=min(mn[s<<1],mn[s<<1|1]),mn[s<<1]-=a,mn[s<<1|1]-=a,mn[s]+=a;
a=max(mx[t<<1],mx[t<<1|1]),mx[t<<1]-=a,mx[t<<1|1]-=a,mx[t]+=a;
a=min(mn[t<<1],mn[t<<1|1]),mn[t<<1]-=a,mn[t<<1|1]-=a,mn[t]+=a;
}
a=max(mx[t<<1],mx[t<<1|1]),mx[t<<1]-=a,mx[t<<1|1]-=a,mx[t]+=a;
a=min(mn[t<<1],mn[t<<1|1]),mn[t<<1]-=a,mn[t<<1|1]-=a,mn[t]+=a;
for(;s;s>>=1){
a=max(mx[s<<1],mx[s<<1|1]),mx[s<<1]-=a,mx[s<<1|1]-=a,mx[s]+=a;
a=min(mn[s<<1],mn[s<<1|1]),mn[s<<1]-=a,mn[s<<1|1]-=a,mn[s]+=a;
}
}
void update_sum(int s,int t,long long val){
long long lc=0,rc=0,len=1;
for(s=bit+s-1,t=bit+t+1;s^t^1;s>>=1,t>>=1,len<<=1){
sum[s]+=val*lc;
sum[t]+=val*rc;
if(~s&1){
add[s^1]+=val,sum[s^1]+=val*len,lc+=len;
}
if(t&1){
add[t^1]+=val,sum[t^1]+=val*len,rc+=len;
}
}
for(;s||t;s>>=1,t>>=1){
sum[s]+=val*lc,sum[t]+=val*rc;
}
}
long long query_RMQ_node(int x,long long ans=0){
for(x+=bit;x;x>>=1){
ans+=mn[x];
}
return ans;
}
long long query_sum_node(int x,long long ans=0){
for(;x;x>>=1){
ans+=sum[x];
}
return ans;
}
long long query_sum(int s,int t){
int lc=0,rc=0,len=1;
long long ans=0;
if(s==t){
query_sum_node(s);
}
for(s=bit+s-1,t=bit+t+1;s^t^1;s>>=1,t>>=1,len<<=1){
if(add[s]){
ans+=add[s]*lc;
}
if(add[t]){
ans+=add[t]*rc;
}
if(~s&1){
ans+=sum[s^1],lc+=len;
}
if(t&1)
ans+=sum[t^1],rc+=len;
}
for (;s||t;s>>=1,t>>=1){
ans+=add[s]*lc;
ans+=add[t]*rc;
}
return ans;
}
long long query_min(int s,int t,int L=0,int R=0,long long ans=0){
if(s==t){
query_RMQ_node(s);
}
for(s+=bit,t+=bit;s^t^1;s>>=1,t>>=1){
L+=mn[s],R+=mn[t];
if(~s&1){
L=min(L,mn[s^1]);
}
if(t&1){
R=min(R,mn[t^1]);
}
}
L+=mn[s],R+=mn[t];
for(ans=min(L,R),s>>=1;s;s>>=1){
ans+=mn[s];
}
return ans;
}
long long query_max(int s,int t,int L=0,int R=0,long long ans=0){
if(s==t){
query_RMQ_node(s);
}
for(s+=bit,t+=bit;s^t^1;s>>=1,t>>=1){
L+=mx[s],R+=mx[t];
if(~s&1){
L=max(L,mx[s^1]);
}
if(t&1){
R=max(R,mx[t^1]);
}
}
L+=mx[s],R+=mx[t];
for(ans=max(L,R),s>>=1;s;s>>=1){
ans+=mx[s];
}
return ans;
}
int main(){
int opt,x,y,k;
scanf("%d%d",&n,&q);
build();
for(int i=1;i<=q;i++){
scanf("%d",&opt);
if(opt==1){
scanf("%d%d%d",&x,&y,&k);
update_sum(x,y,k);
}
else if(opt==2){
scanf("%d%d",&x,&y);
printf("%lld\n",query_sum(x,y));
}
}
return 0;
}