#include <bits/stdc++.h>
#define INF 0x7f7f7f7f
#define eps 1e-6
#define ll long long
#define ull unsigned long long
#define N 100010
using namespace std;
int n,m;
int arr[4*N+10];
int tree[4*N+10];
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
inline void build_tree(int node,int start,int end)
{
if(start == end)
{
tree[node] = arr[start];
return;
}
int mid = (start+end)/2;
int left_node = 2 * node + 1;
int right_node = 2 * node + 2;
build_tree(left_node , start, mid);
build_tree(right_node, mid+1,end);
tree[node] = tree[left_node] + tree[right_node];
}
inline void update_tree(int node,int start,int end,int idx,int val)
{
if(start == end)
{
arr[idx] = val;
tree[node] = val;
return;
}
int mid = (start + end) /2;
int left_node = 2*node + 1;
int right_node = 2*node + 2;
if(idx >= start && idx <= mid)
{
update_tree(left_node, start, mid, idx, val);
}else{
update_tree(right_node, mid+1, end, idx, val);
}
tree[node] = tree[left_node] + tree[right_node];
}
inline ll query_tree(int node, int start, int end, int L, int R)
{
if(R < start || L > end)
{
return 0;
}
else if(L <= start && end <= R)
{
return tree[node];
}
int mid = (start + end) /2;
int left_node = 2 * node + 1;
int right_node = 2 * node + 2;
int sum_left = query_tree(left_node, start, mid, L, R);
int sum_right = query_tree(right_node, mid+1, end, L, R);
return sum_left + sum_right;
}
void print_tree()
{
for(int i = 0;i < pow(2,n)-1;i++)
{
printf("tree[%d]=%d\n" , i, tree[i]);
}
printf("\n");
}
int main()
{
n=rea d(),m=read();
n--;
for(int i=0; i <= n; i++)
{
arr[i]=read();
}
build_tree(0, 0, n);
for(int i = 1;i <= m; i++)
{
int mode = read();
if(mode == 1)
{
int x = read(),y = read(),k = read();
x--; y--;
for(int j = x;j <= y;j++)
{
update_tree(0, 0, n, j, arr[j]+k);
}
}else{
int x = read(),y = read();
x--; y--;
printf("%lld\n", query_tree(0, 0, n, x, y));
}
}
return 0;
}