#include <iostream>
#include <vector>
#include <fstream>
#include <cmath>
using namespace std;
void creare_arbore(int arb_int[], vector<int> &v, int st_interval, int dr_interval, int poz_arbore){
if(st_interval == dr_interval)
arb_int[poz_arbore] = v[st_interval];
else{
int mij = (st_interval + dr_interval)/2;
creare_arbore( arb_int, v, st_interval, mij, 2*poz_arbore);
creare_arbore( arb_int, v, mij+1, dr_interval, 2*poz_arbore+1);
arb_int[poz_arbore] = max(arb_int[poz_arbore*2], arb_int[poz_arbore*2+1]);
}
}
void maximul_a_b(int* arboric, vector<int> &v, int a, int b, int poz, int stanga_curent, int dreapta_curent, int& maxim){
if (a <= stanga_curent && b >= dreapta_curent){
maxim= max(maxim, arboric[poz]);
}
else{
int mij=(stanga_curent+dreapta_curent)/2;
if (mij >= a)
maximul_a_b(arboric, v, a, b, poz * 2, stanga_curent, mij, maxim);
if (mij < b)
maximul_a_b(arboric, v, a, b, poz * 2 + 1, mij + 1, dreapta_curent, maxim);
}
}
void schimbare_element(int* arboric, vector<int> &v, int stanga, int dreapta, int poz_curent, int a, int b){
if (stanga == dreapta){
arboric[poz_curent]= b;
}
else{
int mij=(stanga+dreapta)/2;
if (mij >= a){
schimbare_element(arboric, v, stanga, mij,poz_curent*2, a, b);
arboric[poz_curent]=max(arboric[poz_curent*2],arboric[poz_curent*2+1]);
}
else{
schimbare_element(arboric, v,mij+1, dreapta,poz_curent*2+1, a, b);
arboric[poz_curent]=max(arboric[poz_curent*2],arboric[poz_curent*2+1]);
}
}
}
int main() {
ifstream f("arbint.in");
int n,m,aux;
f>>n>>m;
vector<int> numere;
for(int i=0; i<n;i++) {
f >> aux;
numere.push_back(aux);
}
int arbore[1<<(int)(log2(n)+2)];
arbore[0]=-1;
creare_arbore( arbore, numere, 0, n-1 , 1);
for(int a=0; a<1<<(int)(log2(n)+2);a++)
cout<<arbore[a]<<' ';
cout<<'\n';
ofstream g("arbint.out");
int comanda, a,b;
for(int i=0;i<m;i++){
f>>comanda>>a>>b;
if (comanda==0){
a--;
b--;
int maxim = 0;
maximul_a_b(arbore, numere, a, b,1, 0 , n-1, maxim);
g<<maxim<<'\n';
}
else{
a--;
schimbare_element(arbore, numere,0, n-1, 1, a, b);
}
}
f.close();
g.close();
return 0;
}