#include <bits/stdc++.h>
const int INF = 0x3f3f3f3f;
using namespace std;
vector<int> Arr;
class SegmentTree{
private:
vector<int> range;
int A, B, newX, ans, pos, N;
void update(int li, int lf, int pz)
{
if (li == lf) {
range[pz] = newX;
return;
}
int m = li + ((lf - li) >> 1);
if (pos <= m)
update(li, m, pz << 1);
else
update(m + 1, lf, (pz << 1) | 1);
range[pz] = max(range[pz << 1], range[(pz << 1) | 1]);
}
void build(int li, int lf, int pz)
{
if (li == lf) {
range[pz] = Arr[li];
return;
}
int m = li + ((lf - li) >> 1);
build(li, m, pz << 1);
build(m + 1, lf, (pz << 1) | 1);
range[pz] = max(range[pz << 1], range[(pz << 1) | 1]);
}
void query(int li, int lf, int pz)
{
if (A <= li && lf <= B) {
ans = max(ans, range[pz]);
return;
}
int m = li + ((lf - li) >> 1);
if (A <= m)
query(li, m, pz << 1);
if (m < B)
query(m + 1, lf, (pz << 1) | 1);
}
public:
void update(int value, int position) {
pos = position;
newX = value;
update(1, N, 1);
}
int query(int left, int right) {
ans = -INF;
A = left;
B = right;
query(1, N, 1);
return ans;
}
void build()
{
build(1, N, 1);
}
void init(int n) {
range.resize(4 * n);
N = n;
}
};
SegmentTree t;
int main()
{
freopen("arbint.in", "r", stdin);
freopen("arbint.out", "w", stdout);
int N, M;
scanf("%d%d",&N, &M);
t.init(N);
Arr.resize(N + 1);
for (int i = 1; i <= N; ++i)
scanf("%d", &Arr[i]);
t.build();
for (int i = 1; i <= M; ++i) {
int tip, a, b;
scanf("%d%d%d", &tip, &a, &b);
if (tip == 0) {
printf("%d\n", t.query(a, b));
}
else {
t.update(b, a);
}
}
return 0;
}