#include <stdio.h>
#include <algorithm>
#define MAXN 100000
int v[MAXN], aint[MAXN * 2];
void construct( int l, int r, int node ) {
int leftChild, rightChild, middle;
middle = (r + l) / 2;
leftChild = node + 1;
rightChild = node + 2 * ( middle - l + 1 );
if( l == r )
aint[node] = v[l - 1];
else {
construct( l, middle, leftChild );
construct( middle + 1, r, rightChild );
aint[node] = std::max( aint[leftChild], aint[rightChild] );
}
}
int getMax( int a, int b, int l, int r, int node ) {
if( l == a && r == b )
return aint[node];
int leftChild, rightChild, middle, mx;
middle = (r + l) / 2;
leftChild = node + 1;
rightChild = node + 2 * ( middle - l + 1 );
mx = 0;
if( a <= middle )
mx = std::max( mx, getMax( a, std::min( middle, b ), l, middle, leftChild ));
if( b > middle )
mx = std::max( mx, getMax( std::max( middle + 1, a ), b, middle + 1, r, rightChild ));
return mx;
}
void update( int l, int r, int node, int pos, int val ) {
if( l == r ) {
aint[node] = val;
return;
}
int leftChild, rightChild, middle, mx;
middle = (r + l) / 2;
leftChild = node + 1;
rightChild = node + 2 * ( middle - l + 1 );
if( pos <= middle )
update( l, middle, leftChild, pos, val );
else
update( middle + 1, r, rightChild, pos, val );
aint[node] = std::max( aint[leftChild], aint[rightChild] );
}
int main() {
FILE *fin, *fout;
int n, m, i, a, b, op;
fin = fopen( "arbint.in", "r" );
fscanf( fin, "%d%d", &n, &m );
for( i = 0; i < n; i++ )
fscanf( fin, "%d", &v[i] );
construct(1, n, 0);
fout = fopen( "arbint.out", "w" );
for( i = 0; i < m; i++ ) {
fscanf( fin, "%d%d%d", &op, &a, &b );
if( op == 0 )
fprintf( fout, "%d\n", getMax(a, b, 1, n, 0) );
else
update( 1, n, 0, a, b );
}
fclose( fin );
fclose( fout );
return 0;
}