//
// Created by Vlad Nitu on 11.02.2023.
//
#include <bits/stdc++.h>
using namespace std;
#define NMAX (int)(100001)
#define INF (int)(1e9)
#define ll long long
#define mkp make_pair
#define mkt make_tuple
#define lsb(x) (x & -x)
int N, Q;
int T[4 * NMAX + 1];
// A[pos] = val
void update(int pos, int val, int node = 1, int node_lb = 1, int node_ub = N) { // update(pos, val)
if (node_lb == node_ub) T[node] = val;
else {
int mij = (node_lb + node_ub) / 2;
if (pos <= mij)
update(pos, val, node * 2, node_lb, mij);
else
update(pos, val, node * 2 + 1, mij + 1, node_ub);
T[node] = max(T[node * 2], T[node * 2 + 1]);
}
}
// max(a[i]), i in [a,b]
int query(int a, int b, int node = 1, int node_lb = 1, int node_ub = N) { // query(a, b)
int x1 = -1, x2 = -1;
if (a <= node_lb && b >= node_ub) return T[node];
else {
int mid = (node_lb + node_ub) / 2;
if (a <= mid)
x1 = query(a, b, node * 2, node_lb, mid);
if (b >= mid + 1)
x2 = query(a, b, node * 2 + 1, mid + 1, node_ub);
return max(x1, x2);
}
}
int x;
int task, a, b;
int main() {
freopen("arbint.in", "r", stdin);
freopen("arbint.out", "w", stdout);
cin >> N >> Q;
for (int i = 1; i <= N; ++i) {
cin >> x;
update(i, x); // A[i] = x
}
while (Q--) {
cin >> task >> a >> b;
if (task == 0)
cout << query(a, b) // Max on range [a, b]
<< '\n';
else
update(a, b); // A[a] = b
}
return 0;
}