#include <stdio.h>
#include <ctype.h>
#define MAXN 100000
#define MAXNOD 262144// 2^18 (nu este cu -1 deoarece avem o santinela la poz. 0)
int num[MAXN];// numerele insusi
int coresp[MAXN];// nodul care corespunde elementului i
int st[MAXNOD];
int dr[MAXNOD];
int val[MAXNOD];
FILE *fin, *fout;
static inline int max( int a, int b ){
return a > b ? a : b;
}
static inline int fgetint(){
int n = 0, ch;
while( !isdigit(ch = fgetc(fin)) );
do
n = n * 10 + ch - '0';
while( isdigit(ch = fgetc(fin)) );
return n;
}
static inline void fputint( int n ){
int i = 10;
char out[] = "0000000000\n";
if( n == 0 ){
fputs("0\n", fout);
return;
}
while( n ){
out[--i] = n % 10 + '0';
n /= 10;
}
fputs(out + i, fout);
}
void init( int root, int a, int b ){
int left = 2 * root, right = 2 * root + 1;
st[root] = a;
dr[root] = b;
if( a == b ){
coresp[a] = root;
val[root] = num[a];
}else{
init( left, a, (a + b)/2 );
init( right, (a + b)/2 + 1, b );
val[root] = max(val[left], val[right]);
}
}
void setVal( int i, int newval ){
int parent;
num[i] = newval;
val[coresp[i]] = newval;
parent = coresp[i] / 2;
while( parent > 0 ){// cat timp mai avem noduri de actualizat
val[parent] = max(val[2 * parent], val[2 * parent + 1]);
parent = parent / 2;
}
}
/*
avem 4 cazuri:
a b root
[--------] [-----------]
a b
[-----[=====]------]
root
a b
[-------[=======]-------]
root
a b
[-------[=======]-------]
root
*/
int getMax( int root, int a, int b ){
if( st[root] > b || a > dr[root] )// daca nu se intersecteaza returnam 0
return 0;
if( a <= st[root] && dr[root] <= b )
return val[root];
return max(getMax(2 * root, a, b), getMax(2 * root + 1, a, b));
}
/*void printTree( int root, int indent ){
int i;
if( st[root] < dr[root] )
printTree(2 * root, indent + 1);
for( i = 0 ; i < indent ; i++ )
fputs(" ", stdout);
printf("[%d, %d] -> %d\n", st[root], dr[root], val[root]);
if( st[root] < dr[root] )
printTree(2 * root + 1, indent + 1);
}*/
int main(){
fin = fopen("arbint.in", "r");
fout = fopen("arbint.out", "w");
int n, q, type, i, j, newval;
n = fgetint();
q = fgetint();
for( i = 0 ; i < n ; i++ )
num[i] = fgetint();
// calculam starea initiala a arborelui
init(1, 0, n - 1);// 1 = root (poz. 0 este santinela)
// raspundem la query-uri
for( ; q-- ; ){
type = fgetint();
if( type == 0 ){
i = fgetint() - 1;
j = fgetint() - 1;
fputint(getMax(1, i, j));
}else{
i = fgetint() - 1;
newval = fgetint();
setVal(i, newval);
}
}
fclose(fin);
fclose(fout);
return 0;
}