#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 ans=0;
aint(vector<int>& v, int n)
:arbore(2*NMAX+5)
{
build(v, 1, 1, n);
}
void build(vector<int> &v, int node, int left, int right){
if(left==right){
arbore[node]=v[left];
return;
}
int mid=(left+right)/2;
build(v, node+1, left, mid);
build(v, node+2*(mid-left+1), mid+1, right);
arbore[node]=max(arbore[node+1], arbore[node+2*(mid-left+1)]);
}
void update(vector<int>& v, int node, int left, int right, int pos, int value){
if(left==right){
arbore[node]=value;
return;
}
int mid=(left+right)/2;
if(pos<=mid){
update(v, node+1, left, mid, pos, value);
}else{
update(v, node+2*(mid-left+1), mid+1, right, pos, value);
}
arbore[node]=max(arbore[node+1], arbore[node+2*(mid-left+1)]);
}
void query(vector<int>& v, int node, int left, int right, int ansleft, int ansright){
if(left>=ansleft and right<=ansright){
ans=max(arbore[node], ans);
return;
}
int mid=(left+right)/2;
if(mid>=ansleft){
query(v, node+1, left, mid, ansleft, ansright);
}
if(mid<ansright){
query(v, node+2*(mid-left+1), mid+1, right, ansleft, ansright);
}
}
};
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.ans=0;
ans.query(v, 1, 1, n, x, y);
fout<<ans.ans<<'\n';
}else{
ans.update(v, 1, 1, n, x, y);
}
}
}