#include <fstream>
#include <queue>
using namespace std;
int* CreateBit(int n, istream &fin);
void ApplyQuerys(int n, int m, int* tree, istream &fin, ostream &fout);
void ChangeElem(int n, int a, int b, int *tree);
int SumElem(int a, int b, int *tree);
int GetSum(int a, int* tree);
int DetPos(int n, int a, int *tree);
int main()
{
ifstream fin;
ofstream fout;
fout.open("aib.out");
fin.open("aib.in");
int n, m;
fin >> n >> m;
int* tree = CreateBit(n, fin);
ApplyQuerys(n, m, tree, fin, fout);
fin.close();
fout.close();
return 0;
}
int* CreateBit(int n, istream &fin)
{
int *tree = new int[n + 1]();
int x;
for(int i = 1; i <= n; i++)
{
fin >> x;
int r = 0;
while(((1 << r) & i) == 0)
{
r ++;
}
tree[i] = SumElem(i - (1 << r) + 1, i - 1, tree) + x;
}
return tree;
}
void ApplyQuerys(int n, int m, int* tree, istream &fin, ostream &fout)
{
int opt, a, b;
for(int i = 1; i <= m; i++)
{
fin >> opt;
switch(opt)
{
case 0:
fin >> a >> b;
ChangeElem(n, a, b, tree);
break;
case 1:
fin >> a >> b;
fout << SumElem(a, b, tree) << '\n';
break;
case 2:
fin >> a;
if(a == 0)
fout << "-1\n";
else
fout << DetPos(n, a, tree) << '\n';
break;
default:
exit(1);
}
}
}
void ChangeElem(int n, int a, int b, int *tree)
{
while(a > 0 && a <= n)
{
tree[a] += b;
a += (a & (-1)*a);
}
}
int SumElem(int a, int b, int *tree)
{
return GetSum(b, tree) - GetSum(a - 1, tree);
}
int GetSum(int a, int* tree)
{
int sum = 0;
while(a > 0)
{
sum += tree[a];
a -= (a & (-1)*a);
}
return sum;
}
int DetPos(int n, int a, int *tree)
{
int r = 0;
while((1 << r) <= n)
{
r++;
}
r--;
int idx = 0;
int bitMask = (1 << r);
while((bitMask != 0) && (idx < n))
{
int tmp = idx + bitMask;
if(a == tree[tmp])
{
return tmp;
}
else if(a > tree[tmp] && tmp < n)
{
idx = tmp;
a -= tree[tmp];
}
bitMask >>= 1;
}
if(a != 0)
{
return -1;
}
return idx;
}