#include<bits/stdc++.h>
using namespace std;
#define dbg(x) (cout<<#x<<" = "<<(x)<<'\n')
typedef long long int lld;
const int INF = (1LL << 30) - 1;
const lld LINF = (1LL << 62) - 1;
const int NMAX = 100000 + 5;
template<typename T>
class SegmentTree {
private:
vector<T> AI;
int N;
void update(int nod, int lo, int hi, int poz, T& val) {
if (lo == hi) {
AI[nod] = val;
return;
}
int mi = (lo + hi) / 2;
if (poz <= mi)
update(2 * nod + 0, lo, mi + 0, poz, val);
else
update(2 * nod + 1, mi + 1, hi, poz, val);
AI[nod] = max(AI[2 * nod + 0], AI[2 * nod + 1]);
}
T query(int nod, int lo, int hi, int L, int R) {
if (L <= lo && hi <= R)
return AI[nod];
if (R < lo || hi < L)
return -1;
int mi = (lo + hi) / 2;
T q1 = query(2 * nod + 0, lo, mi + 0, L, R);
T q2 = query(2 * nod + 1, mi + 1, hi, L, R);
return max(q1, q2);
}
template<typename U>
void build(int nod, int lo, int hi, U& V) {
if (lo == hi) {
AI[nod] = V[lo];
return;
}
int mi = (lo + hi) / 2;
build(2 * nod + 0, lo, mi + 0, V);
build(2 * nod + 1, mi + 1, hi, V);
AI[nod] = max(AI[2 * nod + 0], AI[2 * nod + 1]);
}
public:
SegmentTree() {}
SegmentTree(int N) {
this->N = N;
AI.resize(4 * N + 20);
}
template<typename U>
SegmentTree(int N, U& V) {
this->N = N;
AI.resize(4 * N + 20);
build(1, 1, N, V);
}
void update(int position, T& value) {
update(1, 1, N, position, value);
}
T query(int left, int right) {
return query(1, 1, N, left, right);
}
int size() {
return N;
}
};
SegmentTree<int> A;
int N, M;
int V[NMAX];
int main() {
int t, x, y;
freopen("arbint.in", "r", stdin);
freopen("arbint.out", "w", stdout);
scanf("%d%d", &N, &M);
for (int i = 1; i <= N; i++)
scanf("%d", &V[i]);
A = SegmentTree<int>(N, V);
while (M--) {
scanf("%d%d%d", &t, &x, &y);
if (t == 0)
printf("%d\n", A.query(x, y));
else
A.update(x, y);
}
return 0;
}