#include <iostream>
#include <fstream>
#include <string.h>
#include <algorithm>
#include <vector>
#include <assert.h>
using namespace std;
#define NMAX 100001
struct entry {
int val,viz,upd;
};
class segmentTree {
entry *arb;
int n, val;
public:
segmentTree() {
arb = NULL;
n=0;
}
segmentTree(int _n) {
int i;
arb = new entry[4*_n+1];
for(i=0;i<=4*_n;i++) {
arb[i].val=0;
arb[i].viz=0;
arb[i].upd=0;
}
n=_n;
}
void Update(int _a, int _b, int _val) {
update(1,1,n,_a,_b,_val);
}
int Query(int _a, int _b) {
val = 0;
query(1,1,n,_a,_b);
return val;
}
~segmentTree() {
free(arb);
}
private:
void update(int nod, int st, int dr, int a, int b, int val)
{
int mij;
if(a<=st && dr<=b) {
arb[nod].val = arb[nod].val + val;
arb[nod].viz = 1;
arb[nod].upd = arb[nod].upd + val;
return ;
}
mij = (st+dr)/2;
if(arb[nod].viz==1) {
lazyUpdate(nod*2,arb[nod].upd);
lazyUpdate(nod*2+1,arb[nod].upd);
arb[nod].viz=0;
arb[nod].upd=0;
}
if(a<=mij)
update(nod*2,st,mij,a,b,val);
if(mij<b)
update(nod*2+1,mij+1,dr,a,b,val);
arb[nod].val = max(arb[nod*2].val, arb[nod*2+1].val);
}
void lazyUpdate(int nod, int _upd)
{
// assert(nod<=4*n);
arb[nod].val = arb[nod].val + _upd;
arb[nod].viz = 1;
arb[nod].upd = arb[nod].upd + _upd;
}
void query(int nod, int st, int dr, int a, int b)
{
int mij;
if(a<=st && dr<=b) {
val = max(val, arb[nod].val);
return ;
}
mij=(st+dr)/2;
if(arb[nod].viz==1) {
lazyUpdate(nod*2,arb[nod].upd);
lazyUpdate(nod*2+1,arb[nod].upd);
arb[nod].viz=0;
arb[nod].upd=0;
}
if(a<=mij)
query(nod*2,st,mij,a,b);
if(mij<b)
query(nod*2+1,mij+1,dr,a,b);
}
};
int main ()
{
int n,m,i,x,op,y,aux;
ifstream f("arbint.in");
ofstream g("arbint.out");
f>>n>>m;
segmentTree a(n);
for(i=1;i<=n;i++) {
f>>x;
a.Update(i,i,x);
}
for(i=1;i<=m;i++) {
f>>op>>x>>y;
if(op==0)
g<<a.Query(x,y)<<'\n';
else {
aux = a.Query(x,x);
a.Update(x,x,y-aux);
}
}
f.close();
g.close();
return 0;
}