#include <algorithm>
#include <fstream>
#include <iostream>
#include <limits>
#include <vector>
template <class T>
class segment_tree {
public:
explicit segment_tree(int size);
explicit segment_tree(const std::vector<T>& init_data);
void update(int left, int right, T value);
T query(int left, int right) const;
private:
void _init(int node, int left, int right, const std::vector<T>& init_data);
void _update(int node, int left, int right, int x, int y, T value);
T _query(int node, int left, int right, int x, int y) const;
int size;
std::vector<T> tree;
};
template <class T>
segment_tree<T>::segment_tree(int _size): size(_size) {
tree.resize(4 * _size + 10);
}
template <class T>
segment_tree<T>::segment_tree(const std::vector<T>& init_data): size(init_data.size()) {
tree.resize(4 * init_data.size() + 10);
_init(1, 1, init_data.size(), init_data);
}
template <class T>
void segment_tree<T>::update(int left, int right, T value) {
_update(1, 1, size, left, right, value);
}
template <class T>
T segment_tree<T>::query(int left, int right) const {
return _query(1, 1, size, left, right);
}
template <class T>
void segment_tree<T>::_init(int node, int left, int right, const std::vector<T>& init_data) {
if (left == right) {
tree[node] = init_data[left];
} else {
int mid = left + (right - left) / 2;
_init(2 * node, left, mid, init_data);
_init(2 * node + 1, mid + 1, right, init_data);
tree[node] = std::max(tree[2 * node], tree[2 * node + 1]);
}
}
template <class T>
void segment_tree<T>::_update(int node, int left, int right, int x, int y, T value) {
if (x <= left && right <= y) {
tree[node] = value;
} else {
int mid = left + (right - left) / 2;
if (x <= mid)
_update(2 * node, left, mid, x, y, value);
if (y > mid)
_update(2 * node + 1, mid + 1, right, x, y, value);
tree[node] = std::max(tree[2 * node], tree[2 * node + 1]);
}
}
template <class T>
T segment_tree<T>::_query(int node, int left, int right, int x, int y) const {
if (x <= left && right <= y) {
return tree[node];
} else {
int mid = left + (right - left) / 2;
T value = std::numeric_limits<T>::min();
if (x <= mid)
value = std::max(value, _query(2 * node, left, mid, x, y));
if (y > mid)
value = std::max(value, _query(2 * node + 1, mid + 1, right, x, y));
return value;
}
}
int main()
{
std::ifstream fin("arbint.in");
std::ofstream fout("arbint.out");
int N, M;
fin >> N >> M;
std::vector<int> vec(N + 1);
for (int i = 1; i <= N; ++i)
fin >> vec[i];
segment_tree<int> tree(vec);
for (int i = 0; i < M; ++i) {
int op, a, b;
fin >> op >> a >> b;
if (op == 0) {
fout << tree.query(a, b) << std::endl;
} else {
tree.update(a, a, b);
}
}
return 0;
}