#include <stdio.h>
using namespace std;
int A[15000], arb[59999];
int construieste_arbint(int st, int dr, int indice, int *A) {
if (st == dr) {
arb[indice] = A[st];
return A[st];
}
int mij = st + (dr - st) / 2, a, b;
a = construieste_arbint(st, mij, 2 * indice + 1, A); // mergem pe primul fiu in arbore, indexarea incepe de la 0 deci fiul stang va fi 2 * i + 1
b = construieste_arbint(mij + 1, dr, 2 * indice + 2, A); // mergem pe al doilea fiu, cu indexul 2 * i + 2
arb[indice] = a + b;
return a + b;
}
void actualizeaza(int st, int dr, int a, int b, int indice) {
if (st == dr) {
// daca limitele converg la pozitia ceruta, atunci actualizam valoarea din arbore cu noua valoare
if (st == a)
arb[indice] -= b;
return;
}
int mij = st + (dr - st) / 2;
if (st <= a && a <= dr) {
actualizeaza(st, mij, a, b, 2 * indice + 1);
actualizeaza(mij + 1, dr, a, b, 2 * indice + 2);
arb[indice] = arb[2 * indice + 1] + arb[2 * indice + +2]; //reactualizam maximul pe fiecare interval care continea pozitia a
}
}
int interogheaza(int st, int dr, int a, int b, int indice) {
// daca intervalul [st, dr] e inclus in [a, b] inseamna ca trebuie sa luam toata "bucata"
if (a <= st && dr <= b)
return arb[indice];
// daca nu, atunci cautam subintervalele de pe cei doi fii pana cand subintervalele se incadreaza in cerinta de mai sus
int mij = st + (dr - st) / 2, x = 0, y = 0;
if (a <= mij)
x = interogheaza(st, mij, a, b, indice * 2 + 1);
if (b > mij)
y = interogheaza(mij + 1, dr, a, b, indice * 2 + 2);
// este asigurat ca cel putin o data va merge pe una din ramuri, deci nu trebuie sa avem in vedere cazul cand si x si y sunt 0
return x + y;
}
int main() {
freopen("datorii.in", "r", stdin);
freopen("datorii.out", "w", stdout);
int n, m, cod, a, b;
scanf("%d %d", &n, &m);
for (int i = 0; i < n; i++)
scanf("%d", &A[i]);
arb[0] = construieste_arbint(0, n - 1, 0, A);
for (int i = 0; i < m; i++) {
scanf("%d %d %d", &cod, &a, &b);
if (cod == 0)
actualizeaza(0, n - 1, a - 1, b, 0);
else
printf("%d\n", interogheaza(0, n - 1, a - 1, b - 1, 0));
}
return 0;
}