#include<bits/stdc++.h>
#define int long long // 开 long long
#define maxn 100005 // 本题 n <= 1e5
#define ls(x) (x<<1) // 左子树
#define rs(x) (x<<1|1) // 右子树
using namespace std;
// 定义线段树框架变量
int num[maxn],n,m,op,x,y,k;
int tree[maxn<<2],tag[maxn<<2];
// 更新 tree[p]
void pushup(int p){
tree[p]=tree[ls(p)]+tree[rs(p)];
}
// 建线段树
void build(int pl,int pr,int p){
if (pl==pr){ tree[p]=num[pl]; return; }
int mid=(pl+pr)>>1;
build(pl,mid,ls(p));
build(mid+1,pr,rs(p));
pushup(p);
}
// 给节点 p 打 tag 标记
void addtag(int pl,int pr,int p,int k){
tag[p]+=k,tree[p]+=(pr-pl+1)*k;
}
// 下传 tag
void pushdown(int pl,int pr,int p){
if (tag[p]){
int mid=(pl+pr)>>1;
addtag(pl,mid,ls(p),tag[p]);
addtag(mid+1,pr,rs(p),tag[p]);
tag[p]=0;
}
}
// 将区间 [l,r] 的每个数加 k,现在节点是 p,表示 [pl,pr] 的区间和
void update(int pl,int pr,int p,int l,int r,int k){
if (l<=pl && r>=pr){ addtag(pl,pr,p,k); return; }
pushdown(pl,pr,p);
int mid=(pl+pr)>>1;
if (l<=mid) update(pl,mid,ls(p),l,r,k);
if (r>mid) update(mid+1,pr,rs(p),l,r,k);
pushup(p);
}
// 查询区间 [l,r] 的和,现在节点是 p,表示 [pl,pr] 的区间和
int query(int pl,int pr,int p,int l,int r){
if (l<=pl && r>=pr) return tree[p];
pushdown(pl,pr,p);
int mid=(pl+pr)>>1,ans=0;
if (l<=mid) ans+=query(pl,mid,ls(p),l,r);
if (r>mid) ans+=query(mid+1,pr,rs(p),l,r);
return ans;
}
signed main(){
scanf("%lld%lld",&n,&m);
for (int i=1;i<=n;i++) scanf("%lld",&num[i]);
for (int i=1;i<=m;i++){
scanf("%lld%lld%lld",&op,&x,&y);
if (op==1) scanf("%lld",&k),update(1,n,1,x,y,k); // 区间修改
else printf("%lld\n",query(1,n,1,x,y)); // 区间查询
}
return 0;
}