#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
class AInt {
public:
AInt() = delete;
AInt(const vector<int> &v) : v(v), aint(4*v.size()) {
build(1, 1, v.size()-1);
}
void update(int pos, int newval) {
update(1, 1, v.size()-1, pos, newval);
}
int query(int left, int right) {
return query(1, 1, v.size()-1, left, right);
}
private:
int query(int node, int left, int right, int qleft, int qright) {
if(left == right) {
return aint[node];
}
else {
int m = (left + right) / 2;
if(qright <= m) {
return query(node * 2, left, m, qleft, qright);
}
if (m + 1 <= qleft){
return query(node * 2 + 1, m+1, right, qleft, qright);
}
return max(query(node * 2, left, m, qleft, qright),
query(node * 2 + 1, m+1, right, qleft, qright));
}
}
void update(int node, int left, int right, int pos, int newval) {
if(left == right) {
aint[node] = newval;
}
else {
int m = (left + right) / 2;
if(pos <= m) {
update(node * 2, left, m, pos, newval);
}
else {
update(node * 2 + 1, m+1, right, pos, newval);
}
aint[node] = max(aint[node*2], aint[node*2+1]);
}
}
void build(int node, int left, int right) {
if(left == right) {
aint[node] = v[left];
}
else {
int m = (left + right) / 2;
build(node * 2, left, m);
build(node * 2 + 1, m+1, right);
aint[node] = max(aint[node*2], aint[node*2+1]);
}
}
vector<int> aint;
vector<int> v;
};
int main() {
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int n, m;
fin >> n >> m;
vector<int> v(n+1);
for(int i = 1; i <= n; i++) {
fin >> v[i];
}
AInt aint(v);
for(int i = 0; i < m; i++) {
int op, x, y;
fin >> op >> x >> y;
if(op == 1) {
aint.update(x, y);
}
else {
fout << aint.query(x, y) << '\n';
}
}
return 0;
}