#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
using namespace std;
int n,m;
int a[500009];
long long int ans=0;
struct node{
int l,r;
long long int num;
}tree[4000009];
void build(int left,int right,int ind)
{//建树
tree[ind].l=left;
tree[ind].r=right;
if(left==right) return;
int mid=(left+right)/2;
build(left,mid,ind*2);
build(mid+1,right,ind*2+1);
}
int add(int ind)
{//区间加点
if(tree[ind].l==tree[ind].r)
{
tree[ind].num=a[tree[ind].r];
return tree[ind].num;
}
tree[ind].num=add(ind*2)+add(ind*2+1);
return tree[ind].num;
}
void my_plus(int ind,int dis,int k)//ind为此时的所在的区间的标号,dis为修改的点,k为咬修改的值
{//单点修改
tree[ind].num+=k;
if(tree[ind].l==tree[ind].r) return;
if(tree[ind*2].r>=dis) my_plus(ind*2,dis,k);
if(tree[ind*2+1].l<=dis) my_plus(ind*2+1,dis,k);
}
void search(int ind,int l,int r)
{//区间查询
if(tree[ind].l>=l&&tree[ind].r<=r)//如果这个节点所代表的区间全部在要查询的范围内,则加上,返回
{
ans+=tree[ind].num;
return;
}
if(tree[ind*2].r>=l) search(ind*2,l,r);
if(tree[ind*2+1].l<=r) search(ind*2+1,l,r);
}
void pls(int ind,int l,int r,int k)
{//区间修改
if(tree[ind].l>=l&&tree[ind].r<=r)
{
tree[ind].num+=k;
return;
}
if(tree[ind*2].r>=l) pls(ind*2,l,r,k);
if(tree[ind*2+1].l<=r) pls(ind*2+1,l,r,k);
}
void search_p(int ind,int dis)//ind 根节点,dis目标节点
{//区间查点
ans+=tree[ind].num;
if(tree[ind].l==tree[ind].r)
{
return;
}
if(dis<=tree[ind*2].r) search_p(ind*2,dis);
if(dis>=tree[ind*2+1].l) search_p(ind*2+1,dis);
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
build(1,n,1);
add(1);
for(int i=1;i<=m;i++)
{
int ques,x,y,k;
cin>>ques;
if(ques==1) cin>>x>>y>>k,pls(1,x,y,k);
if(ques==2)
{
cin>>x>>y;
ans=0;
search(1,x,y);
cout<<ans<<endl;
}
}
return 0;
}