#include <iostream>
#include <fstream>
using namespace std;
#define MAX 100001
ifstream in("arbint.in");
ofstream out("arbint.out");
int tree[4 * MAX + 5];
int V[MAX + 5];
void build(int node, int le, int ri)
{
if (le == ri)
{
tree[node] = V[le];
return;
}
int mid = (le + ri) / 2;
build(2 * node, le, mid);
build(2 * node + 1, mid + 1, ri);
tree[node] = max(tree[2 * node], tree[2 * node + 1]);
}
void query(int node, int le, int ri, int x, int y, int &ans)
{
if (x <= le && ri <= y)
{
ans = max(ans, tree[node]);
return;
}
int mid = (le + ri) / 2;
if (x <= mid)
{
query(2 * node, le, mid, x, y, ans);
}
if (y > mid)
{
query(2 * node + 1, mid + 1, ri, x, y, ans);
}
}
void update(int node, int le, int ri, int pos, int val)
{
if (le == ri)
{
tree[node] = val;
return;
}
int mid = (le + ri) / 2;
if (pos <= mid)
{
update(2 * node, le, mid, pos, val);
}
else
{
update(2 * node + 1, mid + 1, ri, pos, val);
}
tree[node] = max(tree[2 * node], tree[2 * node + 1]);
}
int main()
{
int N, M;
in >> N >> M;
for (int i = 1; i <= N; i++)
{
in >> V[i];
}
// for (int i = 0; i < N; i++)
// {
// out << V[i] << " " << endl;
// }
build(1, 1, N);
int ans = 0;
// query(1, 1, 5, 1, 3, ans);
// out << "ans=" << ans << endl;
// for (int i = 0; i < 10; i++)
// {
// out << "tree[" << i << "]=" << tree[i] << endl;
// }
int op, a, b;
for (int i = 0; i < M; i++)
{
ans = 0;
in >> op >> a >> b;
// out << op << " " << a << " " << b << endl;
if (op == 0)
{
query(1, 1, N, a, b, ans);
out << ans << endl;
}
else
{
update(1, 1, N, a, b);
// for (int i = 0; i < 10; i++)
// {
// out << "tree[" << i << "]=" << tree[i] << endl;
// }
}
}
}