#ifdef __INFOARENA_PROJ
#include "infoarena.h"
#endif
#include <fstream>
#include <algorithm>
#ifdef __INFOARENA_PROJ
namespace arbint {
#endif
const unsigned int nMax = 100000;
template <size_t N> struct log2_
{
enum { value = 1 + log2_<N / 2>::value };
};
template <> struct log2_<1>
{
enum { value = 0 };
};
template <size_t N> struct pow2_
{
enum { value = 2 * pow2_<N - 1>::value };
};
template <> struct pow2_<0>
{
enum { value = 1 };
};
class ArboreDeMax {
public:
ArboreDeMax(unsigned N) : N(N) { }
void adaugare(unsigned index, unsigned val) { _actualizare(1, 1, N, index, val); }
void actualizare(unsigned index, unsigned val) { _actualizare(1, 1, N, index, val); }
unsigned maximInInterval(unsigned a, unsigned b) { return _interogareMax(1, 1, N, a, b); }
private:
unsigned V[pow2_<log2_<nMax>::value + 2>::value + 1], N;
void _actualizare(unsigned nod, unsigned st, unsigned dr, unsigned index, unsigned val)
{
if (st == dr && dr == index)
V[nod] = val;
else
{
unsigned mij = (st + dr) / 2;
if (index <= mij)
_actualizare(2 * nod, st, mij, index, val);
else _actualizare(2 * nod + 1, mij + 1, dr, index, val);
V[nod] = std::max(V[2 * nod], V[2 * nod + 1]);
}
}
unsigned _interogareMax(unsigned nod, unsigned st, unsigned dr, unsigned a, unsigned b)
{
if (st == a && dr == b)
return V[nod];
unsigned mij = (st + dr) / 2;
if (b <= mij)
return _interogareMax(2 * nod, st, mij, a, b);
if (a > mij)
return _interogareMax(2 * nod + 1, mij + 1, dr, a, b);
return std::max(_interogareMax(2 * nod, st, mij, a, mij),
_interogareMax(2 * nod + 1, mij + 1, dr, mij + 1, b));
}
};
int main()
{
std::ifstream in("arbint.in");
std::ofstream out("arbint.out");
unsigned N, M, op, a, b;
in >> N >> M;
ArboreDeMax *A = new ArboreDeMax(N);
for (unsigned i = 1; i <= N; ++i)
{
in >> a;
A->adaugare(i, a);
}
for (unsigned i = 1; i <= M; ++i)
{
in >> op >> a >> b;
if (op == 0)
out << A->maximInInterval(a, b) << '\n';
if (op == 1)
A->actualizare(a, b);
}
return 0;
}
#ifdef __INFOARENA_PROJ
}
#endif