#include <stdio.h>
#include <stdlib.h>
#define NMAX 100000
int v[NMAX];
int aint[NMAX*4];
void build(int node, int nLeft, int nRight) {
if (nLeft == nRight) {
aint[node] = v[nLeft];
return;
}
int nMid, leftSon, rightSon;
nMid = (nLeft + nRight) / 2;
leftSon = node + 1;
rightSon = node + 2 * (nMid - nLeft + 1);
build(leftSon, nLeft, nMid);
build(rightSon, nMid + 1, nRight);
if( aint[leftSon] > aint[rightSon] )
aint[node] = aint[leftSon];
else
aint[node] = aint[rightSon];
}
int query( int node, int nLeft, int nRight, int qLeft, int qRight ) {
if (qLeft <= nLeft && qRight >= nRight)
return aint[node];
int nMid, leftSon, rightSon;
int lmax, rmax;
nMid = (nLeft + nRight) / 2;
leftSon = node + 1;
rightSon = node + 2 * (nMid - nLeft + 1);
lmax = rmax = 0;
if (qLeft <= nMid)
lmax = query(leftSon, nLeft, nMid, qLeft, qRight);
if (nMid < qRight)
rmax = query(rightSon, nMid+1, nRight, qLeft, qRight);
return rmax > lmax ? rmax : lmax;
}
void update( int node, int nLeft, int nRight, int pos, int value ) {
if (nLeft == nRight) {
aint[node] = value;
return;
}
int nMid, leftSon, rightSon;
nMid = (nLeft + nRight) / 2;
leftSon = node + 1;
rightSon = node + 2 * (nMid - nLeft + 1);
if (pos <= nMid)
update(leftSon, nLeft, nMid, pos, value);
else
update(rightSon, nMid + 1, nRight, pos, value);
if( aint[leftSon] > aint[rightSon] )
aint[node] = aint[leftSon];
else
aint[node] = aint[rightSon];
}
int main() {
FILE *fin, *fout;
int n, m, i, op, a, b;
fin = fopen( "arbint.in", "r" );
fout = fopen( "arbint.out", "w" );
fscanf( fin, "%d%d", &n, &m );
for( i = 0; i < n; i++ )
fscanf( fin, "%d", &v[i] );
build( 0, 0, n - 1 );
for( i = 0; i < m; i++ ) {
fscanf( fin, "%d%d%d", &op, &a, &b );
a--;
b--;
if( op == 1 ) {
v[a] = b + 1;
update( 0, 0, n - 1, a, b + 1 );
}
else
fprintf( fout, "%d\n", query( 0, 0, n - 1, a, b ) );
}
fclose( fin );
fclose( fout );
return 0;
}