#include <cstdio>
#include <algorithm>
using namespace std;
FILE *f = fopen ( "arbint.in" , "r" ) , *g = fopen ( "arbint.out" , "w" );
const int MAX = 100005 , MAXT = 1000000;
int N , M , i , myInts [ MAX ] , tree [ MAXT ] , type , a , b ;
void read()
{
fscanf ( f , "%d %d" , &N , &M );
for ( i = 1 ; i <= N ; i ++ )
fscanf ( f , "%d" , &myInts [ i ] );
}
void build ( int left , int right , int index )
{
int LHS , RHS , mid;
if ( left <= right )
if ( left == right )
tree [ index ] = myInts [ left ];
else
{
mid = ( left + right ) / 2;
LHS = index * 2 , RHS = index * 2 + 1;
build ( left , mid , LHS );
build ( mid + 1 , right , RHS );
tree [ index ] = max ( tree [ LHS ] , tree [ RHS ] );
}
}
int getMax ( int left , int right , int index , int Lindex , int Rindex )
{
int LHS , RHS , mid;
if ( left <= right )
if ( Lindex == left && Rindex == right )
return tree [ index ];
else
{
mid = ( left + right ) / 2;
LHS = index * 2 , RHS = index * 2 + 1;
if ( Rindex <= mid )
return getMax ( left , mid , LHS , Lindex , Rindex );
else
if ( Lindex > mid )
return getMax ( mid + 1 , right , RHS , Lindex , Rindex );
else
return max ( getMax ( left , mid , LHS , Lindex , mid ) , getMax ( mid + 1 , right , RHS , mid + 1 , Rindex ) );
}
}
int update ( int left , int right , int index , int range , int value )
{
int LHS , RHS , mid;
if ( left <= right )
if ( left == range && right == range )
tree [ index ] = value;
else
{
mid = ( left + right ) / 2;
LHS = index * 2 , RHS = index * 2 + 1;
if ( range <= mid )
update ( left , mid , LHS , range , value );
else
update ( mid + 1 , right , RHS , range , value );
//update father
tree [ index ] = max ( tree [ LHS ] , tree [ RHS ] );
}
}
int main()
{
read();
build ( 1 , N , 1 );
//get requests
for ( i = 1 ; i <= M ; i ++ )
{
fscanf ( f , "%d %d %d" , &type , &a , &b );
if ( type == 0 )
fprintf ( g , "%d\n" , getMax ( 1 , N , 1 , a , b ) );
else
update ( 1 , N , 1 , a , b );
}
return 0;
}