#include <bits/stdc++.h>
using namespace std;
ifstream f("arbint.in");
ofstream g("arbint.out");
int n, m, x, t, a, b;
vector<int> aint;
int update(int index, int node_left, int node_right, int update_index, int val)
{
// not included
if (update_index < node_left || node_right < update_index)
return aint[index];
// included and leaf node
if (node_left == node_right)
{
aint[index] = val;
return val;
}
int m = node_left + (node_right - node_left) / 2;
return (aint[index] = max(
update(index * 2, node_left, m, update_index, val),
update(index * 2 + 1, m + 1, node_right, update_index, val)));
}
int query(int index, int node_left, int node_right, int query_left, int query_right)
{
// node included in query segment - return all
if (query_left <= node_left && node_right <= query_right)
return aint[index];
// query segment not intersecting node segment
if (query_right < node_left || node_right < query_left)
return INT_MIN;
int m = node_left + (node_right - node_left) / 2;
return max(
query(index * 2, node_left, m, query_left, query_right),
query(index * 2 + 1, m + 1, node_right, query_left, query_right));
}
int main()
{
f >> n >> m;
aint.resize(n * 5, INT_MIN);
for (int i = 1; i <= n; ++i)
f >> x,
update(1, 1, n, i, x);
while (m--)
{
f >> t >> a >> b;
if (t)
update(1, 1, n, a, b);
else
g << query(1, 1, n, a, b) << '\n';
}
return 0;
}