#include <fstream>
#include <vector>
void build(const int a, const int b, const std::vector<int> &v, std::vector<int> &it, const int index = 0)
{
if(a == b)
{
it[index] = v[a];
return;
}
const int mid = (a + b) / 2;
build(a, mid, v, it, 2*index + 1);
build(mid + 1, b, v, it, 2*index + 2);
it[index] = std::max(it[2*index + 1], it[2*index + 2]);
}
void update(const int pos, const int val, const int a, const int b, std::vector<int> &it, const int index = 0)
{
if(a == b)
{
it[index] = val;
return;
}
int mid = (a + b) / 2;
if(pos <= mid)
update(pos, val, a, mid, it, 2*index + 1);
else
update(pos, val, mid + 1, b, it, 2*index + 2);
it[index] = std::max(it[2*index + 1], it[2*index + 2]);
}
int query(const int qA, const int qB, const int a, const int b, const std::vector<int> &it, const int index = 0)
{
if(qA <= a && b <= qB)
return it[index];
const int mid = (a + b) / 2;
if(qB <= mid)
return query(qA, qB, a, mid, it, 2*index + 1);
if(qA > mid)
return query(qA, qB, mid + 1, b, it, 2*index + 2);
return std::max(query(qA, qB, a, mid, it, 2*index + 1), query(qA, qB, mid + 1, b, it, 2*index + 2));
}
int main()
{
std::ifstream in("arbint.in");
std::ofstream out("arbint.out");
int n, m; in >> n >> m;
std::vector v(n, 0);
for (int i = 0; i < n; ++i)
in >> v[i];
std::vector intervalTree(4*n + 66, 0);
build(0, n - 1, v, intervalTree);
for(int ii = 0; ii < m; ii++)
{
int t, a, b; in >> t >> a >> b;
if(t == 1)
update(a - 1, b, 0, n - 1, intervalTree);
else
out << query(a - 1, b - 1, 0, n - 1, intervalTree) << '\n';
}
in.close();
out.close();
return 0;
}