#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
#define inf -0x7fffffff
int A[N];//存储原数组
int n,m;
struct node{
long long val,maxx;
}tree[N*4];
void pushup(int rt)
{
tree[rt].val = tree[rt*2].val + tree[rt*2+1].val;
tree[rt].maxx = max(tree[rt*2].maxx,tree[rt*2+1].maxx);
}
void build(int rt,int l,int r)
{
if(l>r) return ;
if(l==r)
{
tree[rt].val = A[l];
tree[rt].maxx = A[l];
return ;
}
int mid = l+r>>1;
build(rt*2,l,mid),build(rt*2+1,mid+1,r);
pushup(rt);
}
//查询1:查询[l,r]中的最大值
int query1(int rt,int l,int r,int L,int R)
{
if(l>R||r<L) return inf;
//好坑啊啊啊啊,如果查询区间在当前区间以外即[l,r]和[L,R]没有交集,则返回最大负值,不能返回0,因为
//初始值可能为很大的负数
if(r>=R&&l<=L) return tree[rt].maxx;
int mid = L+R>>1;
return max(query1(rt*2,l,r,L,mid) , query1(rt*2+1,l,r,mid+1,R));
}
//查询2:查询[l,r]的区间和
int query2(int rt,int l,int r,int L,int R)
{
if(l<=L&&r>=R) return tree[rt].val;
if(l>R||r<L) return 0;
int mid = L+R>>1;
return query2(rt*2,l,r,L,mid) + query2(rt*2+1,l,r,mid+1,R);
}
//更新1:单点更新:A[a]+=b
void update(int rt,int L,int R,int a,int b)
{
if(a>R||a<L) return ;
if(L==R)
{
tree[rt].val+=b;
return ;
}
int mid = L+R>>1;
update(rt*2,L,mid,a,b),update(rt*2+1,mid+1,R,a,b);
pushup(rt);
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
scanf("%d",&A[i]);
}
build(1,1,n);
// for(int i=1;i<=n*4;i++) cout<<tree[i].maxx<<endl;
int t,x,y;
while(m--)
{
scanf("%d%d%d",&t,&x,&y);
if(t==0) printf("%d\n",query2(1,x,y,1,n));
else update(1,1,n,x,y);
}
return 0;
}