#include <iostream>
#include <vector>
#include <fstream>
std::ifstream fin{"arbint.in"};
std::ofstream fout{"arbint.out"};
class Segtree {
public:
int n;
std::vector<int> segtree;
Segtree(int _n) : n(_n) {
segtree.reserve(4 * n + 1);
}
int parent(int n) {
return n / 2;
}
int child_left(int n) {
return 2 * n;
}
int child_right(int n) {
return 2 * n + 1;
}
// interval a, b starting from node(l, r)
int update(int a, int b, int l, int r, int node, int s) {
int mid = l + (r - l) / 2;
if (l == r) {
// node is leaf & update
segtree[node] = s;
} else {
if (a <= mid)
this->update(a, b, l, mid, child_left(node), s);
if (b >= mid)
this->update(a, b, mid + 1, r, child_right(node), s);
}
}
int query(int a, int b, int l, int r, int node) {
int mid = l + (r - l) / 2;
if (l == r)
return segtree[node];
else {
int x = 0, y = 0;
if (a <= mid)
x = query(a, b, l, mid, child_left(node));
if (b >= mid)
y = query(a, b, mid + 1, r, child_right(node));
return std::max(x, y);
}
}
int update(int a, int b, int s) {
return update(a, b, 1, n, 1, s);
}
int query(int a, int b) {
return query(a, b, 1, n, 1);
}
int query() {
int q, a, b;
std::cin >> q >> a >> b;
if (q == 1) {
update(a, a, b);
} else {
fout << query(a, b-1)<<"\n";
}
}
void build(int l, int r, int nod) {
if (l == r)
fin >> segtree[nod];
else {
int mid = l + (r - l) / 2;
build(l, mid, child_left(nod));
build(mid + 1, r, child_right(nod));
segtree[nod] = std::max(segtree[child_left(nod)], segtree[child_right(nod)]);
}
}
};
int main() {
int n, m;
fin >> n >> m;
Segtree s(n);
s.build(1, n, 1);
for (int i = 0 ; i < m; ++i) {
s.query();
}
}