#include <fstream>
using namespace std;
#define NMAX 100000
int v[NMAX + 1];
int aint[4 * NMAX + 1];
void build (int node, int left, int right){
if (left == right){
aint[node] = v[left];
return;
}
int mij = (left + right) / 2;
build (2 * node, left, mij);
build (2 * node + 1, mij + 1, right);
aint[node] = max (aint[2 * node + 1], aint[2 * node]);
}
void update (int node, int left, int right, int poz, int val){
if (left == right){
aint[node] = val;
return;
}
int mij = (left + right) / 2;
if (poz <= mij){
update (2 * node, left, mij, poz, val);
}
else
update (2 * node + 1, mij + 1, right, poz, val);
aint[node] = max (aint[2 * node], aint[2 * node + 1]);
}
int query (int node, int left, int right, int qleft, int qright){
if (left == qleft && right == qright) return aint[node];
int mij = (left + right) / 2;
if (qleft <= mij && qright > mij){
return max (query (2 * node, left, mij, qleft, mij), query(2 * node + 1, mij + 1, right, mij + 1, qright));
}
else if (qleft <= mij){
return query(2 * node, left, mij, qleft, qright);
}
else{
return query(2 * node + 1, mij + 1, right, qleft, qright);
}
}
int main(){
ifstream fin ("arbint.in");
ofstream fout ("arbint.out");
int n, q;
fin >> n >> q;
for (int i = 1; i <= n; i++){
fin >> v[i];
}
build (1, 1, n);
int qst, qdr;
int type;
int val;
int poz;
for (int i = 1; i <= q; i++){
fin >> type;
if (type == 1){ /// update
fin >> poz >> val;
update (1, 1, n, poz, val);
}
else {
fin >> qst >> qdr;
fout << query(1, 1, n, qst, qdr) << "\n";
}
}
return 0;
}