#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,t,opt;
int l,r,x;
int a[100005];
int totr=0;
struct node{
int val;
int l,r;
int lch,rch;
int tag;
}rt[400005];
void spread(int x)
{
rt[x].val+=(rt[x].r-rt[x].l+1)*rt[x].tag;
rt[rt[x].lch].tag+=rt[x].tag;
rt[rt[x].rch].tag+=rt[x].tag;
rt[x].tag=0;
}
int calc(int x)
{
return rt[x].val+(rt[x].r-rt[x].l+1)*rt[x].tag;
}
int build(int l,int r)
{
totr++;
int x=totr;
rt[x].l=l;
rt[x].r=r;
if(l==r)
{
rt[x].val=a[l];
return x;
}
int mid_build=(l+r)/2;
rt[x].lch=build(l,mid_build);
rt[x].rch=build(mid_build+1,r);
rt[x].val=rt[rt[x].lch].val+rt[rt[x].rch].val;
return x;
}
void update(int x,int l,int r,int v)
{
int mid_update=(rt[x].l+rt[x].r)/2;
if(rt[x].l==l&&rt[x].r==r)
{
rt[x].tag+=v;
return ;
}
else if(r<=mid_update)
{
update(rt[x].lch,l,r,v);
}
else if(l>=mid_update+1)
{
update(rt[x].rch,l,r,v);
}
else
{
update(rt[x].lch,l,mid_update,v);
update(rt[x].rch,mid_update+1,r,v);
}
rt[x].val=calc(rt[x].lch)+calc(rt[x].rch);
}
int ask(int x,int l,int r)
{
int temp=0;
int mid_ask=(rt[x].l+rt[x].r)/2;
if(rt[x].l==l&&rt[x].r==r)
{
temp+=calc(x);
}
else if(r<=mid_ask)
{
spread(x);
temp+=ask(rt[x].lch,l,r);
}
else if(l>=mid_ask+1)
{
spread(x);
temp+=ask(rt[x].rch,l,r);
}
else
{
spread(x);
temp+= ask(rt[x].lch,l,mid_ask)+ask(rt[x].rch,mid_ask+1,r);
}
return temp;
}
int main()
{
scanf("%d%d",&n,&t);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
build(1,n);
while(t--)
{
scanf("%d",&opt);
if(opt==2)
{
scanf("%d%d",&l,&r);
printf("%d\n",ask(1,l,r));
}
else
{
scanf("%d%d%d",&l,&r,&x);
update(1,l,r,x);
}
}
return 0;
}