#include <iostream>
#include <vector>
#include <fstream>
std::ifstream fin("arbint.in");
std::ofstream fout("arbint.out");
int segtree[4 * 100000 + 1];
class Segtree {
public:
int n;
Segtree(int _n) : n(_n) {
}
int parent(int& n) {
return n / 2;
}
int child_left(int& n) const {
return 2 * n;
}
int child_right(int& n) const {
return 2 * n + 1;
}
// interval a, b starting from node(l, r)
void update(int& a, int& b, int l, int r, int node, int s) {
int mid = l + (r - l) / 2;
if (a <= l && r <= b) {
segtree[node] = s;
return;
}
if (a <= mid)
update(a, b, l, mid, child_left(node), s);
else
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 (a <= l && r <= b)
return segtree[node];
int x = -1;
if (a <= mid)
x = std::max(x, query(a, b, l, mid, child_left(node)));
if (b > mid)
x = std::max(x, query(a, b, mid + 1, r, child_right(node)));
return x;
}
void update(int& a, int& b, int s) {
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;
fin >> q >> a >> b;
if (q == 1) {
update(a, a, b);
} else {
fout << query(a, b)<<"\n";
}
return 0;
}
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();
}
}