#include <algorithm>
#include <fstream>
#include <vector>
using namespace std;
class IntervalTree {
public:
IntervalTree(int size);
void Set(int pos, int value);
int Max(int left, int right) const;
private:
void Set(int node, int l, int r, int pos, int value);
int Max(int node, int l, int r, int left, int right) const;
static int LeftSon(int pos) {
return 2 * pos + 1;
}
static int RightSon(int pos) {
return 2 * pos + 2;
}
vector<int> nodes_;
int size_;
};
IntervalTree::IntervalTree(int size)
: nodes_(4 * size + 4, 0), size_(size) {
}
void IntervalTree::Set(int pos, int value) {
Set(0, 0, size_ - 1, pos, value);
}
int IntervalTree::Max(int left, int right) const{
return Max(0, 0, size_ - 1, left, right);
}
void IntervalTree::Set(int node, int l, int r, int pos, int value) {
if (l == r) {
nodes_[node] = value;
return;
}
auto m = l + (r - l) / 2;
if (pos <= m) {
Set(LeftSon(node), l, m, pos, value);
} else {
Set(RightSon(node), m + 1, r, pos, value);
}
nodes_[node] = max(nodes_[LeftSon(node)],
nodes_[RightSon(node)]);
}
int IntervalTree::Max(int node, int l, int r, int left, int right) const {
if (left <= l && r <= right) {
return nodes_[node];
}
auto m = l + (r - l) / 2;
return max({
(left <= m) ? Max(LeftSon(node), l, m, left, right) : -(1 << 30),
(m < right) ? Max(RightSon(node), m + 1, r, left, right) : -(1 << 30),
});
}
int main() {
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int n, q;
fin >> n >> q;
IntervalTree tree(n);
for (auto i = 0; i < n; i += 1) {
int num;
fin >> num;
tree.Set(i, num);
}
for (auto i = 0; i < q; i += 1) {
int type, a, b;
fin >> type >> a >> b;
if (type == 0) {
fout << tree.Max(a - 1, b - 1) << "\n";
} else {
tree.Set(a - 1, b);
}
}
return 0;
}