#include <cstdio>
#include <cstdlib>
using namespace std ;
int nrFrunze , nrOperatii , arbore [ 400001 ] ;
void citireStart ( ) ;
void compunereArbore ( ) ;
void efectuareOperatie ( ) ;
void infundArbore ( int , int , int , int , int ) ;
int extragArbore ( int , int , int , int , int ) ;
inline int max ( int A , int B )
{
return ( A > B ) ? A : B ;
}
int main ( )
{
freopen ( "arbint.in", "r" , stdin ) ;
freopen ( "arbint.out" , "w" , stdout ) ;
citireStart ( ) ;
compunereArbore ( ) ;
for ( int i = 0 ; i < nrOperatii ; ++i )
efectuareOperatie ( ) ;
}
void citireStart ( )
{
scanf ("%d%d" , &nrFrunze , &nrOperatii ) ;
return ;
}
void compunereArbore ( )
{
int val ;
for ( int i = 1 ; i <= nrFrunze ; ++i )
{
scanf ( "%d" , &val ) ;
infundArbore ( i , val , 1 , nrFrunze , 1 ) ;
}
return ;
}
void efectuareOperatie ( )
{
int opt ;
int a , b ;
scanf ( "%d%d%d" , &opt , &a , &b ) ;
if ( opt )
infundArbore ( a , b, 1, nrFrunze , 1 ) ;
else
printf ( "%d\n" , extragArbore ( a , max ( nrFrunze ,b ) , 1 , nrFrunze , 1 ) ) ;
return ;
}
void infundArbore ( int Poz , int Val , int Stanga , int Dreapta , int Index )
{
if ( Stanga == Dreapta )
{
arbore [ Index ] = Val ;
return ;
}
if ( Poz > ( ( Stanga + Dreapta ) >> 1 ) )
{
infundArbore ( Poz , Val , ( ( Stanga + Dreapta ) >> 1 ) + 1 , Dreapta , ( Index << 1 ) + 1 ) ;
arbore [ Index ] = max ( arbore [ Index << 1 ] , arbore [ ( Index << 1 ) + 1 ] ) ;
return ;
}
else
{
infundArbore ( Poz , Val , Stanga , ( Stanga + Dreapta ) >> 1 , Index << 1 ) ;
arbore [ Index ] = max ( arbore [ Index << 1 ] , arbore [ ( Index << 1 ) ] ) ;
return ;
}
}
int extragArbore ( int maxStanga , int maxDreapta , int Stanga , int Dreapta , int Index )
{
if ( Stanga > maxDreapta || Dreapta < maxStanga )
return 0 ;
if ( Stanga >= maxStanga && Dreapta <= maxDreapta )
return arbore [ Index ] ;
return max ( extragArbore ( maxStanga , maxDreapta , ( ( Stanga + Dreapta ) >> 1 ) + 1 , Dreapta , ( Index << 1 ) + 1 ) ,
extragArbore ( maxStanga , maxDreapta , Stanga , ( Stanga + Dreapta ) >> 1 , Index << 1 ) );
}