// FMI - UNIBUC - INFO
/*
_|_|_|_| _|_|_|_|_| _|_| _| _|_|_|_| _|_|_|_|_| _| _|_| _| _|_|_|_|_| _| _|_| _|
_| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _|
_| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _|
_| _| _| _| _| _| _|_|_| _| _| _|_|_| _| _| _| _| _| _| _| _|
_| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _| _|
_|_|_|_| _|_|_|_|_| _| _|_| _|_|_|_| _| _| _| _| _|_| _| _| _| _|_|
*/
// Platform: Infoarena
// Problem: Arbori de intervale
// Programming Language: C++
// Date: 23.5.2016
# include <fstream>
# include <algorithm>
# include <vector>
using namespace std;
ifstream f ( "arbint.in" );
ofstream g ( "arbint.out" );
vector < int > A;
void update( int index, pair< int, int > seg, int poz, int val ) {
if ( seg.first == seg.second ) {
A[index] = val;
return;
}
int mid = ( seg.first + seg.second ) / 2;
if ( poz <= mid ) {
update( index * 2, { seg.first, mid }, poz, val );
}
else {
update( index * 2 + 1, { mid + 1, seg.second}, poz, val );
}
A[index] = max( A[index * 2], A[index * 2 + 1] );
}
int query( int index, pair< int, int > seg, pair< int, int > q ) {
if ( q.first <= seg.first && seg.second <= q.second ) {
return max( A[index], 0 );
}
int mid = ( seg.first + seg.second ) / 2;
int answer = 0;
if ( q.first <= mid ) {
answer = max( answer, query( index * 2, { seg.first, mid }, q ) );
}
if ( q.second >= mid + 1 ) {
answer = max( answer, query( index * 2 + 1, { mid + 1, seg.second }, q ) );
}
return answer;
}
int main()
{
int n, m; f >> n >> m;
A.resize( 4 * n, 0 );
for ( int i = 1; i <= n; ++ i ) {
int x; f >> x;
update( 1, {1, n}, i, x );
}
for ( int i = 1; i <= m; ++ i ) {
int op, a, b; f >> op >> a >> b;
if ( op ) {
update( 1, {1, n}, a, b );
}
else {
g << query( 1, {1, n}, {a, b} ) << '\n';
}
}
return 0;
}