/*
如果是查询[2,4] 就是a2+a3+a4 a2+a3 a2
显然裸地线段树算不出来
我们维护前缀和 那查询的时候还要减去前多计算的
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 100010
#define ll long long
using namespace std;
ll n,m,tot,a[maxn],s[maxn],x,y,z;
struct node
{
ll l,r,lc,rc,lazy,sum;
}t[maxn*4];
ll init()
{
ll x=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
return x*f;
}
void Build(ll li,ll ri)
{
ll k=++tot;
t[k].l=li;t[k].r=ri;
if(li==ri-1)
{
t[k].sum=s[li];return;
}
ll mid=(li+ri)/2;
t[k].lc=tot+1;Build(li,mid);
t[k].rc=tot+1;Build(mid,ri);
t[k].sum=t[t[k].lc].sum+t[t[k].rc].sum;
}
void Updata(int k)
{
t[t[k].lc].lazy+=t[k].lazy;
t[t[k].rc].lazy+=t[k].lazy;
t[t[k].lc].sum+=(t[t[k].lc].r-t[t[k].lc].l)*t[k].lazy;
t[t[k].rc].sum+=(t[t[k].rc].r-t[t[k].rc].l)*t[k].lazy;
t[k].lazy=0;
}
void Change(ll k,ll li,ll ri,ll data)
{
if(li<=t[k].l&&ri>=t[k].r)
{
t[k].sum+=(t[k].r-t[k].l)*data;
t[k].lazy+=data;
return;
}
if(t[k].lazy)Updata(k);
ll mid=(t[k].l+t[k].r)/2;
if(li<mid)Change(t[k].lc,li,ri,data);
if(ri>mid)Change(t[k].rc,li,ri,data);
t[k].sum=t[t[k].lc].sum+t[t[k].rc].sum;
}
ll Query(int k,int li,int ri)
{
if(li<=t[k].l&&ri>=t[k].r)return t[k].sum;
ll r=0;
if(t[k].lazy)Updata(k);
ll mid=(t[k].l+t[k].r)/2;
if(li<mid)r+=Query(t[k].lc,li,ri);
if(ri>mid)r+=Query(t[k].rc,li,ri);
return r;
}
int main()
{
n=init();m=init();
for(int i=1;i<=n;i++)
a[i]=init();
for(int i=1;i<=n;i++)
s[i]=s[i-1]+a[i];
Build(1,n+1);
for(int i=1;i<=m;i++)
{
x=init();y=init();z=init();
if(x==1)Change(1,y,n+1,z);
if(x==2)printf("%lld\n",Query(1,y,z+1)-(z-y+1)*Query(1,y-1,y));
}
return 0;
}