#include <cstdio>
#include <iostream>
using namespace std;
const int MAX = 100010;
int a[MAX];
int arb[MAX*4 + 100];
int N, M;
char r[MAX];
int p = MAX - 1;
int type, x, y;
int maxim;
void Get( int& x );
void Next();
void Update( int poz, int val, int nod, int left, int right );
void Query( int a, int b, int nod, int left, int right );
int main()
{
freopen( "arbint.in", "r", stdin );
freopen( "arbint.out", "w", stdout );
int i, j;
Get(N); Get(M);
for ( i = 1; i <= N; i++ )
{
Get(j);
a[i] = j;
Update( i, j, 1, 1, N );
}
for ( i = 1; i <= M; i++ )
{
Get(type);
Get(x);
Get(y);
if ( type == 0 )
{
maxim = 0;
Query(x, y, 1, 1, N);
printf( "%d\n", maxim );
}
else
{
Update( x, y, 1, 1, N );
}
}
fclose(stdin);
fclose(stdout);
return 0;
}
void Get( int& x )
{
for ( ; r[p] < '0' || r[p] > '9'; Next() );
for ( x = 0; r[p] >= '0' && r[p] <= '9'; Next() )
x = x * 10 + ( r[p] - '0' );
}
void Next()
{
if ( ++p == MAX )
std::fread( r, 1, MAX, stdin ), p = 0;
}
void Update( int poz, int val, int nod, int left, int right )
{
if ( left == right )
{
arb[nod] = val;
return;
}
int mid = ( left + right ) / 2;
if ( poz <= mid ) Update( poz, val, nod * 2, left, mid );
else Update( poz, val, nod * 2 + 1, mid + 1, right );
arb[nod] = max( arb[2*nod], arb[2*nod + 1] );
}
void Query( int a, int b, int nod, int left, int right )
{
if ( left >= a && right <= b )
{
if ( arb[nod] > maxim ) maxim = arb[nod];
return;
}
int mid = ( left + right ) / 2;
if ( a <= mid ) Query( a, b, nod * 2, left, mid );
if ( mid < b ) Query( a, b, nod * 2 + 1, mid + 1, right );
}