#include <cstdio>
#define fs( x ) ( x ) * 2
#define fd( x ) ( x ) * 2 + 1
#define maxim( a, b ) ( a > b ) ? a : b
const int MAX_N = 100002;
const char infile[] = "arbint.in";
const char outfile[] = "arbint.out";
int arb[ 4 * MAX_N ];
int N, M, max, val, poz, a, b;
void update( int node, int left, int right ){
if( left == right ){
arb[ node ] = val;
return;
}
int m = ( left + right ) / 2;
if( poz <= m )
update( fs( node), left, m );
else
update( fd( node ), m + 1, right );
arb[ node ] = maxim( arb[ fs( node ) ], arb[ fd( node ) ] );
}
void query( int node, int left, int right ){
if( a <= left && right <= b ){
if( max < arb[ node ] )
max = arb[ node ];
return;
}
int m = ( left + right ) / 2;
if( a <= m )
query( fs( node ), left, m );
if( b > m )
query( fd( node), m + 1, right );
}
int main(){
FILE *f, *g;
f = fopen( infile, "rt" );
g = fopen( outfile, "wt" );
int i, op;
fscanf( f, "%d %d", &N, &M );
for( i = 1; i <= N; ++i ){
fscanf( f, "%d", &val );
poz = i;
update( 1, 1, N );
}
for( i = 1; i <=M ; ++i ){
fscanf( f, "%d %d %d", &op, &a, &b );
if( !op ){
max = -1;
query( 1, 1, N );
fprintf( g, "%d\n", max );
}
else{
val = b;
poz = a;
update( 1, 1, N );
}
}
return 0;
}