#include<stdio.h>
#define NMAX 100001
int N, M, S[NMAX];
//S este sirul prin care se reprezinta arborele binar
int binary(int x){
int no;
no = ((x^(x-1))+1)>>1;
return no;
}
void modify(int pos, int val){
//adauga val elementului de pe pozitia pos. Este folosita pt op de tip 0
int i;
for(i = pos; i <= N; i += binary(i))
S[i] = S[i] + val;
}
int sum(int pos){
//calculeaza suma de la 1 la pos
int res = 0, i;
for(i = pos; i >= 1; i -= binary(i))
res = res + S[i];
return res;
}
int query_sum(int left, int right){
//returneaza suma elem din intervalul [left, right] pt operatia de tip 1
int sum1, sum2, res;
sum1 = sum(left - 1);
sum2 = sum(right);
res = sum2 - sum1;
return res;
}
int pos_sum(int val){
//returneaza pozitia minima pe care suma elem este egala cu val pt operatia de tip 2
int res, l = 1, r = N, m;
while(l <= r){
m = (l + r) / 2;
res = sum(m);
if(res == val)
return m;
if(res < val)
l = m + 1;
else
r = m - 1;
}
return -1;
}
void read_solve_print(FILE *pf, FILE *pg){
int i, code, a, b, k, pos, elem, sm;
fscanf(pf, "%d %d", &N, &M);
for(i = 1; i <= N; i++){
fscanf(pf, "%d", &elem);
if(i % 2 == 1)
S[i] = elem;
else
S[i] = elem + query_sum(i - binary(i) + 1, i - 1);
}
for(i = 1; i <= M; i++){
fscanf(pf, "%d", &code);
if(code == 0){
fscanf(pf, "%d %d", &a, &b);
modify(a, b);
}
else
if(code == 1){
fscanf(pf, "%d %d", &a, &b);
sm = query_sum(a, b);
fprintf(pg, "%d\n", sm);
}
else{
fscanf(pf, "%d", &a);
pos = pos_sum(a);
fprintf(pg, "%d\n", pos);
}
}
}
int main(){
FILE *pf, *pg;
pf = fopen("aib.in", "r");
pg = fopen("aib.out", "w");
read_solve_print(pf, pg);
fclose(pf);
fclose(pg);
return 0;
}