#include <stdio.h>
#define print fprintf
#define NMAX 400001
unsigned int AINT[NMAX]; // valoarea maxima pe intervale
int max(int a, int b){
return (a > b ? a : b);
}
void update(int val, int poz, int node, int l, int r){
if(l == r){
AINT[node] = val;
return;
}
const int mid = (l + r) / 2;
if(poz <= mid)
update(val, poz, 2 * node, l, mid);
else update(val, poz, 2 * node + 1, mid + 1, r);
AINT[node] = max(AINT[2 * node], AINT[2 * node + 1]);
}
int querry(int a, int b, int node, int l, int r){
if(l == r || (l == a && r == b))
return AINT[node];
const int mid = (l + r) / 2;
if(a <= mid && b <= mid)
return querry(a, b, 2 * node, l, mid);
else if(a > mid && b > mid)
return querry(a, b, 2 * node + 1, mid + 1, r);
return max(querry(a, mid, 2 * node, l, mid), querry(mid + 1, b, 2 * node + 1, mid + 1, r));
}
int main(){
FILE *in, *out;
in = fopen("arbint.in", "r");
out = fopen("arbint.out", "w");
int n, m;
fscanf(in, "%d", &n);
fscanf(in, "%d", &m);
for(int i=1; i<=n; i++){
unsigned int x;
fscanf(in, "%d", &x);
update(x, i, 1, 1, n);
}
while(m--){
int op, a, b;
fscanf(in, "%d", &op);
fscanf(in, "%d", &a);
fscanf(in, "%d", &b);
switch (op){
case 0:
print(out, "%d\n", querry(a, b, 1, 1, n));
break;
case 1:
update(b, a, 1, 1, n);
}
}
return 0;
}