#include <iostream>
#include <fstream>
#include <climits>
#define NMAX 100000
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int n, queries;
int a[NMAX], ST[4 * NMAX];
inline int maxim(int a, int b)
{
return a > b ? a : b;
}
void build(int node, int left, int right)
{
if (left == right) ST[node] = a[left];
else {
int middle = left + (right - left) / 2;
build(2 * node + 1, left, middle);
build(2 * node + 2, middle + 1, right);
ST[node] = maxim(ST[2 * node + 1], ST[2 * node + 2]);
}
}
void update(int i, int val, int node, int left, int right)
{
if (left == right) a[i] = ST[node] = val;
else {
int middle = left + (right - left) / 2;
if (i <= middle) update(i, val, 2 * node + 1, left, middle);
else update(i, val, 2 * node + 2, middle + 1, right);
ST[node] = maxim(ST[2 * node + 1], ST[2 * node + 2]);
}
}
int query(int node, int leftQuery, int rightQuery, int left, int right)
{
if (left > right || leftQuery > right || left > rightQuery) return INT_MIN;
if (left >= leftQuery && right <= rightQuery) return ST[node];
int middle = left + (right - left) / 2;
return maxim(query(2 * node + 1, leftQuery, rightQuery, left, middle),
query(2 * node + 2, leftQuery, rightQuery, middle + 1, right));
}
int main()
{
fin >> n >> queries;
for (int i = 0; i < n; ++i) fin >> a[i];
build(0, 0, n - 1);
int opt, x, y;
while (queries--){
fin >> opt >> x >> y;
if (opt == 0) fout << query(0, x - 1, y - 1, 0, n - 1) << '\n';
else update(x - 1, y, 0, 0, n - 1);
}
fin.close();
fout.close();
return 0;
}