#include <fstream>
#include <iostream>
#include <vector>
#include <climits>
#include <math.h>
using namespace std;
int m, n, aux, start = 0;
vector<int> original;
vector<vector<int> > operatii;
ifstream infile;
ofstream outfile;
void constructTree (vector<int> &original, vector<int> &arbore, int start, int end, int poz) {
if (start == end) {
arbore[poz] = original[start];
return;
}
int mid = (start + end) / 2;
constructTree(original, arbore, start, mid, poz * 2 + 1);
constructTree(original, arbore, mid + 1, end, poz * 2 + 2);
arbore[poz] = max(arbore[poz * 2 + 1], arbore[poz * 2 + 2]);
}
int findMax (vector<int> &arbore, int a, int b, int start, int end, int poz) {
if (start >= a && b >= end)
return arbore[poz];
if (b < start || a > end)
return INT_MIN;
int mid = (start + end) / 2;
return max(findMax(arbore, a, b, start, mid, poz * 2 + 1), findMax(arbore, a, b, mid + 1, end, poz * 2 + 2));
}
int main() {
infile.open("arbint.in");
outfile.open("arbint.out");
infile >> n >> m;
for (int i = 0; i < n; i ++) {
infile >> aux;
original.push_back(aux);
}
for (int i = 0; i < m; i ++) {
vector<int> linie;
for (int j = 0; j < 3; j ++) {
infile >> aux;
linie.push_back(aux);
}
operatii.push_back(linie);
}
int p = 0;
while (pow(2, p) < original.size())
p ++;
int arb_size = pow(2, p) * 2 - 1;
vector<int> arbore(arb_size);
while (operatii[start][0] == 1) {
original[operatii[start][1]] = operatii[start][2];
start ++;
}
constructTree (original, arbore, 0, original.size() - 1, 0);
for (int i = start; i < m; i ++) {
if (operatii[i][0] == 0)
outfile << findMax(arbore, operatii[i][1] - 1, operatii[i][2] - 1, 0, original.size() - 1, 0) << endl;
else {
arbore.clear();
original[operatii[i][1] - 1] = operatii[i][2];
constructTree (original, arbore, 0, original.size() - 1, 0);
}
}
return 0;
}