#include <fstream>
using namespace std;
ifstream fin ("arbint.in");
ofstream fout ("arbint.out");
int v[100001], arb[200001];
void construieste ( int nod, int st, int dr );
int maxx ( int nod, int st, int dr, int a, int b );
void inlocuieste ( int nod, int st, int dr, int a, int b );
int main()
{
int n, m, i, c, a, b;
fin >> n >> m;
for ( i = 1 ; i <= n ; i++ ) fin >> v[i];
construieste ( 1, 1, n );
for ( i = 1 ; i <= m ; i++ )
{
fin >> c >> a >> b;
if ( c == 0 ) fout << maxx ( 1, 1, n, a, b ) << '\n';
else inlocuieste ( 1, 1, n, a, b );
}
return 0;
}
void construieste ( int nod, int st, int dr )
{
int mij = ( st + dr ) / 2;
if ( st == dr ) arb[nod] = v[st];
else
{
construieste ( nod * 2 , st, mij );
construieste ( nod * 2 + 1, mij + 1 , dr );
arb[nod] = max ( arb[nod*2], arb[nod*2+1] );
}
}
void inlocuieste ( int nod, int st, int dr, int a, int b )
{
int mij = ( st + dr ) / 2;
if ( st == dr ) arb[nod] = b;
else
{
if ( a <= mij ) inlocuieste ( nod * 2 , st, mij, a, b );
else inlocuieste ( nod * 2 + 1 , mij + 1 , dr, a, b );
arb[nod] = max ( arb[nod*2], arb[nod*2+1] );
}
}
int maxx ( int nod, int st, int dr, int a, int b )
{
int mij = ( st + dr ) / 2, r = 0;
if ( a <= st && b >= dr ) r = arb[nod];
else
{
if ( a <= mij ) r = maxx ( nod * 2 , st, mij, a, b );
if ( b > mij ) r = max ( r, maxx ( nod * 2 + 1, mij + 1 , dr, a, b ) );
}
return r;
}