#include <vector>
#include <cassert>
#ifdef CLI
#include <iostream>
#else
#include <fstream>
#endif
struct segment {
const int left, right;
segment(int l, int r) : left(l), right(r) {}
segment(int l, int r, bool x) : segment(l, r) { assert(l < r); }
inline int mid() const { return (right - left) / 2 + left; }
inline int size() const { return right - left; }
inline bool isUnit() const { return (right - left) == 1; }
std::pair<segment, segment> splitMid() const {
const int middle = mid();
return { segment(left, middle), segment(middle, right) };
}
};
typedef int T;
std::vector<T> store;
T op(T a, T b) { return a < b ? b : a; }
void modify(const int position, const int x, const int id, const segment seg) {
if(seg.isUnit()) {
store[id] = x; return;
}
position < seg.mid() ?
modify(position, x, 2 * id, segment(seg.left, seg.mid())) :
modify(position, x, 2 * id + 1, segment(seg.mid(), seg.right));
store[id] = op(store[id * 2], store[id * 2 + 1]);
}
T query(const segment target, const int id, const segment seg) {
if(target.left >= seg.right || target.right <= seg.left) return 0;
if(target.left <= seg.left && target.right >= seg.right) return store[id];
const auto s = seg.splitMid();
return op(query(target, id * 2, s.first), query(target, id * 2 + 1, s.second));
}
//void printv(std::ostream& out, std::vector<T>& collection) { for(auto& i : collection) out << i << ' '; out << '\n'; }
int main() {
#ifdef CLI
std::istream& in = std::cin;
std::ostream& out = std::cout;
#else
std::ifstream ________a ("arbint.in");
std::ofstream ________b ("arbint.out");
std::istream& in = ________a;
std::ostream& out = ________b;
#endif
int n, q; in >> n >> q;
store = std::vector<T>(4 * n + 5, 0);
for(int i = 0; i < n; i++) {
int x; in >> x;
modify(i, x, 1, {0, n});
}
while(q--) {
int type, a, b; in >> type >> a >> b;
a--;
if(type == 0) { out << query({a, b}, 1, {0, n}) << '\n'; }
else { modify(a, b, 1, {0, n}); }
//printv(out, store); out << std::flush;
}
out << std::flush;
return 0;
}