#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 100001
typedef struct {
int left;
int right;
int max;
} Node;
int max(int a, int b) {
return (a > b) ? a : b;
}
void buildSegmentTree(int *arr, Node *tree, int idx, int start, int end) {
if (start == end) {
tree[idx].left = start;
tree[idx].right = end;
tree[idx].max = arr[start];
return;
}
int mid = (start + end) / 2;
buildSegmentTree(arr, tree, 2 * idx + 1, start, mid);
buildSegmentTree(arr, tree, 2 * idx + 2, mid + 1, end);
tree[idx].left = start;
tree[idx].right = end;
tree[idx].max = max(tree[2 * idx + 1].max, tree[2 * idx + 2].max);
}
int query(Node *tree, int idx, int start, int end, int left, int right) {
if (start > right || end < left) {
return -1; // Intervalul de interogare nu se intersecteaza cu intervalul nodului curent
}
if (left <= start && end <= right) {
return tree[idx].max; // Nodul curent este complet inclus în intervalul de interogare
}
int mid = (start + end) / 2;
int leftMax = query(tree, 2 * idx + 1, start, mid, left, right);
int rightMax = query(tree, 2 * idx + 2, mid + 1, end, left, right);
if (leftMax == -1) return rightMax;
if (rightMax == -1) return leftMax;
return max(leftMax, rightMax);
}
void update(Node *tree, int idx, int start, int end, int pos, int val) {
if (start == end) {
tree[idx].max = val;
return;
}
int mid = (start + end) / 2;
if (pos <= mid) {
update(tree, 2 * idx + 1, start, mid, pos, val);
} else {
update(tree, 2 * idx + 2, mid + 1, end, pos, val);
}
tree[idx].max = max(tree[2 * idx + 1].max, tree[2 * idx + 2].max);
}
int main() {
int N, M;
scanf("%d %d", &N, &M);
int A[MAX_SIZE];
Node tree[4 * MAX_SIZE]; // Segment tree
// Citim elementele vectorului A
for (int i = 0; i < N; i++) {
scanf("%d", &A[i]);
}
// Construim arborele de intervale
buildSegmentTree(A, tree, 0, 0, N - 1);
// Executam operatiile
for (int i = 0; i < M; i++) {
int op, a, b;
scanf("%d %d %d", &op, &a, &b);
if (op == 0) {
// Interogam arborele de intervale pentru a obține maximul din intervalul specificat
int result = query(tree, 0, 0, N - 1, a - 1, b - 1);
printf("%d\n", result);
} else if (op == 1) {
// Actualizam arborele de intervale cu noua valoare a elementului specificat
update(tree, 0, 0, N - 1, a - 1, b);
}
}
return 0;
}