#include <bits/stdc++.h>
using namespace std;
ifstream fin("aib.in");
ofstream fout("aib.out");
class Arbore
{
protected:
int *aint;
int n;
public:
virtual int InitInt() {return 0;}
virtual int Merge(int a, int b){return a + b;}
void Init(int n)
{
this->n = n;
aint = new int[4 * n + 1];
for (int i = 0; i <= 4 * n; i++)
aint[i] = InitInt();
}
void Build(int a[], int nod, int l, int r)
{
if (l == r)
{
aint[nod] = a[l];
return;
}
int mid = (l + r) / 2;
Build(a, 2 * nod, l, mid);
Build(a, 2 * nod + 1, mid + 1, r);
aint[nod] = Merge(aint[2 * nod], aint[2 * nod + 1]);
}
void Update(int nod, int l, int r, int p, int x)
{
if (r < p || l > p) return;
if (l == r)
{
aint[nod] = x;
return;
}
int mid = (l + r) / 2;
Update(2 * nod, l, mid, p, x);
Update(2 * nod + 1, mid + 1, r, p, x);
aint[nod] = Merge(aint[2 * nod], aint[2 * nod + 1]);
}
Arbore(int n){Init(n);}
Arbore(int a[], int n){Init(n); Build(a, 1, 1, n);}
int Query(int nod, int start, int end, int l, int r)
{
if (r < start || l > end) return InitInt();
if (start <= l && r <= end) return aint[nod];
int mid = (l + r) / 2;
int p1 = Query(2 * nod, start, end, l, mid);
int p2 = Query(2 * nod + 1, start, end, mid + 1, r);
return Merge(p1, p2);
}
int PozMin(int x)
{
int l, r, q, mid, ind;
l = 1; r = n; ind = -1;
while (l <= r)
{
mid = (l + r) / 2;
q = Query(1, 1, mid, 1, n);
if (q >= x)
{
if (q == x) ind = mid;
r = mid - 1;
}
else
l = mid + 1;
}
return ind;
}
};
int a[100005], n;
int main()
{
int i, x, y, op, q;
fin >> n >> q;
for (i = 1; i <= n; i++)
fin >> a[i];
Arbore aint(a, n);
while (q--)
{
fin >> op >> x;
if (op == 0)
{
fin >> y;
aint.Update(1, 1, n, x, a[x] + y);
a[x] += y;
}
else if (op == 1)
{
fin >> y;
fout << aint.Query(1, x, y, 1, n) << "\n";
}
else
fout << aint.PozMin(x) << "\n";
}
return 0;
}