#include <iostream>
#include <fstream>
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int const n_max = 100000;
int tree[n_max + 5];
int val[n_max + 5];
void build(int nod, int st, int dr){
if(st == dr){
tree[nod] = val[st];
return;
}
int mij = (st + dr) / 2;
build(2 * nod, st, mij);
build(2 * nod + 1, mij + 1, dr);
tree[nod] = max(tree[2 * nod], tree[2 * nod + 1]);
}
void update(int nod, int st, int dr, int poz, int val){
if(st == dr){
tree[nod] = val;
return;
}
int mij = (st + dr) / 2;
if(poz <= mij){
update(nod * 2, st, mij, poz, val);
}
else{
update(nod * 2 + 1, mij + 1, dr, poz, val);
}
tree[nod] = max(tree[nod * 2], tree[nod * 2 + 1]);
}
int mmax(int nod, int st, int dr, int int1, int int2){
if(int1 <= st && dr <= int2){
return tree[nod];
}
int mij = (st + dr) / 2;
if(int1 <= mij){
return mmax(nod * 2, st, mij, int1, int2);
}
if(int2 > mij){
return mmax(nod * 2 + 1, mij + 1, dr, int1, int2);
}
return 0;
}
// void afisare_tree(int n){
// for(int i = 1; i < 4 * n; i ++){
// fout << i << " ";
// }
// fout << endl;
// for(int i = 1; i < 4 * n; i ++){
// fout << tree[i] << " ";
// }
// fout << endl;
// }
int main(){
int n, m;
int a, b, cond;
fin >> n >> m;
for(int i = 1; i <= n; i ++){
fin >> a;
val[i] = a;
}
build(1, 1, n);
//afisare_tree(n);
for(int i = 0; i < m; i++){
fin >> cond >> a >> b;
if(cond){
update(1, 1, n, a, b);
} else {
fout << mmax(1, 1, n, a, b) << endl;
}
//afisare_tree(n);
}
fin.close();
fout.close();
return 0;
}