#include <fstream>
#include <queue>
using namespace std;
int* ReadList(int n, istream &fin);
int* CreateBit(int n, int* list);
int* ReadList(int n, istream &fin);
int* CreateBit(int n, int* list);
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* list = ReadList(n, fin);
int* tree = CreateBit(n, list);
ApplyQuerys(n, m, tree, fin, fout);
fin.close();
fout.close();
return 0;
}
int* ReadList(int n, istream &fin)
{
int *list = new int[n + 1]();
for(int i = 1; i <= n; i++)
{
fin >> list[i];
}
return list;
}
int* CreateBit(int n, int* list)
{
int *tree = new int[n + 1]();
for(int i = 1; i <= n; i++)
{
int r = 0;
while(((1 << r) & i) == 0)
{
r ++;
}
for(int j = i - (1 << r) + 1; j <= i; j++)
{
tree[i] += list[j];
}
}
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;
fout << DetPos(n, a, tree) << '\n';
break;
default:
exit(1);
}
}
}
void ChangeElem(int n, int a, int b, int *tree)
{
while(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])
{
idx = tmp;
a -= tree[tmp];
}
bitMask >>= 1;
}
if(a != 0)
{
return -1;
}
return idx;
}