/**
* Interval Tree
*/
#include <stdio.h>
#define MAX 100005
#define MINUS -999
#define FIN "arbint.in"
#define FOUT "arbint.out"
int tree[ 3 * MAX ];
FILE *fin,
*fout;
int num_of_elem,
num_of_op,
elem;
//function prototypes
void readAndSolve();
int max(int, int);
void update(int, int, int, int, int);
int query(int, int, int, int, int);
int main() {
readAndSolve();
return(0);
};
void readAndSolve() {
int i, op, a, b;
fin = fopen(FIN, "r");
fout = fopen(FOUT, "w");
fscanf(fin, "%d %d", &num_of_elem, &num_of_op);
for(i = 1; i <= num_of_elem; i++) {
fscanf(fin, "%d", &elem);
update(1, 1, num_of_elem, i, elem) ;
}
while( num_of_op-- ) {
fscanf(fin, "%d %d %d", &op, &a, &b);
if(op == 0) {
fprintf(fout, "%d\n", query(1, 1, num_of_elem, a, b));
} else if(op == 1) {
update(1, 1, num_of_elem, a, b);
}
}
fclose( fin );
fclose( fout );
};
int max(int x, int y) {
if(x > y) return x;
else
return y;
};
void update(int node, int li, int ls, int pos, int val) {
int middle;
if(li == ls && ls == pos) {
tree[ node ] = val;
} else {
middle = (li+ls) >> 1;
if(pos <= middle) update(2*node, li, middle, pos, val);
else
update(2*node+1, middle+1, ls, pos, val);
tree[ node ] = max(tree[ 2 * node], tree[ 2 * node + 1 ]);
}
};
int query(int node, int li, int ls, int a, int b) {
int x,
y, middle;
if(a<=li && b>=ls) {
return tree[ node ];
} else {
x = MINUS;
y = MINUS;
middle = (li+ls)>>1;
if(a <= middle) x = query(2*node, li, middle, a, b);
if(b > middle) y = query(2*node+1, middle + 1, ls, a, b);
return max(x, y);
}
};