#include <bits/stdc++.h>
using namespace std;
ifstream in("arbint.in");
ofstream out("arbint.out");
typedef long long ll;
typedef unsigned long long ull;
const ll nmx = 100005;
const ll inf = 1<<30;
class segmTree {
private:
ll _valMin[4 * nmx];
ll _valMax[4 * nmx];
ll _nodes;
void _upd(ll left, ll right, ll node, ll pos, ll val, bool MIN) {
if(left == right) {
_valMin[node] = val;
_valMax[node] = val;
}
else {
ll mid = (left + right) / 2;
if(pos <= mid) _upd(left, mid, 2 * node, pos, val, MIN);
else _upd(mid + 1, right, 2 * node + 1, pos, val, MIN);
if(MIN) _valMin[node] = min(_valMin[2 * node], _valMin[2 * node + 1]);
else _valMax[node] = max(_valMax[2 * node], _valMax[2 * node + 1]);
}
}
void _query(ll left, ll right, ll node, ll l, ll r, ll &v, bool MIN) {
if(l <= left && right <= r) {
if(MIN) v = min(v, _valMin[node]);
else v = max(v, _valMax[node]);
}
else {
ll mid = (left + right) / 2;
if(l <= mid) _query(left, mid, 2 * node, l, r, v, MIN);
if(r > mid) _query(mid + 1, right, 2 * node + 1, l, r, v, MIN);
}
}
public:
segmTree(ll n) {
for(int i = 0; i < 4 * nmx; ++i) {
_valMin[i] = 1<<30;
_valMax[i] = 0;
}
_nodes = n;
}
void update(const ll &pos, const ll &val) {
_upd(1, _nodes, 1, pos, val, 0);
_upd(1, _nodes, 1, pos, val, 1);
}
ll queryMin(const ll &left, const ll &right) {
ll mn = 1<<30;
_query(1, _nodes, 1, left, right, mn, 1);
return mn;
}
ll queryMax(const ll &left, const ll &right) {
ll mx = 0;
_query(1, _nodes, 1, left, right, mx, 0);
return mx;
}
};
int main() {
ios::sync_with_stdio(0);
ll N, M, v[nmx];
in>>N>>M;
segmTree tree(N);
for(int i = 1; i <= N; ++i) {
in>>v[i];
tree.update(i, v[i]);
}
while(M--) {
ll op, a, b;
in>>op>>a>>b;
if(op == 0) {
out<<tree.queryMax(a, b)<<"\n\n";
}
else {
tree.update(a, b);
}
}
return 0;
}