#include <fstream>
#include <cstring>
using namespace std;
ifstream f ("arbint.in");
ofstream g ("arbint.out");
const int Dim = 1e5 + 5;
int a[Dim], tree[4 * Dim];
int n, m;
int type, x, y;
void BuildTree (int node, int inc, int sf) {
if (inc == sf) {
tree[node] = a[inc];
return;
}
int mid = (inc + sf) / 2;
BuildTree (2 * node, inc, mid);
BuildTree (2 * node + 1, mid + 1, sf);
tree[node] = max (tree[2 * node], tree[2 * node + 1]);
}
int QueryTree (int node, int inc, int sf, int a, int b) {
if (inc > sf || a > sf || b < inc) {
return 0;
}
if (a <= inc && sf <= b) {
return tree[node];
}
int mid = (inc + sf) / 2;
int q1 = QueryTree (2 * node, inc, mid, a, b);
int q2 = QueryTree (2 * node + 1, mid + 1, sf, a, b);
return max (q1, q2);
}
void UpdateTree (int node, int inc, int sf, int pos, int val) {
if (inc > sf || inc > pos || sf < pos) {
return;
}
if (inc == sf && inc == pos) {
tree[node] = val;
return;
}
int mid = (inc + sf) / 2;
UpdateTree (2 * node, inc, mid, pos, val);
UpdateTree (2 * node + 1, mid + 1, sf, pos, val);
tree[node] = max (tree[2 * node], tree[2 * node + 1]);
}
int main() {
f >> n >> m;
for (int i = 1; i <= n; ++ i) {
f >> a[i];
}
BuildTree (1, 1, n);
for (int i = 1; i <= m; ++ i) {
f >> type >> x >> y;
if (type == 0) {
g << QueryTree (1, 1, n, x, y) << "\n";
}
else {
UpdateTree (1, 1, n, x, y);
}
}
return 0;
}