#include <bits/stdc++.h>
using namespace std;
int n, m;
int segt[300001];
int v[100001];
void build(int node, int st, int dr) {
if (st == dr) {
segt[node] = v[st];
return;
}
int mid = (st + dr) / 2;
build(2 * node, st, mid);
build(2 * node + 1, mid + 1, dr);
segt[node] = max(segt[2 * node], segt[2 * node + 1]);
}
void update(int elem, int node, int x, int y, int st, int dr) {
if (x > dr || y < st) {
return;
}
if (x <= st && y >= dr) {
segt[node] = elem;
return;
}
int mid = (st + dr) / 2;
update(elem, 2 * node, x, y, st, mid);
update(elem, 2 * node + 1, x, y, mid + 1, dr);
segt[node] = max(segt[2 * node], segt[2 * node + 1]);
}
int query(int node, int x, int y, int st, int dr) {
if (x > dr || y < st) {
return 0;
}
if (x <= st && y >= dr) {
return segt[node];
}
int mid = (st + dr) / 2;
int leftSubtree = query(2 * node, x, y, st, mid);
int rightSubtree = query(2 * node + 1, x, y, mid + 1, dr);
return max(leftSubtree, rightSubtree);
}
int main() {
ifstream cin("arbint.in");
ofstream cout("arbint.out");
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
cin >> v[i];
}
build(1, 1, n);
for (int i = 1; i <= m; ++i) {
int op, x, y;
cin >> op >> x >> y;
if (op == 1) {
update(y, 1, x, x, 1, n);
} else {
cout << query(1, x, y, 1, n) << "\n";
}
}
}