#include <bits/stdc++.h>
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
template <typename T> class SegTree {
vector <T> t; int n, h; T id;
function <T(T, T)> f;
void build(int l, int r, int ind, vector <T>& v) {
int med = (l + r) >> 1;
if(l == r) t[ind] = v[l];
else { build(l, med, ind << 1, v); build(med + 1, r, ind << 1 | 1, v); t[ind] = f(t[ind << 1], t[ind << 1 | 1]); }
}
void u(int pos, int tl, int tr, int ind, int val) {
if(pos < tl || pos > tr) return;
if(tl == tr && pos == tl) {t[ind] = val; return;}
int tm = (tl + tr) >> 1;
if(pos <= tm) u(pos, tl, tm, ind << 1, val);
else u(pos, tm + 1, tr, ind << 1 | 1, val);
t[ind] = f(t[ind << 1], t[ind << 1 | 1]);
}
T q(int l, int r, int tl, int tr, int ind) {
if(tl > r || l > tr) return id;
if(l <= tl && r >= tr) return t[ind];
int tm = (tl + tr) >> 1;
return f(q(l, r, tl, tm, ind << 1), q(l, r, tm + 1, tr, ind << 1 | 1));
}
public:
template <typename Iterator> SegTree(Iterator op, Iterator ed, T _id, function <T(T, T)> _f) : id(_id), n(ed - op), h(31 - __builtin_clz(n)), f(_f) {
vector <T> init(n);
for(Iterator it = op; it != ed; it++) init[it - op] = *it;
t.resize(1 << (h + 2), id); build(0, n - 1, 1, init);
}
void update(int pos, T val) {u(pos, 0, n - 1, 1, val);}
T query(int l, int r) { /// indexat de la 0 pe intervalul [l, r]
return q(l, r, 0, n - 1, 1);
}
};
int main()
{
vector <int> v;
int n, q, l, r, t;
fin >> n >> q; v.resize(n);
for(int i = 0; i < n; i++) fin >> v[i];
SegTree <int> S(v.begin(), v.end(), 0, [](int a, int b){return a > b ? a : b;});
for(int i = 0; i < q; i++) {
fin >> t >> l >> r;
if(t) S.update(l - 1, r);
else fout << S.query(l - 1, r - 1) << "\n";
}
return 0;
}