#include <iostream>
#include <fstream>
#include <vector>
#include <climits>
#include <algorithm>
#define INFILE "arbint.in"
#define OUTFILE "arbint.out"
using namespace std;
ifstream in(INFILE);
ofstream out(OUTFILE);
class SegmentTree{
public:
SegmentTree(vector<int> input){
int p=1;
sz=input.size();
while(p<sz)
p*=2;
sgmt.resize(2*p-1);
for(int i=0;i<sz;i++)
Actualizare(i,input[i]);
}
void Actualizare(int posInp,int newVal){
ActualizareRec(posInp,newVal,0,sz-1,0);
}
int FindMin(int ilow,int ihigh){
return FindMinRec(ilow,ihigh,0,sz-1,0);
}
private:
vector<int> sgmt;
int sz=0;
void Generare(vector<int> input,int low,int high,int pos){
if(low==high){
sgmt[pos]=input[low];
return;
}
int mid=(low+high)/2;
Generare(input,low,mid,2*pos+1);
Generare(input,mid+1,high,2*pos+2);
sgmt[pos]=max(sgmt[2*pos+1],sgmt[2*pos+2]);
}
void ActualizareRec(int posInp,int newVal,int low,int high,int pos){
if(low==high){
if(posInp==low)
sgmt[pos]=newVal;
return;
}
int mid=(low+high)/2;
if(posInp<=mid){
ActualizareRec(posInp,newVal,low,mid,2*pos+1);
}
else{
ActualizareRec(posInp,newVal,mid+1,high,2*pos+2);
}
sgmt[pos]=max(sgmt[2*pos+1],sgmt[2*pos+2]);
}
int FindMinRec(int ilow,int ihigh,int low,int high,int pos){
if(ilow<=low&&high<=ihigh){//overlap
return sgmt[pos];
}
if(ihigh<low||ilow>high){
return INT_MIN;
}
int mid=(low+high)/2;
int v1=INT_MIN;
int v2=INT_MIN;
if(mid>=ilow)
v1=FindMinRec(ilow,ihigh,low,mid,2*pos+1);
if(mid+1<=ihigh)
v2=FindMinRec(ilow,ihigh,mid+1,high,2*pos+2);
return max(v1,v2);
}
};
int N,M;
vector<int> inp;
void Read(){
in>>N>>M;
for(int i=0;i<N;i++){
int temp;
in>>temp;
inp.push_back(temp);
}
}
void Determinare(){
SegmentTree sg(inp);
for(int i=1;i<=M;i++){
int tip;
in>>tip;
if(tip==0){
int l,h;
in>>l>>h;
out<<sg.FindMin(l-1,h-1)<<"\n";
}
else if(tip==1){
int pos,val;
in>>pos>>val;
sg.Actualizare(pos-1,val);
}
}
}
int main()
{
Read();
Determinare();
return 0;
}