#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 val, int query_left, int query_right)
{
// disjoint
if (query_right < node_left || node_right < query_left)
return aint[index];
// not disjoint and leaf node
if (node_left == node_right)
{
aint[index] = val;
return val;
}
// overlapping
int m = node_left + (node_right - node_left) / 2;
return (aint[index] = max(
update(index * 2, node_left, m, x, query_left, query_right),
update(index * 2 + 1, m + 1, node_right, x, query_left, query_right)));
}
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;
if (node_left == node_right)
return aint[index];
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, x, i, i);
while (m--)
{
f >> t >> a >> b;
if (t)
update(1, 1, n, b, a, a);
else
g << query(1, 1, n, a, b) << '\n';
}
return 0;
}