#include <algorithm>
#include <fstream>
#include <limits.h>
// Tree nodes are 1-indexed.
const size_t MAX_MN = 100000 + 1;
int N, M, A[MAX_MN];
int T[4 * MAX_MN], T0, T1;
void update(int *T, int root, int left, int right, int pos, int val)
{
if (left == right) {
T[root] = val;
return;
}
int mid = left + (right - left) / 2;
if (pos <= mid)
update(T, 2 * root, left, mid, pos, val);
else
update(T, 2 * root + 1, mid + 1, right, pos, val);
T[root] = std::max(T[2 * root], T[2 * root + 1]);
}
int query(int *T, int root, int left, int right, int start, int stop)
{
if (start <= left && right <= stop)
return T[root];
int ret = -INT_MIN;
int mid = left + (right - left) / 2;
if (start <= mid)
ret = std::max(ret, query(T, 2 * root, left, mid, start, stop));
if (mid < stop)
ret = std::max(ret, query(T, 2 * root + 1, mid + 1, right, start, stop));
return ret;
}
int main()
{
std::ifstream fin("arbint.in");
std::ofstream fout("arbint.out");
fin >> N >> M;
for (int i = 1; i <= N; ++i) {
int x;
fin >> x;
update(T, 1, 1, N, i, x);
}
for (int i = 0; i < M; ++i) {
int t, a, b;
fin >> t >> a >> b;
if (t == 0)
fout << query(T, 1, 1, N, a, b) << '\n';
else
update(T, 1, 1, N, a, b);
}
return 0;
}