#include <fstream>
#define tata(x) (x)/2
#define fst(x) (x)<<1
#define fdr(x) ((x)<<1)+1
using namespace std;
ifstream f("arbint.in");
ofstream g("arbint.out");
int arbint[400001],a[100001],n,m;
int maxim(int a, int b) {
if(a > b)
return a;
return b;
}
void update(int poz,int st, int dr, int vpoz, int val) {
if(st == dr) {
arbint[poz] = val;
return;
}
int mijl = (st + dr) / 2;
if(vpoz > mijl) {
update(fdr(poz),mijl+1,dr,vpoz,val);
}
else {
update(fst(poz),st,mijl,vpoz,val);
}
arbint[poz] = maxim(arbint[fst(poz)],arbint[fdr(poz)]);
}
int query(int poz, int st, int dr, int a , int b) {
if(st >= a && dr <= b) {
return arbint[poz];
}
int mijl = (st + dr) / 2;
int suma = 0;
if(b > mijl)
suma = maxim(suma,query(fdr(poz),mijl+1,dr,a,b));
if(a <= mijl)
suma = maxim(suma,query(fst(poz),st,mijl,a,b));
return suma;
}
void create(int poz, int st, int dr) {
if(st == dr) {
arbint[poz] = a[st];
return;
}
int mijl = (st + dr) / 2;
create(fst(poz),st,mijl);
create(fdr(poz),mijl+1,dr);
arbint[poz] = maxim(arbint[fst(poz)],arbint[fdr(poz)]);
}
void citire() {
f >> n >> m;
for(int i = 1; i <= n; i++) {
f >> a[i];
}
create(1,1,n);
for(int i = 0; i < m; i++) {
int op,val1,val2;
f >> op >> val1 >> val2;
if(op == 0)
g << query(1,1,n,val1,val2) << "\n";
else
update(1,1,n,val1,val2);
}
}
int main() {
citire();
}