// https://infoarena.ro/problema/arbint
#include <iostream>
#include <fstream>
#include <assert.h>
#include <vector>
using namespace std;
// Functia actualizeaza valoarea unui element in arborele de intervale
void Update(unsigned int node, unsigned int start, unsigned int end, unsigned int idx, unsigned int value, unsigned int* tree) {
if (start == end) {
// Am ajuns la frunza
tree[node] = value;
}
else {
unsigned int mid = (start + end) / 2;
if (idx <= mid) {
// Actualizam subarborele stang
Update(2 * node, start, mid, idx, value, tree);
}
else {
// Actualizam subarborele drept
Update(2 * node + 1, mid + 1, end, idx, value, tree);
}
// Recalculam valoarea maxima pentru nodul curent
tree[node] = max(tree[2 * node], tree[2 * node + 1]);
}
}
// Functia interogheaza arborele de intervale pentru a gasi maximul in intervalul [l, r]
void Query(unsigned int node, unsigned int start, unsigned int end, unsigned int l, unsigned int r, unsigned int* tree, unsigned int& result) {
if (l > end || r < start) {
// Intervalul curent nu se intersecteaza cu [l, r]
return;
}
if (l <= start && end <= r) {
// Intervalul curent este inclus in [l, r]
result = max(result, tree[node]);
return;
}
unsigned int mid = (start + end) / 2;
Query(2 * node, start, mid, l, r, tree, result);
Query(2 * node + 1, mid + 1, end, l, r, tree, result);
}
int main() {
ifstream fin("arbint.in");
ofstream fout("arbint.out");
if (!fin.is_open() || !fout.is_open()) {
cerr << "Eroare la deschiderea fisierelor!" << endl;
return 1;
}
unsigned int M, N;
fin >> N >> M;
assert(M >= 1 && N <= 100000);
vector<unsigned int> tree(4 * N, 0); // Arborele de intervale pentru maxim
for (unsigned int i = 0; i < N; i++) {
unsigned int a;
fin >> a;
assert(a <= 1000000000);
Update(1, 1, N, i + 1, a, tree.data()); // Actualizam arborele de intervale
}
for (unsigned int i = 0; i < M; i++) {
unsigned int op, a, b;
fin >> op >> a >> b;
if (op == 0) {
assert(a >= 1 && b <= N && a <= b);
unsigned int result = 0; // Variabila pentru a stoca maximul
Query(1, 1, N, a, b, tree.data(), result);
fout << result << endl; // Afisam maximul pentru intervalul [a, b]
}
else {
assert(op == 1 && a >= 1 && a <= N && b >= 1 && b <= 1000000000);
// Actualizam valoarea elementului de pe pozitia a
Update(1, 1, N, a, b, tree.data());
}
}
fin.close();
fout.close();
return 0;
}