#include<iostream>
#include<algorithm>
const long long MAXN = 50010;
long long Tree[MAXN];
long long A[10010];
long long Lazy[MAXN];
void PushDown(long long Root,long long Start,long long End){
long long mid = (Start + End)/2;
Lazy[Root*2+1] += Lazy[Root];
Lazy[Root*2+2] += Lazy[Root];
Tree[Root*2+1] += Lazy[Root]*(mid - Start);
Tree[Root*2+2] += Lazy[Root]*(End - mid);
Lazy[Root] = 0;
}
void BuildTree(long long Root,long long Start,long long End){
if((End - Start)<=1){
Tree[Root] = A[Start];
return;
}
long long mid = (Start+End)/2;
BuildTree(2*Root+1,Start,mid);
BuildTree(2*Root+2,mid,End);
Tree[Root]=Tree[2*Root+1] + Tree[2*Root+2];
}
void SectionAddTree(long long Root,long long Start,long long End,long long StartOfIndex,long long EndOfIndex,long long value){
if(Lazy[Root]){
PushDown(Root,Start,End);
}
if(StartOfIndex >= End or EndOfIndex<=Start){
return;
}
if(Start>=StartOfIndex && EndOfIndex >=End){
Tree[Root] += value*(End-Start);
Lazy[Root] += value;
return;
}
long long mid = (Start+End)/2;
SectionAddTree(2*Root+1,Start,mid,StartOfIndex,EndOfIndex,value);
SectionAddTree(2*Root+2,mid,End,StartOfIndex,EndOfIndex,value);
Tree[Root]=Tree[2*Root+1] + Tree[2*Root+2];
}
long long QueryTree(long long Root,long long Start,long long End,long long StartOfQuery,long long EndOfQuery){
if(StartOfQuery>=End or EndOfQuery <=Start){
return 0;
}
if(Start>=StartOfQuery && EndOfQuery >=End){
return Tree[Root];
}
if(Lazy[Root]){
PushDown(Root,Start,End);
}
long long mid = (Start+End)/2;
return QueryTree(Root*2+1,Start,mid,StartOfQuery,EndOfQuery)+QueryTree(Root*2+2,mid,End,StartOfQuery,EndOfQuery);
}
int main(){
int n,m;
std::cin>>n>>m;
for(int i = 0;i<n;i++){
std::cin>>A[i];
}
BuildTree(0,0,n);
for(int i = 0;i<18;i++){
int Type;
std::cin>>Type;
if(Type == 1){
int x,y,k;
std::cin>>x>>y>>k;
SectionAddTree(0,0,n,x-1,y,k);
}
if(Type == 2){
int x,y;
std::cin>>x>>y;
std::cout<<QueryTree(0,0,n,x-1,y)<<'\n';
}
}
}