#include <bits/stdc++.h>
using namespace std;
#define INFILE "arbint.in"
#define OUTFILE "arbint.out"
struct Node {
public:
int value;
Node() : value(0) {}
Node(int _value) : value(_value) {}
};
Node compareNodes(Node a, Node b) {
return (a.value > b.value ? a : b);
}
struct SegmentTree {
public:
int n;
vector<Node> aint;
SegmentTree() {}
SegmentTree(int _n) : n(_n) {
aint.resize(4 * (_n + 1) + 1, Node(0));
}
void update(int position, Node value) {
update(1, 1, n, position, value);
}
Node query(int queryLeft, int queryRight) {
return query(1, 1, n, queryLeft, queryRight);
}
private:
void update(int node, int left, int right, int position, Node value) {
if (left == right) {
aint[node] = value;
return;
}
int middle = (left + right) >> 1;
if (position <= middle) update((1 << node), left, middle, position, value);
else update((1 << node | 1), middle + 1, right, position, value);
aint[node] = compareNodes(aint[(1 << node)], aint[(1 << node | 1)]);
}
Node query(int node, int left, int right, int queryLeft, int queryRight) {
if (left >= queryLeft && right <= queryRight) return aint[node];
int middle = (left + right) >> 1;
if (queryRight <= middle) return query((1 << node), left, middle, queryLeft, queryRight);
else if (queryLeft > middle) return query((1 << node | 1), middle + 1, right, queryLeft, queryRight);
return compareNodes(
query((1 << node), left, middle, queryLeft, queryRight),
query((1 << node | 1), middle + 1, right, queryLeft, queryRight)
);
}
};
void solve() {
int n, queries; cin >> n >> queries;
SegmentTree aint(n);
for (int i = 1; i <= n; ++i) {
int aux; cin >> aux;
aint.update(i, Node(aux));
}
while (queries--) {
bool type; cin >> type;
int a, b; cin >> a >> b;
if (!type) cout << aint.query(a, b).value << '\n';
else aint.update(a, Node(b));
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
freopen(INFILE, "r", stdin);
freopen(OUTFILE, "w", stdout);
solve();
return 0;
}