#include <iostream>
#include <fstream>
using namespace std;
#include <algorithm>
#include <utility>
#include <sstream>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <map>
#include <set>
#include <stack>
#include <chrono>
using namespace std::chrono;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vint;
typedef vector<vint> vvint;
typedef vector<ll> vll;
typedef vector<vll> vvll;
typedef vector<vvll> vvvll;
typedef vector<ull> vull;
typedef vector<vull> vvull;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
typedef pair<ll, ll> pll;
typedef vector<pll> vpll;
#define fs first
#define sc second
#define pb push_back
// forward strict for, most common
#define fors(i, a, n) for (int i = (int) (a); i < (int) (n); ++i)
// forward inclusive for
#define fori(i, a, n) for (int i = (int) (a); i <= (int) (n); ++i)
// backward for, inclusive
#define forb(i, n, a) for (int i = (int) n; i >= a; --i)
struct node {
int x, lr, rr;
node(int x = 0, int lr = 0, int rr = 0) : x(x), lr(lr), rr(rr) {}
};
class Problem {
public:
// levels [0..L-1]
int n, m, L, n2;
//n2 = 2^(L-1);
vector<node> heap;
void solve() {
ifstream ifs("arbint.in");
ofstream ofs("arbint.out");
ifs >> n >> m;
L = (int) log2(n + 1);
if ((1 << L) < n + 1) L++;
n2 = 1 << L;
heap.resize(2 * n2);
fors(i, 0, n)
{
int b;
ifs >> b;
update_heap(n2 + i, b);
}
fill_ranges(1);
// print_heap();
fors(m_, 0, m)
{
int o, a, b;
ifs >> o >> a >> b;
if (o == 1) {
update_heap(n2 + a - 1, b);
// print_heap();
// printf("heap[%d] = %d\n", a, b);
}
else if (o == 0) {
int mab = find_max(a, b);
ofs << mab << "\n";
//printf("max(%d, %d) = %d\n\n", n2 + a - 1, n2 + b - 1, mab);
}
}
}
int find_max(int a, int b)
{
int so = n2 + a - 1, e = n2 + b - 1;
int s = so;
int m = heap[s].x;
while (s <= e)
{
// find a parent
int i = s;
// cout << "s = " << s << ", ";
while (i != 1 && so <= heap[parent(i)].lr && heap[parent(i)].rr <= e) i = parent(i);
m = max(m, heap[i].x);
s = heap[i].rr + 1;
}
return m;
}
void fill_ranges(int i)
{
if (i >= n2) heap[i].lr = heap[i].rr = i;
else {
fill_ranges(chl(i));
fill_ranges(chr(i));
heap[i].lr = heap[chl(i)].lr;
heap[i].rr = heap[chr(i)].rr;
}
}
// i is a leaf node, b is it's value
void update_heap(int i, int b) {
heap[i].x = b;
while (i != 1) {
i = parent(i);
heap[i].x = max(heap[chl(i)].x, heap[chr(i)].x);
}
}
void print_heap() {
fori(l, 0, L)
{
int c = 1 << l;
fors(i, 0, c)
cout << heap[c + i].x << " ";
cout << endl;
}
// cout << endl;
}
// left child
int chl(int i) {
return 2 * i;
}
// right child
int chr(int i) {
return 2 * i + 1;
}
// parent
int parent(int i) {
return i / 2;
}
};
int main() {
Problem p;
p.solve();
return 0;
}