#include <fstream>
#include <vector>
using namespace std ;
ifstream cin ("arbint.in") ;
ofstream cout ("arbint.out") ;
class SegmentTree {
public :
SegmentTree() {}
SegmentTree(int n) {
this -> n = n ;
arb.resize(n << 2) ;
}
void Update (int poz, int val) {
update (1, 1, this -> n, poz, val) ;
}
int Query (int a, int b) {
return query (1, 1, this -> n, a, b) ;
}
private :
int n ;
vector <int> arb ;
void update (int nod, int st, int dr, int pos, int val) {
if (st == dr) {
arb [nod] = val ;
return ;
}
int mij = (st + dr) >> 1 ;
if (pos <= mij) {
update (nod * 2, st, mij, pos, val) ;
}
else {
update (nod * 2 + 1, mij + 1, dr, pos, val) ;
}
arb [nod] = max (arb [nod << 1], arb [nod << 1 | 1]) ;
}
int query (int nod, int st, int dr, int a, int b) {
if (a <= st and dr <= b) {
return arb [nod] ;
}
int mij = (st + dr) >> 1 ;
int leftt = 0 ;
int rightt = 0 ;
if (a <= mij) {
leftt = query (nod << 1, st, mij, a, b) ;
}
if (b > mij) {
rightt = query (nod << 1 | 1, mij + 1, dr, a, b) ;
}
return max (leftt, rightt) ;
}
};
int main() {
int n, m ;
cin >> n >> m ;
SegmentTree * T = new SegmentTree (n);
for (int i = 1 ; i <= n ; ++ i) {
int x ;
cin >> x ;
T -> Update(i, x) ;
}
while (m --) {
int tip ;
cin >> tip ;
if (tip == 0) {
int a, b ;
cin >> a >> b ;
cout << T -> Query(a, b) << '\n' ;
}
else {
int poz, val ;
cin >> poz >> val ;
T -> Update(poz, val) ;
}
}
return 0;
}