#include <fstream>
#include <vector>
using namespace std;
struct SegTree {
vector<int> nodes;
int size;
SegTree(int size) : nodes(4 * size + 10, 0), size(size) {
}
void Set(int pos, int num) {
Set(0, 0, size - 1, pos, num);
}
int Max(int left, int right) const {
return Max(0, 0, size - 1, left, right);
}
void Set(int node, int l, int r, int pos, int num) {
if (l == r) {
nodes[node] = num;
return;
}
auto m = l + (r - l) / 2;
if (pos <= m) {
Set(LeftSon(node), l, m, pos, num);
} else {
Set(RightSon(node), m + 1, r, pos, num);
}
nodes[node] = max(nodes[LeftSon(node)], nodes[RightSon(node)]);
}
int 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;
auto res = 0;
if (left <= m) {
res = max(res, Max(LeftSon(node), l, m, left, right));
}
if (m < right) {
res = max(res, Max(RightSon(node), m + 1, r, left, right));
}
return res;
}
static int LeftSon(int node) {
return 2 * node + 1;
}
static int RightSon(int node) {
return 2 * node + 2;
}
};
int main() {
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int n, queries;
fin >> n >> queries;
SegTree tree(n);
for (int i = 0; i < n; i += 1) {
int num;
fin >> num;
tree.Set(i, num);
}
for (int i = 0; i < queries; 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;
}