#include "bits/stdc++.h"
#include <cassert>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using pi = pair<int, int>;
using pll = pair<ll, ll>;
using pd = pair<double, double>;
using pld = pair<ld, ld>;
// #define LOCAL
#ifdef LOCAL
ifstream cin("input.txt");
ofstream cout("output2.txt");
#else
ifstream cin("arbint.in");
ofstream cout("arbint.out");
#endif
vector<int> arr, segtree;
inline int merge(const int nr1, const int nr2)
{
return max(nr1, nr2);
}
inline int build(const int vertex_idx, const int node_left, const int node_right)
{
if (node_left == node_right)
{
segtree[vertex_idx] = arr[node_left];
return segtree[vertex_idx];
}
const int m = node_left + (node_right - node_left) / 2;
segtree[vertex_idx] = merge(build(2 * vertex_idx, node_left, m), build(2 * vertex_idx + 1, m + 1, node_right));
return segtree[vertex_idx];
}
inline int max_query(const int vertex_idx, const int node_left, const int node_right, const int query_left, const int query_right)
{
if (query_left > query_right)
{
return 0;
}
if (tie(node_left, node_right) == tie(query_left, query_right))
{
return segtree[vertex_idx];
}
const int m = node_left + (node_right - node_left) / 2;
return merge(max_query(2 * vertex_idx, node_left, m, query_left, min(m, query_right)),
max_query(2 * vertex_idx + 1, m + 1, node_right, max(m + 1, query_left), query_right));
}
inline int update_query(const int vertex_idx, const int node_left, const int node_right, const int query_pos, const int query_new_val)
{
if (node_left == node_right)
{
segtree[vertex_idx] = query_new_val;
return segtree[vertex_idx];
}
const int m = node_left + (node_right - node_left) / 2;
if (query_pos <= m)
{
segtree[vertex_idx] = merge(update_query(2 * vertex_idx, node_left, m, query_pos, query_new_val), segtree[2 * vertex_idx + 1]);
}
else
{
segtree[vertex_idx] = merge(segtree[2 * vertex_idx], update_query(2 * vertex_idx + 1, m + 1, node_right, query_pos, query_new_val));
}
return segtree[vertex_idx];
}
int main()
{
int N, M;
::cin >> N >> M;
arr.resize(N);
for (auto &nr : arr)
{
::cin >> nr;
}
segtree.resize(4 * N);
build(1, 0, N - 1);
while (M--)
{
int query_type, a, b;
::cin >> query_type >> a >> b;
if (query_type == 0)
{
--a, --b;
::cout << max_query(1, 0, N - 1, a, b) << "\n";
}
else // query_type == 1
{
--a;
update_query(1, 0, N - 1, a, b);
}
}
}