#include<bits/stdc++.h>
using namespace std;
long long n,m,x,y,k,a1;
long long tree[1000200]/*线段树模型*/, tag[1000050];// 懒惰标志
long long a[1000050];//数组模型
void build(int rt, int l, int r)
{
if (l == r) {
tree[rt] = a[l];
tag[rt] = 0;//将懒惰标志清零(初始化)
return;
}
int mid = (l + r) >> 1;
build(rt * 2, l, mid);//递归左儿子
build(rt * 2 + 1, mid + 1, r);//递归右儿子
tree[rt] = tree[rt * 2] + tree[rt * 2 + 1];
}//构造二叉树模型
void down(int rt, int l, int mid, int r)
{
int val = tag[rt];
tag[rt] = 0;
tree[rt * 2] += val * (mid - l + 1);
tag[rt * 2] += val;
tree[rt * 2 + 1] += val * (r - mid);
tag[rt * 2 + 1] += val;
}
void update(int rt, int l, int r, int x, int y, int val)//(x,y)为需要更新的区间,val为需要加的值
{
if (y < l || x > r) return;//不在此区间,跳过
if (x <= l && r <= y)/*在此区间*/ {
tree[rt] += val * (r - l + 1);//更新线段树模型
tag[rt] += val;//更新懒惰标志的值
return;
}
int mid = (l + r) >> 1;
down(rt, l, mid, r);//调用懒惰标志下放函数
update(rt * 2, l, mid, x, y, val);//递归左儿子
update(rt * 2 + 1, mid + 1, r, x, y, val);//递归右儿子
tree[rt] = tree[rt * 2] + tree[rt * 2 + 1];
}//更新
long long query(long long rt, long long l, long long r, long long x, long long y)
{
if (y < l || r < x) return 0;//不在此区间,跳过
if (x <= l && r <= y) return tree[rt];/*在此区间*/
int mid = (l + r) >> 1;
down(rt, l, mid, r);
return query(rt * 2, l, mid, x, y) + query(rt * 2 + 1, mid + 1, r, x, y);
}//查询
int main()
{
scanf("%d%d",&n,&m);
for(long long i=1;i<=n;i++) scanf("%d",&a[i]);
build(1,1,n);
for(long long i=1;i<=m;i++)
{
scanf("%d",&a1);
if(a1==1){
scanf("%d%d%d",&x,&y,&k);
update(1,1,n,x,y,k);
}
else{
scanf("%d%d",&x,&y);
printf("%d\n",query(1,1,n,x,y));
}
}
return 0;
}