#include <iostream>
#define in "arbint.in"
#define out "arbint.out"
using namespace std;
struct tree{
tree *left;
tree *right;
int st;
int dr;
int val;
};
int Maxim(int a, int b) {
if ( a < b ) {
return b;
}
return a;
}
tree* updateTree(tree *node, int left, int right, int pos, int value) {
if (node == NULL) {
node = new tree;
node->left = NULL;
node->right = NULL;
node->st = left;
node->dr = right;
}
if (left==right) {
node->val = value;
return node;
}
int mid = (node->st+node->dr)/2;
if (pos <= mid) {
node->left = updateTree(node->left, node->st, mid, pos, value);
} else {
node->right = updateTree(node->right, mid+1, node->dr, pos, value);
}
int left_value, right_value;
left_value = (node->left == NULL) ? 0 : node->left->val;
right_value = (node->right == NULL) ? 0: node->right->val;
node->val = Maxim(left_value, right_value);
return node;
}
int queryTree(tree *node, int start, int finish, int maxim) {
if (start<= node->st && node->dr <= finish) {
return Maxim(maxim, node->val);
}
int mij = (node->st+node->dr) / 2;
if (start <= mij) {
maxim = queryTree(node->left, start, finish, maxim);
}
if (finish > mij) {
maxim = queryTree(node->right, start, finish, maxim);
}
return maxim;
}
int main(){
int N,M;
int X;
tree *root = NULL;
freopen(in, "r", stdin);
freopen(out, "w", stdout);
scanf("%d%d", &N, &M);
for (int i=1; i<=N; i++) {
scanf("%d", &X);
root = updateTree(root, 1, N, i, X);
}
int a,b;
for (int i=1; i<=M; i++) {
scanf("%d%d%d", &X, &a, &b);
if (!X) {
printf("%d\n", queryTree(root, a, b, -1));
} else {
root = updateTree(root, 1, N, a, b);
}
}
return 0;
}