#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <sstream>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
using namespace std;
#define ll long long
#define re register
#define mp make_pair
#define fi first
#define se second
#define pb push_back
#define P pair<int,int>
const int N=1e6+10;
void read(ll &a)
{
int d=1;
char ch;
a=0;
while(ch=getchar(),!isdigit(ch))
if(ch=='-')
d=-1;
a=ch^48;
while(ch=getchar(),isdigit(ch))
a=(a<<3)+(a<<1)+(ch^48);
a*=d;
}
void write(ll x)
{
if(x<0)
putchar(45),x=-x;
if(x>9)
write(x/10);
putchar(x%10+'0');
}
ll ans[N<<1],a[N],tag[N<<1];
ll ls(ll i){return i<<1;}///左儿子
ll rs(ll i){return i<<1|1;}///右儿子
void push_up(ll p){ans[p]=ans[ls(p)]+ans[rs(p)];}///区间合并
void built(ll p,ll l,ll r)
{
if(l==r)
{
ans[p]=a[l];
return;
}
ll mid=(l+r)>>1;
built(ls(p),l,mid);
built(rs(p),mid+1,r);
push_up(p);///回溯时做区间合并
}
void f(ll p,ll l,ll r,ll k)
{
tag[p]+=k;
ans[p]+=(r-l+1)*k;
}
void push_down(ll p,ll l,ll r)
{
ll mid=(l+r)>>1;
f(ls(p),l,mid,tag[p]);///将父节点所带的值加到子区间去
f(rs(p),mid+1,r,tag[p]);
tag[p]=0;///然后父节点的值归0
}
void update(ll nl,ll nr,ll l,ll r,ll p,ll k)
{
if(nl<=l&&r<=nr)///包含整个区间,直接加就完事
{
ans[p]+=(r-l+1)*k;
tag[p]+=k;
return;
}
push_down(p,l,r);///将该父节点的值放入子区间
ll mid=(l+r)>>1;
if(nl<=mid)
update(nl,nr,l,mid,ls(p),k);
if(nr>mid)
update(nl,nr,mid+1,r,rs(p),k);
push_up(p);///合并区间
}
ll query(ll nl,ll nr,ll l,ll r,ll p)
{
ll res=0;
if(nl<=l&&r<=nr)
return ans[p];
ll mid=(l+r)>>1;
push_down(p,l,r);
if(nl<=mid)
res+=query(nl,nr,l,mid,ls(p));
if(nr>mid)
res+=query(nl,nr,mid+1,r,rs(p));
return res;
}
int main()
{
//freopen("out.txt","w",stdout);
ll n,T;
read(n);
read(T);
for(re ll i=1;i<=n;i++)
read(a[i]);
built(1,1,n);
while(T--)
{
ll f;
read(f);
if(f==1)
{
ll l,r,k;
read(l);
read(r);
read(k);
update(l,r,1,n,1,k);
}
else
{
ll l,r;
read(l);
read(r);
write(query(l,r,1,n,1));
putchar('\n');
}
}
return 0;
}