#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
ifstream in("arbint.in");
ofstream out("arbint.out");
void build(int node, int left, int right, vector<int> &tree, vector<int> &v)
{
if (left == right)
tree[node] = v[left];
else
{
int mij = (left + right) / 2;
build(node * 2, left, mij, tree, v);
build(node * 2 + 1, mij + 1, right, tree, v);
tree[node] = max(tree[node * 2], tree[node * 2 + 1]);
}
}
void update(int node, int left, int right, vector<int> &tree, int pos, int value)
{
if (left == right)
tree[node] = value;
else
{
int mij = (left + right) / 2;
if (pos <= mij)
update(node * 2, left, mij, tree, pos, value);
else
update(node * 2 + 1, mij + 1, right, tree, pos, value);
tree[node] = max(tree[node * 2], tree[node * 2 + 1]);
}
}
int querry(int node, int left, int right, int q_left, int q_right, vector<int> &tree)
{
if (q_left <= left && right <= q_right)
return tree[node];
else
{
int mij = (left + right) / 2;
if (q_right <= mij)
return querry(node * 2, left, mij, q_left, q_right, tree);
if (q_left > mij)
return querry(node * 2 + 1, mij + 1, right, q_left, q_right, tree);
return max(querry(node * 2, left, mij, q_left, q_right, tree),
querry(node * 2 + 1, mij + 1, right, q_left, q_right, tree));
}
}
int main()
{
int n, T;
in>> n >> T;
vector<int> v(n + 1), tree(2 * n - 1, 0);
for (int i = 1; i <= n; i++)
in>> v[i];
build(1, 1, n, tree, v);
for (int test = 0; test < T; test++)
{
int cer, a, b;
in>> cer >> a >> b;
if (cer == 0)
out<< querry(1, 1, n, a, b, tree) << "\n";
else
update(1, 1, n, tree, a, b);
}
return 0;
}