#include <cstdio>
#include <algorithm>
#include <deque>
using namespace std;
struct tree
{
tree *st, *dr;
int val;
tree(int v = 0)
{
st = NULL;
dr = NULL;
val = v;
}
};
tree *root;
int n,m;
void constr(deque< tree *> init)
{
deque< tree *> final;
tree * aux, *first, *sec;
if(init.front() == init.back())
{
root = init.front();
return;
}
while(!init.empty())
{
first = init.front();
init.pop_front();
if(init.empty())
aux = first;
else
{
sec = init.front();
init.pop_front();
aux = new tree;
aux -> val = first-> val + sec-> val;
aux -> st = first;
aux -> dr = sec;
}
final.push_back(aux);
}
constr(final);
}
void citire()
{
deque< tree *> sir;
int i, cit;
tree *aux;
scanf("%d%d\n",&n, &m);
for(i=0; i<n; i++)
{
scanf("%d",&cit);
aux = new tree;
*aux = cit;
sir.push_back(aux);
}
constr(sir);
}
void debug( tree * t)
{
if(t == NULL)
return;
printf("(%d",t->val);
debug(t->st);
printf("");
debug(t->dr);
printf(")");
}
void add(int val, int poz, tree *t, int x, int y)
{
if(poz<x || poz>y || t==NULL)
return;
t->val += val;
if(x==y)
return;
add(val, poz, t->st, x, x+(y-x)/2);
add(val, poz, t->dr, x+(y-x)/2+1, y);
}
int sum(int a, int b, tree *t, int x, int y)
{
if(t == NULL)
return 0;
if(a<=x && b>=y)
return t->val;
if(y<a || x>b)
return 0;
return sum(a, b, t->st, x, x+(y-x)/2)
+ sum(a, b,t->dr, x+(y-x)/2+1, y);
}
int doi(int a, tree *t, int x, int y)
{
if(t->val<=a)
return y;
if(t->st == NULL)
return x-1;
if(t->st->val < a)
return doi(a - t->st->val, t->st, x+(y-x)/2+1, y);
return doi(a, t->st, x, x+(y-x)/2);
}
int main()
{
freopen("aib.in","r",stdin);
freopen("aib.out","w",stdout);
citire();
int command, a, b;
for(int i=0; i < m; i++)
{
scanf("%d",&command);
switch(command)
{
case 0:
scanf("%d%d",&a,&b);
add(b,a-1,root,0,n-1);
break;
case 1:
scanf("%d%d",&a,&b);
printf("%d\n",sum(a-1, b-1, root, 0, n-1));
break;
case 2:
scanf("%d",&a);
printf("%d\n",doi(a, root, 0, n-1)+1);
}
}
return 0;
}