#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
struct Nod {
int stanga;
int dreapta;
int valoareMaxima;
};
vector<Nod> arboreSegment;
void construiesteArboreSegment(const vector<int>& A, int nod, int stanga, int dreapta) {
if (stanga == dreapta) {
arboreSegment[nod].stanga = stanga;
arboreSegment[nod].dreapta = dreapta;
arboreSegment[nod].valoareMaxima = A[stanga];
return;
}
int mijloc = (stanga + dreapta) / 2;
construiesteArboreSegment(A, 2 * nod, stanga, mijloc);
construiesteArboreSegment(A, 2 * nod + 1, mijloc + 1, dreapta);
arboreSegment[nod].stanga = stanga;
arboreSegment[nod].dreapta = dreapta;
arboreSegment[nod].valoareMaxima = max(arboreSegment[2 * nod].valoareMaxima, arboreSegment[2 * nod + 1].valoareMaxima);
}
int interogareValoareMaxima(int nod, int stanga, int dreapta, int a, int b) {
if (stanga > b || dreapta < a)
return 0;
if (stanga >= a && dreapta <= b)
return arboreSegment[nod].valoareMaxima;
int mijloc = (stanga + dreapta) / 2;
int stangaMax = interogareValoareMaxima(2 * nod, stanga, mijloc, a, b);
int dreaptaMax = interogareValoareMaxima(2 * nod + 1, mijloc + 1, dreapta, a, b);
return max(stangaMax, dreaptaMax);
}
void actualizareValoare(int nod, int stanga, int dreapta, int pozitie, int valoare) {
if (stanga == dreapta && stanga == pozitie) {
arboreSegment[nod].valoareMaxima = valoare;
return;
}
int mijloc = (stanga + dreapta) / 2;
if (pozitie <= mijloc)
actualizareValoare(2 * nod, stanga, mijloc, pozitie, valoare);
else
actualizareValoare(2 * nod + 1, mijloc + 1, dreapta, pozitie, valoare);
arboreSegment[nod].valoareMaxima = max(arboreSegment[2 * nod].valoareMaxima, arboreSegment[2 * nod + 1].valoareMaxima);
}
int main() {
ifstream f("arbint.in");
ofstream g("arbint.out");
int N, M;
f >> N >> M;
vector<int> V(N + 1);
for (int i = 1; i <= N; i++) {
f>> V[i];
}
arboreSegment.resize(4 * N); // Redimensionează arborele de segmente pentru a permite nodurile necesare
construiesteArboreSegment(V, 1, 1, N); // Construiește arborele de segmente
for (int i = 1; i <= M; i++) {
int operatie, a, b;
f >> operatie >> a >> b;
if (operatie == 0) {
int valoareMaxima = interogareValoareMaxima(1, 1, N, a, b);
g<< valoareMaxima << endl;
} else if (operatie == 1) {
actualizareValoare(1, 1, N, a, b);
}
}
f.close();
g.close();
return 0;
}