/* arbori indexati binari
la arbori indexati binari se cauta ultimul numar cu un singur nr de biti de 1 si se aduna tot pana acolo.
i & -i - important pentru izolarea ultimului bit
i= 10110100
-i=01001100
i& -i = 00000100
1010 = 10 => 1100 = 12
i+=(i & -i) 10110100 -> 10111000 -> 1100000... se muta unu pe primul zero
i-=(i & -i) eliminam un 1 pe ultima pozitie
i-=(i&-i) = > query
i-> i+=(i&-i) => update parcurgi arborele
3-> 0011
4-> 0100
8-> 1000
suma primelor 13 -> suma [13,13]
1101=13
query
1100=12 ->suma [9,12];
query
1000=8 ->suma[1,8];
*/
#include <fstream>
#include <iostream>
#include <utility>
#include <stdlib.h>
#include <climits>
#define Inf 0x3f3f3f3f
using namespace std;
int n,m,x,y;
int hawktuah[400001];
int res,p ;
std::ifstream fin ("date.in");
std::ofstream fout ("date.out");
void create(int pos, int st, int dr)
{
if(st==dr)
{
fin >> hawktuah[pos];
return;
}
int mij=(st+dr)/2;
create(2*pos,st,mij);
create(2*pos+1,mij+1,dr);
hawktuah[pos]=(hawktuah[2*pos]+hawktuah[2*pos+1]);
}
void update(int pos,int st, int dr)
{
if(p < st || p > dr)
{
return;
}
if(st==dr)
{
hawktuah[pos]+=x;
return;
}
int mij=(st+dr)/2;
if(x<=mij)
update(2*pos,st,mij);
else
update(2*pos+1,mij+1,dr);
hawktuah[pos]=(hawktuah[2*pos]+hawktuah[2*pos+1]);
}
void query(int pos, int st, int dr) {
if( dr < x || st > y)
return;
if(x<=st && dr<=y)
{
res+=hawktuah[pos];
return;
}
int mij=(st+dr)/2;
query(2*pos,st,mij);
query(2*pos+1,mij+1,dr);
}
int main()
{
fin >> n >> m;
create(1,1,n);
for(int i=1;i<=m;i++)
{
int opps;
fin >> opps;
if(opps==0)
{
fin >> p >> x;
update(1,1,n);
}
else if(opps==1)
{
fin >> x >> y;
res=0;
query(1,1,n);
fout<<res << '\n';
}
else
{
int k;
fin >>k;
int st=1,dr=n;
while(st!=dr){
int mij=(st+dr)/2;
x=1,y=mij,res=0;
query(1,1,n);
if(res>=k)
dr=mij;
else
st=mij+1;
}
x=1,y=st,res=0;
query(1,1,n);
if(res==k)
fout << st<< "\n";
else
fout<<-1<<'\n';
}
}
return 0;
}