#include <iostream>
#include <fstream>
using namespace std;
const int MAX_N = 100100;
const int INF = 1 << 30;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int segTree[MAX_N * 4];
int v[MAX_N];
void build(int nod, int lo, int hi) {
void update(int nod, int lo, int hi, int a, int b);
int query(int nod, int lo, int hi, int a, int b);
int N, M;
int main() {
fin >> N >> M;
for (int i = 1; i <= N; ++i) {
fin >> v[i];
}
build(1, 1, N);
for (int i = 1; i <= M; ++i) {
int action, a, b;
fin >> action >> a >> b;
if (action == 1) {
update(1, 1, N, a, b);
} else {
fout << query(1, 1, N, a, b) << '\n';
}
}
return 0;
}
void build(int nod, int lo, int hi) {
if (lo == hi) {
segTree[nod] = v[lo];
} else {
int mid = lo + (hi - lo) / 2;
build(nod * 2, lo, mid);
build(nod * 2 + 1, mid + 1, hi);
segTree[nod] = max(segTree[nod*2], segTree[nod*2+1]);
}
}
void update(int nod, int lo, int hi, int a, int b) {
if (lo == hi) {
segTree[nod] = b;
} else {
int mid = lo + (hi - lo) / 2;
if (a <= mid) {
update(nod * 2, lo, mid, a, b);
} else {
update(nod * 2 + 1, mid + 1, hi, a, b);
}
segTree[nod] = max(segTree[nod*2], segTree[nod*2+1]);
}
}
int query(int nod, int lo, int hi, int a, int b) {
if (a <= lo && b >= hi) {
return segTree[nod];
}
int result = 0;
int mid = lo + (hi - lo) / 2;
if (a <= mid) {
result = max(result, query(nod * 2, lo, mid, a, b));
}
if (b > mid) {
result = max(result, query(nod * 2 + 1, mid + 1, hi, a, b));
}
return result;
}