/*#include <bits/stdc++.h>
#define dim 100001
using namespace std ;
ifstream fin("aib.in") ;
ofstream fout("aib.out") ;
long long g[dim] , tree[4 * dim] , n ;
int q ;
int op ;
void build(int v , int tl , int tr){
if(tl == tr) tree[v] = g[tl] ;
else{
int tm = (tl + tr) / 2 ;
build(2 * v , tl , tm) ;
build(2 * v + 1 , tm + 1 , tr) ;
tree[v] = tree[2 * v] + tree[2 * v + 1] ;
}
}
void update(int v , int tl , int tr , int poz , int val){
if(tl == tr) tree[v] += val ;
else{
int tm = (tl + tr) / 2 ;
if(poz <= tm) update(2 * v , tl ,tm , poz , val) ;
else update(2 * v + 1 , tm + 1 , tr , poz , val) ;
tree[v] = tree[2 * v] + tree[2 * v + 1] ;
}
}
long long query(int v , int tl , int tr , int st , int dr){
if(tl > dr || tr < st) return 0 ;
if(tl >= st && tr <= dr) return tree[v] ;
int tm = (tl + tr) / 2 ;
return query(2 * v , tl , tm , st , dr) + query(2 * v + 1 , tm + 1 , tr , st , dr) ;
}
long long binary(int v , int tl , int tr , long long a){
if(tl == tr){
if(tree[v] == a) return tl ;
return -1 ;
}
int tm = (tl + tr) / 2 ;
if(tree[2 * v] >= a) return binary(2 * v , tl , tm , a) ;
else return binary(2 * v + 1 , tm + 1 , tr , a - tree[2 * v]) ;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0) ;
fin >> n >> q ;
for(int i = 1 ; i <= n ; ++i) fin >> g[i] ;
build(1 , 1 , n) ;
while(q--){
fin >> op ;
if(op == 0){
int poz , val ;
fin >> poz >> val ;
update(1 , 1 , n , poz , val) ;
}
else if(op == 1){
int a , b ;
fin >> a >> b ;
fout << query(1 , 1 , n , a , b) << '\n' ;
}
else{
///op = 2 :
long long a ;
fin >> a ;
if(tree[1] < a) fout << -1 << '\n' ;
else fout << binary(1 , 1 , n , a) << '\n' ;
}
}
return 0 ;
}
*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100000 + 5;
long long g[MAXN], tree[4 * MAXN];
int n, m;
void build(int v, int tl, int tr){
if(tl == tr) tree[v] = g[tl];
else{
int tm = (tl + tr) >> 1;
build(v<<1, tl, tm);
build(v<<1|1, tm+1, tr);
tree[v] = tree[v<<1] + tree[v<<1|1];
}
}
void update(int v, int tl, int tr, int pos, int val){
if(tl == tr) tree[v] += val;
else{
int tm = (tl + tr) >> 1;
if(pos <= tm) update(v<<1, tl, tm, pos, val);
else update(v<<1|1, tm+1, tr, pos, val);
tree[v] = tree[v<<1] + tree[v<<1|1];
}
}
long long query(int v, int tl, int tr, int l, int r){
if(l > r || tl > r || tr < l) return 0;
if(tl >= l && tr <= r) return tree[v];
int tm = (tl + tr) >> 1;
return query(v<<1, tl, tm, l, r) + query(v<<1|1, tm+1, tr, l, r);
}
int find_prefix_exact(int v, int tl, int tr, long long a){
if(a == 0) return 0;
if(tl == tr){
if(tree[v] == a) return tl;
return -1;
}
int tm = (tl + tr) >> 1;
if(tree[v<<1] >= a) return find_prefix_exact(v<<1, tl, tm, a);
else return find_prefix_exact(v<<1|1, tm+1, tr, a - tree[v<<1]);
}
int main(){
if(scanf("%d %d", &n, &m)!=2) return 0;
for(int i = 1; i <= n; ++i) scanf("%lld", &g[i]);
build(1, 1, n);
while(m--){
int op;
scanf("%d", &op);
if(op == 0){
int a, b; scanf("%d %d", &a, &b);
update(1, 1, n, a, b);
} else if(op == 1){
int a, b; scanf("%d %d", &a, &b);
printf("%lld\n", query(1, 1, n, a, b));
} else if(op == 2){
long long a; scanf("%lld", &a);
if(a == 0){ printf("0\n"); continue; }
if(tree[1] < a){ printf("-1\n"); continue; }
int res = find_prefix_exact(1, 1, n, a);
printf("%d\n", res);
}
}
return 0;
}