#include <algorithm>
#include <fstream>
#include <functional>
#include <vector>
using namespace std;
const int oo = 0x3f3f3f3f;
void update(vector<int>& arb, int N, int x, int val) {
function<void(int, int, int)>
_update = [&](int pos, int st, int dr) {
if (st == dr) {
arb[pos] = val;
return;
}
int mid = st + (dr - st) / 2;
if (x <= mid)
_update(2 * pos, st, mid);
else
_update(2 * pos + 1, mid + 1, dr);
arb[pos] = max(arb[2 * pos], arb[2 * pos + 1]);
};
_update(1, 1, N);
}
int query(vector<int>& arb, int N, int x, int y) {
function<int(int, int, int)>
_query = [&](int pos, int st, int dr) {
if (x <= st && dr <= y) {
return arb[pos];
}
int mid = st + (dr - st) / 2;
int ans = -oo;
if (x <= mid) ans = max(ans, _query(2 * pos, st, mid));
if (y > mid) ans = max(ans, _query(2 * pos + 1, mid + 1, dr));
return ans;
};
return _query(1, 1, N);
}
int main() {
vector<int> arb;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int n, m;
fin >> n >> m;
arb.resize(5 * n);
for (int i = 1; i <= n; ++i) {
int val;
fin >> val;
update(arb, n, i, val);
}
while (m --) {
int choice, a, b;
fin >> choice >> a >> b;
switch(choice) {
case 0:
fout << query(arb, n, a, b) << "\n";
break;
case 1:
update(arb, n, a, b);
break;
}
}
return 0;
}