#include <fstream>
#include <vector>
using namespace std;
const int NMAX = 100000;
const int INF = (1 << 30);
vector <int> a;
vector <int> segTree;
void build(int node, int left, int right) {
if (left == right) {
segTree[node] = a[left];
}
else {
int mid = (left + right) / 2;
build(2 * node, left, mid);
build(2 * node + 1, mid + 1, right);
segTree[node] = max(segTree[2 * node], segTree[2 * node + 1]);
}
}
void update(int node, int left, int right, const int pos, const int val) {
if (left == right) {
segTree[node] = val;
}
else {
int mid = (left + right) / 2;
if (pos <= mid) {
update(2 * node, left, mid, pos, val);
}
else {
update(2 * node + 1, mid + 1, right, pos, val);
}
segTree[node] = max(segTree[2 * node], segTree[2 * node + 1]);
}
}
int query(int node, int left, int right, const int leftQuery, const int rightQuery) {
if (leftQuery <= left && right <= rightQuery) {
return segTree[node];
}
else {
int mid = (left + right) / 2;
int ans = -INF;
if (leftQuery <= mid) {
ans = max(ans, query(2 * node, left, mid, leftQuery, rightQuery));
}
if (rightQuery >= mid + 1) {
ans = max(ans, query(2 * node + 1, mid + 1, right, leftQuery, rightQuery));
}
return ans;
}
}
int main() {
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int N, M;
fin >> N >> M;
a = vector<int>(N);
segTree = vector<int>(4 * N);
for (int i = 0; i < N; ++i) {
fin >> a[i];
}
build(1, 0, N - 1);
for (int i = 0; i < M; ++i) {
int op, x, y;
fin >> op >> x >> y;
if (op == 0) {
fout << query(1, 0, N - 1, x - 1, y - 1) << "\n";
}
else {
update(1, 0, N - 1, x - 1, y);
}
}
fin.close();
fout.close();
return 0;
}