#include <fstream>
using namespace std;
const int nmax = 1e5;
int v[nmax + 1];
int aint[4 * nmax + 1];
void build ( int node, int st, int dr ) {
if ( st == dr ) {
aint[node] = v[st];
return;
}
int mij = ( st + dr ) / 2;
build ( 2 * node, st, mij );
build ( 2 * node + 1, mij + 1, dr );
aint[node] = max ( aint[2 * node], aint[2 * node + 1] );
}
void update ( int node, int st, int dr, int poz, int val ) {
if ( st == dr ) {
aint[node] = val;
return;
}
int mij = ( st + dr ) / 2;
if ( poz <= mij ) update ( 2 * node, st, mij, poz, val );
else update ( 2 * node + 1, mij + 1, dr, poz, val );
aint[node] = max ( aint[2 * node], aint[2 * node + 1] );
}
int query ( int node, int st, int dr, int a, int b ) {
if ( a == st && dr == b )
return aint[node];
int mij = ( st + dr ) / 2;
if ( b <= mij )
return query ( 2 * node, st, mij, a, b );
if ( a > mij )
return query ( 2 * node + 1, mij + 1, dr, a, b );
return max ( query ( 2 * node, st, mij, a, mij ),
query ( 2 * node + 1, mij + 1, dr, mij + 1, b ) );
}
ifstream fin ( "arbint.in" );
ofstream fout ( "arbint.out" );
int main() {
int n, q, tip, x, k, a, b;
fin >> n >> q;
for ( int i = 1; i <= n; i++ )
fin >> v[i];
build ( 1, 1, n );
/**
tip 0: query: max ( v[a], ..., v[b] )
tip 1: update: v[x] = k
**/
while ( q-- ) {
fin >> tip;
if ( tip == 1 ) {
fin >> k >> x;
update ( 1, 1, n, k, x );
} else {
fin >> a >> b;
fout << query ( 1, 1, n, a, b ) << '\n';
}
}
return 0;
}