#include<iostream>
#include<fstream>
#define dim 100001
using namespace std;
ifstream f("arbint.in");
ofstream g("arbint.out");
inline int max(int a, int b) {
if (a < b)
return b;
return a;
}
void update(int nod, int left, int right, int *arr, int pos, int val) {
if (left == right) {
arr[nod] = val;
return;
}
int mid = (left + right) / 2;
if (pos <= mid) update(nod * 2, left, mid, arr, pos, val);
else update(nod * 2 + 1, mid + 1, right, arr, pos, val);
arr[nod] = max(arr[2 * nod], arr[2 * nod + 1]);
}
void query(int nod, int left, int right, int *arr, int a, int b, int &maxim) {
if (a <= left && right <= b) {
if (maxim < arr[nod])
maxim = arr[nod];
return;
}
int mid = (left + right) / 2;
if (a <= mid) query(2 * nod, left, mid, arr, a, b, maxim);
if (mid < b) query(2 * nod + 1, mid + 1, right, arr, a, b, maxim);
}
int main() {
int N, M, pos, val, X;
int *arr = new int[5 * dim];
f >> N >> M;
for (int i = 1; i <= N; i++) {
//propagam valorile la baza arborelui si alegem maximul de jos in sus pana la radacina
f >> X;
update(1, 1, N, arr, i, X);
}
for (int i = 1; i <= M; i++) {
f >> X;
if (X == 1) {
f >> pos >> val;
update(1, 1, N, arr, pos, val);
}
else {
int a, b;
f >> a >> b;
int maxim = -1;
query(1, 1, N, arr, a, b, maxim);
g << maxim << endl;
}
}
/*for (int i = 1; i <= 4 * N; i++)
cout << arr[i] << " ";*/
//system("Pause");
return 0;
}