#include <fstream>
#define NMAX 15002
#define DIM 60002
using namespace std;
ifstream fin ("datorii.in");
ofstream fout ("datorii.out");
int n, m, v[NMAX];
int arbint[DIM];
void update(int poz, int val, int nod, int in, int sf); //ii dau pozitia pe care vreau sa pun valoarea val
int query(int st, int dr, int nod, int in, int sf);
int main()
{
bool tip;
int i, st, dr, suma, zi;
fin>>n>>m;
for(i = 1; i <= n; i++)
{
fin>>v[i];
update(i, v[i], 1, 1, n);
}
for(i = 1; i <= m; i++)
{
fin>>tip;
if(tip) //operatie de tip 1(B) - query
{
fin>>st>>dr;
fout<<query(st, dr, 1, 1, n)<<'\n';
}
else
{
fin>>zi>>suma; //v[i] -= suma
update(zi, v[zi] - suma, 1, 1, n);
v[zi] -= suma;
}
}
return 0;
}
void update(int poz, int val, int nod, int in, int sf)
{
int mij;
//cazul de baza al recursiei
if(in == sf) //am ajuns intr-o frunza
{
if(in == poz) //este frunza de care am nevoie
arbint[nod] = val;
return;
}
mij = (in + sf) / 2;
if(in <= poz && poz <= mij) //ma duc in stanga
update(poz, val, 2 * nod, in, mij);
if(mij < poz && poz <= sf) //ma duc in dreapta
update(poz, val, 2 * nod + 1, mij + 1, sf);
arbint[nod] = arbint[nod * 2] + arbint[nod * 2 + 1]; //actualizare recursiva
}
int query(int st, int dr, int nod, int in, int sf)
{
int mij;
//am 3 cazuri
if(st <= in && sf <= dr) //daca intervalul meu este perfect inclus in intervalul cautat
return arbint[nod];
mij = (in + sf) / 2; //iau mijlocul intervalului cautat
if(mij < st) //ma duc in dreapta
{
return query(st, dr, 2 * nod + 1, mij + 1, sf);
}
if(mij >= dr) //ma duc in stanga
{
return query(st, dr, 2 * nod, in, mij);
}
return query(st, dr, 2 * nod, in, mij) + query(st, dr, 2 * nod + 1, mij + 1, sf); //ma duc in ambele
}