#include <iostream>
#include <fstream>
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
const int NLIM = 100000 + 10;
int N, Q;
int v[NLIM];
int tree[NLIM*2];
int left( int i )
{
return i * 2 + 1;
}
int right( int i )
{
return i * 2 + 2;
}
int update( int nod, int l, int r, int ql, int qr )
{
if( r < ql || l > qr )
return tree[nod];
if( l == r )
{
tree[nod] = v[l];
return tree[nod];
}
int m = ( l + r ) / 2;
tree[nod] = max( update( left( nod ), l, m, ql, qr ), update( right( nod ), m + 1, r, ql, qr ) );
return tree[nod];
}
int get( int nod, int l, int r, int ql, int qr )
{
if( l >= ql && r <= qr )
return tree[nod];
if( r < ql || l > qr )
return -1;
int m = ( l + r ) / 2;
return max(
get( left( nod ), l, m, ql, qr ),
get( right( nod ), m + 1, r, ql, qr ) );
}
int build( int nod, int l, int r )
{
if( l == r )
{
tree[nod] = v[l];
return tree[nod];
}
int m = ( l + r ) / 2;
tree[nod] = max( build( left(nod) , l, m ), build(right(nod), m + 1, r ));
return tree[nod];
}
int main()
{
fin >> N >> Q;
for( int i = 0; i < N; ++i )
fin >> v[i];
build( 0, 0, N - 1 );
while( Q-- )
{
int typ;
fin >> typ;
if( typ == 0 )
{
// get max
int a, b;
fin >> a >> b;
--a;
--b;
fout << get( 0, 0, N - 1, a, b ) << "\n";
}
else
{
// update
int idx, val;
fin >> idx >> val;
--idx;
v[idx] = val;
update( 0, 0, N - 1, idx, idx );
}
}
return 0;
}