#include <stdio.h>
#define N_MAX 100000
typedef char bool;
int M, N;
int tree[ 4 * N_MAX + 1 ];
inline int lson( int x ) {
return 2 * x;
}
inline int rson( int x ) {
return 2 * x + 1;
}
inline int max( int a, int b ) {
return a > b ? a : b;
}
void update( int top, int l, int r, int pos, int val ) {
if( r != l ) {
int m = ( l + r ) / 2;
if( pos > m ) {
update( rson( top ), m + 1, r, pos, val );
} else {
update( lson( top ), l, m, pos, val );
}
tree[ top ] = max( tree[ lson( top ) ], tree[ rson( top ) ] );
} else {
tree[ top ] = val;
}
}
int query( int top, int l, int r, int beg, int end ) {
int currmax = -1;
if( beg <= l && r <= end ) {
currmax = max( currmax, tree[ top ] );
} else {
int m = ( l + r ) / 2;
if( beg <= m ) {
currmax = max( currmax, query( lson( top ), l, m, beg, end ) );
}
if( m < end ) {
currmax = max( currmax, query( rson( top ), m + 1, r, beg, end ) );
}
}
return currmax;
}
int main( ) {
FILE * fin, * fout;
fin = fopen( "arbint.in", "r" );
fout = fopen( "arbint.out", "w" );
int N, M;
fscanf( fin, "%d%d", &N, &M );
int i;
for( i = 1; i <= N; i ++ ) {
int read;
fscanf( fin, "%d", &read );
update( 1, 1, N, i, read );
}
for( i = 1; i <= M; i ++ ) {
int type, a, b;
fscanf( fin, "%d%d%d", &type, &a, &b );
if( type ) {
update( 1, 1, N, a, b );
} else {
fprintf( fout, "%d\n", query( 1, 1, N, a, b ) );
}
}
fclose( fin );
fclose( fout );
}