#include <iostream>
#include <stdio.h>
#include <fstream>
#include <assert.h>
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
const int MAX_SIZE = 100000;
int tree[3 * MAX_SIZE], sum;
int ok;
long long curSum, aSum;
void update(int curNode, int left, int right, int val, int pos) {
if (left == right) {
tree[curNode] += val;
return;
}
int mid = (left + right) / 2;
if (pos <= mid) {
update(2 * curNode, left, mid, val, pos);
} else {
update(2 * curNode + 1, mid + 1, right, val, pos);
}
tree[curNode] = tree[2 * curNode] + tree[2 * curNode + 1];
}
void query(int curNode, int left, int right, int start, int end) {
if (start <= left && right <= end) {
sum += tree[curNode];
return;
}
int mid = (left + right) / 2;
if (start <= mid) {
query(2 * curNode, left, mid, start, end);
}
if (end > mid) {
query(2 * curNode + 1, mid + 1, right, start, end);
}
}
void task2(int curNode, int left, int right, int curSum) {
if (curSum == aSum || left == right) {
if (curSum == aSum) {
fout << right << "\n";
ok = 1;
}
return;
}
int mid = (left + right) / 2;
if (curSum > aSum) {
curSum -= tree[2 * curNode + 1];
task2(2 * curNode, left, mid, curSum);
} else if (curSum < aSum) {
curSum += tree[curNode + 1];
task2(curNode + 1, mid + 1, right, curSum);
}
}
int main() {
std::ios::sync_with_stdio(false);
int n, tasks;
fin >> n >> tasks;
for (int pos = 1; pos <= n; ++pos) {
int val;
fin >> val;
update(1, 1, n, val, pos);
}
for (int i = 1; i <= tasks; ++i) {
int task;
fin >> task;
if (task == 0) {
int pos, val;
fin >> pos >> val;
update(1, 1, n, val, pos);
} else if (task == 1) {
int start, end;
fin >> start >> end;
sum = 0;
query(1, 1, n, start, end);
fout << sum << "\n";
} else {
ok = 0;
fin >> aSum;
task2(1, 1, n, tree[1]);
if (!ok) {
fout << -1 << "\n";
}
}
}
}
/*
8 6
25 42 8 15 1 55 16 67
2 2
*/