#include <bits/stdc++.h>
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
const int NMAX=100000;
struct aint{
vector<int> arbore;
int marime, answer=0;
aint(vector<int>& v, int n)
:arbore(NMAX+5)
{
marime=n;
build(v);
}
void build(vector<int>& v, int node=1, int left=1, int right=-1){
if(right==-1){
right=marime;
}
if(left==right){
arbore[node]=v[left];
return;
}
int mid=(left+right)/2;
build(v, 2*node, left, mid);
build(v, 2*node+1, mid+1, right);
arbore[node]=max(arbore[2*node], arbore[2*node+1]);
}
void update(vector<int>& v, int pozitie, int valoare, int node=1, int left=1, int right=-1){
if(right==-1){
right=marime;
}
if(left==right){
arbore[node]=valoare;
return;
}
int mid=(left+right)/2;
if(pozitie<=mid){
update(v, pozitie, valoare, 2*node, left, mid);
}else{
update(v, pozitie, valoare, 2*node+1, mid+1, right);
}
arbore[node]=max(arbore[2*node], arbore[2*node+1]);
}
void query(vector<int>& v, int start, int finish, int node=1, int left=1, int right=-1){
if(right==-1){
right=marime;
}
if(left>=start and right<=finish){
answer=max(answer, arbore[node]);
return;
}
int mid=(left+right)/2;
if(mid>=start){
query(v, start, finish, 2*node, left, mid);
}
if(mid<finish){
query(v, start, finish, 2*node+1, mid+1, right);
}
}
};
int main(){
int n, q;
fin>>n>>q;
vector<int> v(n+1);
for(int i=1;i<=n;i++){
fin>>v[i];
}
aint ans(v, n);
for(int i=1;i<=q;i++){
int tip, x, y;
fin>>tip>>x>>y;
if(tip==0){
ans.answer=0;
ans.query(v, x, y);
fout<<ans.answer<<'\n';
}else{
ans.update(v, x, y);
}
}
}