//1 x y k:将区间[x,y]内每个数加上k。
//2 x y:输出区间[x,y]内每个数的和。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+10;
ll a[N];
struct node
{
ll v,f;
}tree[4*N];
void build(ll l,ll r,ll now)//建树
{
tree[now].f=0;
if(l==r)
{
//scanf("%lld",&tree[now].v);
tree[now].v=a[l];
return;
}
ll mid=(l+r)>>1;
build(l,mid,now<<1);
build(mid+1,r,now<<1|1);
tree[now].v=tree[now<<1].v+tree[now<<1|1].v;
}
//-------- lazy 标记 ---------//
void pushdown(ll now,ll l,ll r,ll l1,ll l2)//下传lazy 标记
{
tree[l].v+=tree[now].f*l1;
tree[l].f+=tree[now].f;
tree[r].v+=tree[now].f*l2;
tree[r].f+=tree[now].f;
tree[now].f=0;
}
void change(ll l,ll r,ll now,ll x,ll y,ll k)//区间修改
{
if(x<=l&&r<=y)
{
tree[now].v+=k*(r-l+1);
tree[now].f+=k;
return;
}
ll mid=(l+r)>>1;
if(tree[now].f)
pushdown(now,now<<1,now<<1|1,mid-l+1,r-mid);
if(x<=mid)
change(l,mid,now<<1,x,y,k);
if(y>mid)
change(mid+1,r,now<<1|1,x,y,k);
tree[now].v=tree[now<<1].v+tree[now<<1|1].v;
}
ll query(ll l,ll r,ll now,ll x,ll y)//区间查询
{
if(x<=l&&r<=y)
return tree[now].v;
ll mid=(l+r)>>1;
if(tree[now].f)
pushdown(now,now<<1,now<<1|1,mid-l+1,r-mid);
if(y<=mid)
return query(l,mid,now<<1,x,y);
else if(x>mid)
return query(mid+1,r,now<<1|1,x,y);
else
return query(l,mid,now<<1,x,y)+query(mid+1,r,now<<1|1,x,y);
}
int main(){
//freopen("in.txt","r",stdin);
int n,m;scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
build(1,n,1);
while(m--){
int op;
ll x,y,k;
scanf("%d",&op);
if(op==1){
scanf("%lld%lld%lld",&x,&y,&k);
change(1,n,1,x,y,k);
}
else{
scanf("%lld%lld",&x,&y);
printf("%lld\n",query(1,n,1,x,y));
}
}
return 0;
}