#include <fstream>
#define DIM 400010
using namespace std;
int A[DIM], N, M, i, X, a, b, t;
ifstream f("arbint.in");
ofstream g("arbint.out");
int query(int nod, int st, int dr, int a, int b) {//maximul din intervalul [a,b] reprezentat de nodul nod
if (a<=st && b>=dr) {
return A[nod];
}
int maxSt = 0;
int maxDr = 0;
int m = ((st+dr)>>1);
if (a<=m) {
maxSt = query(nod<<1, st, m, a, b);
}
if (b>=m+1) {
maxDr = query((nod<<1)+1, m+1, dr, a, b);
}
return maxSt > maxDr ? maxSt : maxDr;
}
void update(int nod, int st, int dr, int poz, int val) {
// if (poz < st || poz > dr) {
//poz nu e in intervalul st, dr, nu conteaza, dar asta ar putea fi testat doar o data, inainte de apelul functiei
// return;
// }
if (st == poz && dr == poz) {
A[nod] = val;
return;
}
int m = ((st+dr)>>1);
if (poz <= m)
update(nod<<1, st, m, poz, val);
if (poz >= m+1)
update((nod<<1)+1, m+1, dr, poz, val);
A[nod] = A[nod<<1] > A[(nod<<1)+1] ? A[nod<<1] : A[(nod<<1)+1];
}
int main() {
f>>N>>M;
for (i=1;i<=N;i++) {
f>>X;
update(1,1,N,i,X);
}
for (i=1;i<=M;i++) {
f>>t>>a>>b;
if (t == 0) {
g<<query(1,1,N,a,b)<<"\n";
} else {
update(1,1,N,a,b);
}
}
}