#include<fstream>
using namespace std;
ifstream f("arbint.in");
ofstream g("arbint.out");
int n , m , cap_st , cap_dr , x , op , a , b;
int Arb[300000];
inline int maxim( int a , int b ){
return a>b?a:b;
}
void update( int nod , int val , int el , int cap_st , int cap_dr ){
if( cap_st == cap_dr )
Arb[nod] = val;
else{
int mid = (cap_st + cap_dr) / 2;
if( el <= mid )
update( 2*nod , val , el , cap_st , mid );
else
update( 2*nod + 1 , val , el , mid + 1 , cap_dr );
Arb[nod] = maxim( Arb[2*nod] , Arb[2*nod + 1] );
}
}
int querry( int nod , int st , int dr , int cap_st , int cap_dr ){
if( cap_st >= st && cap_dr <= dr )
return Arb[nod];
else{
int mid = ( cap_st + cap_dr ) / 2;
int v1 = 0 , v2 = 0;
if( (cap_st >= st && cap_st <= dr) || ( mid >=st && mid <= dr ) )
v1 = querry( 2*nod , st , dr , cap_st , mid );
mid++;
if( ( mid >= st && mid <= dr ) || ( cap_dr >= st && cap_dr <= dr ) )
v2 = querry( 2*nod + 1 , st , dr , mid , cap_dr );
return maxim(v1 , v2);
}
}
void read(){
f>>n>>m;
cap_st = 1;
cap_dr = n;
for( int i = 1 ; i <= n ; i++ ){
f>>x;
update( 1 , x , i , cap_st , cap_dr );
}
}
void solve(){
while( (m--) ){
f>>op>>a>>b;
if( op == 0 )
g<<querry(1 , a , b , cap_st , cap_dr)<<"\n";
else
update(1 , b , a , cap_st , cap_dr );
}
}
int main(){
read();
solve();
return 0;
}