#include <iostream>
#include <stdio.h>
#include <cmath>
using namespace std;
const int N = 1e6 + 2;
int v[N];
int arb[4*N + 3];
int max(int x, int y){
return (x > y)? x : y;
}
void generate_tree(int l, int r, int d){
if (l == r){
arb[d] = v[l];
return ;
}
generate_tree(l, (l+r)/2, 2*d);
generate_tree((l+r)/2+1, r, 2*d+1);
arb[d] = max(arb[2*d], arb[2*d+1]);
}
void update(int pos, int vnew, int l, int r, int node){
if (l == r){
arb[node] = vnew;
return;
}
int mij = (l+r)/2;
if (pos <= mij)
update(pos, vnew, l, mij, 2*node);
else
update (pos, vnew, mij+1, r, 2*node+1);
arb[node] = max(arb[2*node], arb[2*node+1]);
}
int max_search(int node, int l, int r, int a, int b){
if (a<=l && b>=r)
return arb[node];
int mij =(l+r)/2;
int ans = 0;
if (a <= mij)
ans = max_search(2*node, l, mij, a, b);
if (b > mij)
ans = max(ans, max_search(2*node+1, mij+1, r, a, b));
return ans;
}
int main()
{
freopen("arbint.in", "r", stdin);
freopen("arbint.out", "w", stdout);
int n, m;
scanf("%d %d", &n, &m);
for (int i=1; i<=n; i++)
scanf("%d", &v[i]);
generate_tree(1, n, 1);
for (int i=0; i<m; i++){
int a, b, c;
scanf("%d %d %d", &c, &a, &b);
if (c == 0)
printf("%d\n", max_search(1, 1, n, a, b));
else update(a, b, 1, n, 1);
}
}