#include <iostream>
#include <fstream>
#include <stack>
#include <algorithm>
#include <string>
#include <queue>
#include <vector>
#include <map>
#define MAX 100005
#define VALMIN ((1 << 20) - 1) * -1;
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
void constructTree(int* v, int* tree, int low, int high, int poz) {
if (low == high) {
tree[poz] = v[low];
return;
}
int mid = (low + high) / 2;
constructTree(v, tree, low, mid, poz * 2 + 1);
constructTree(v, tree, mid + 1, high, poz * 2 + 2);
tree[poz] = max(tree[poz * 2 + 1], tree[poz * 2 + 2]);
}
int Query(int* tree, int low, int high, int qLow, int qHigh, int poz) {
if (low >= qLow && high <= qHigh) // total overlap
return tree[poz];
if (qLow > high || qHigh < low) // no overlap
return 0;
int mid = (low + high) / 2;
int t1 = Query(tree, low, mid, qLow, qHigh, poz * 2 + 1);
int t2 = Query(tree, mid + 1, high, qLow, qHigh, poz * 2 + 2);
//fout << t1 << " " << t2 << "\n";
return max(t1, t2);
}
void Update(int* tree, int low, int high, int poz, int a, int b) {
if (low == high) {
tree[poz] = b;
return;
}
int mid = (low + high) / 2;
if (a <= mid)
Update(tree, low, mid, poz * 2 + 1, a, b);
else
Update(tree, mid + 1, high, poz * 2 + 2, a, b);
tree[poz] = max(tree[poz * 2 + 1], tree[poz * 2 + 2]);
}
int v[MAX];
int tree[4 * MAX];
int main() {
int N, M;
fin >> N >> M;
for (int i = 1; i <= N; ++i)
fin >> v[i];
constructTree(v, tree, 1, N, 0);
int tip, a, b;
for (int i = 0; i < M; ++i) {
fin >> tip >> a >> b;
if (tip == 0)
fout << Query(tree, 1, N, a, b, 0) << "\n";
else
Update(tree, 1, N, 0, a, b);
}
fout << "\n";
for (int i = 0; i < 10; ++i)
fout << tree[i] << " ";
return 0;
}