#include <stdio.h>
#define MAXN 100000
int tree[4 * MAXN + 1];
int v[MAXN + 1];
int max( int a, int b ) {
if ( a < b ) {
return b;
}
return a;
}
void build( int nod, int st, int dr ) {
int mij;
if ( st == dr ) {
tree[nod] = v[st];
} else {
mij = (st + dr) / 2;
build( 2 * nod, st, mij );
build( 2 * nod + 1, mij + 1, dr );
tree[nod] = max( tree[2 * nod], tree[2 * nod + 1] );
}
}
void update( int nod, int st, int dr, int poz, int val ) {
int mij;
if ( st == dr ) {
tree[nod] = val;
} else {
mij = (st + dr) / 2;
if ( poz <= mij ) {
update( 2 * nod, st, mij, poz, val );
} else {
update( 2 * nod + 1, mij + 1, dr, poz, val );
}
tree[nod] = max( tree[2 * nod], tree[2 * nod + 1] );
}
}
int query( int nod, int st, int dr, int a, int b ) {
int mij, x = 0, y = 0;
if ( a <= st && dr <= b ) {
return tree[nod];
}
mij = (st + dr) / 2;
if ( a <= mij ) {
x = query( 2 * nod, st, mij, a, b );
}
if ( b > mij ) {
y = query( 2 * nod + 1, mij + 1, dr, a, b );
}
return max( x, y );
}
int main() {
FILE *fin = fopen( "arbint.in", "r" );
FILE *fout = fopen( "arbint.out", "w" );
int n, m, i, t, a, b;
fscanf( fin, "%d%d", &n, &m );
for ( i = 1; i <= n; ++i ) {
fscanf( fin, "%d", &v[i] );
}
build( 1, 1, n );
for ( i = 0; i < m; ++i ) {
fscanf( fin, "%d%d%d", &t, &a, &b );
if ( t == 0 ) {
fprintf( fout, "%d\n", query( 1, 1, n, a, b ) );
} else {
update( 1, 1, n, a, b );
}
}
fclose( fin );
fclose( fout );
return 0;
}