import java.io.*;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
InputReader in = new InputReader(new FileInputStream("arbint.in"));
int N = in.nextInt();
int M = in.nextInt();
int[] array = new int[N];
for (int i = 0; i < N; i++) {
array[i] = in.nextInt();
}
SegmentTree ST = new SegmentTree(array);
PrintWriter out = new PrintWriter(new FileOutputStream("arbint.out"));
while (M --> 0){
int t = in.nextInt();
int x = in.nextInt();
int y = in.nextInt();
if (t == 0)
out.println(ST.query(x - 1, y - 1));
else
ST.update(x - 1, y);
}
out.close();
}
static class SegmentTree {
private static class Node{
int maxim;
Node(int maxim) {
this.maxim = maxim;
}
static Node merge(Node L, Node R){
return new Node(Math.max(L.maxim, R.maxim));
}
static void merge(Node T, Node L, Node R){
T.maxim = Math.max(L.maxim, R.maxim);
}
}
private Node[] tree;
private final int N;
SegmentTree(int N){
tree = new Node[4 * N];
this.N = N;
}
SegmentTree(int[] array){
this(array.length);
build(1, 0, N - 1, array);
}
private void build(int node, int l, int r, int[] array){
if (l == r)
tree[node] = new Node(array[l]);
else{
int m = (l + r) / 2;
build(2 * node, l, m, array);
build(2 * node + 1, m + 1, r, array);
tree[node] = Node.merge(tree[2 * node], tree[2 * node + 1]);
}
}
private void update(int node, int l, int r, int position, int key){
if (l == r)
tree[node].maxim = key;
else{
int m = (l + r) / 2;
if (position <= m)
update(2 * node, l, m, position, key);
else
update(2 * node + 1, m + 1, r, position, key);
Node.merge(tree[node], tree[2 * node], tree[2 * node + 1]);
}
}
private int query(int node, int l, int r, int st_q, int dr_q){
if (st_q <= l && r <= dr_q)
return tree[node].maxim;
else{
int m = (l + r) / 2;
if (st_q <= m && m < dr_q){
int left = query(2 * node, l, m, st_q, dr_q);
int right = query(2 * node + 1, m + 1, r, st_q, dr_q);
return Math.max(left, right);
}
else if (st_q <= m)
return query(2 * node, l, m, st_q, dr_q);
else
return query(2 * node + 1, m + 1, r, st_q, dr_q);
}
}
void update(int position, int newKey){
if (!(0 <= position && position < N)) throw new AssertionError("position : out of bounds in update");
update(1, 0, N - 1, position, newKey);
}
int query(int x, int y){
if (!(0 <= x && x <= y && y < N)) throw new AssertionError("x or y : out of bounds in query");
return query(1, 0, N - 1, x, y);
}
}
static class InputReader{
private BufferedReader reader;
private StringTokenizer tokenizer;
InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 65536);
tokenizer = null;
}
private String nextToken() {
while (tokenizer == null || !tokenizer.hasMoreTokens()){
try {
tokenizer = new StringTokenizer(reader.readLine());
}
catch (IOException e){
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
int nextInt() {
return Integer.parseInt(nextToken());
}
String nextString(){
return nextToken();
}
}
}