#include <iostream>
#include <fstream>
#include <limits>
#include <vector>
using namespace std;
using A = int;
A op(A x, A y) {
return max(x, y);
}
A neutru = numeric_limits<int>::min();
struct Aint {
Aint(int size): size(size), data(4 * size, neutru) {}
void update(int p, A v) { update(1, 0, size, p, v); }
void update(int node, int b, int e, int p, A v) {
if (e - b == 1) {
data[node] = v;
// sau data[node] = op(data[node], v)
return;
}
int m = (b + e) / 2;
if (p < m)
update(node * 2, b, m, p, v);
else
update(node * 2 + 1, m, e, p, v);
data[node] = op(data[node * 2], data[node * 2 + 1]);
}
A query(int s, int f) { return query(1, 0, size, s, f); }
A query(int node, int b, int e, int s, int f) {
if (s <= b && e <= f)
return data[node];
int m = (b + e) / 2;
A ret = neutru;
if (s < m)
ret = query(node * 2, b, m, s, f);
if (m < f)
ret = op(ret, query(node * 2 + 1, m, e, s, f));
return ret;
}
int size;
vector<A> data;
};
int main() {
ifstream cin("arbint.in");
ofstream cout("arbint.out");
int N, M; cin >> N >> M;
Aint A(N);
for (int i = 0; i < N; ++i) {
int x; cin >> x;
A.update(i, x);
}
for (int i = 0; i < M; ++i) {
int type, a, b; cin >> type >> a >> b;
if (type == 1)
A.update(a - 1, b);
else
cout << A.query(a - 1, b) << "\n";
}
}