#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
struct ST{
// [1-indexed]
// [uses <vector>, <algorithm>]
int N;
vector <int> T;
ST(int Size) : N(Size) { // Constructor
T.resize(4 * N + 1, 0);
}
void Update(int node, int from, int to, int pos, int val){ // Adds a value to a specified place whitin the ST
if(from == to){
T[node] = val;
return;
}
int mid = (from + to) / 2;
if(pos <= mid)
Update(2 * node, from, mid, pos, val);
else
Update(2 * node + 1, mid + 1, to, pos, val);
T[node] = max(T[2 * node], T[2 * node + 1]);
}
int Query(int node, int from, int to, int qleft, int qright){ // Returns the sum between two places
if(qleft <= from && to <= qright)
return T[node];
int mid = (from + to) / 2, smax = 0;
if(qleft <= mid){
int s = Query(2 * node, from, mid, qleft, qright);
smax = max(s, smax);
}
if(qright > mid){
int s = Query(2 * node + 1, mid + 1, to, qleft, qright);
smax = max(s, smax);
}
return smax;
}
};
int main(){
int N, M, val;
fin >> N >> M;
ST st(N);
for(int i = 1; i <= N; i ++){
fin >> val;
st.Update(1, 1, N, i, val);
}
int op, x, y;
for(int i = 1; i <= M; i ++){
fin >> op >> x >> y;
if(op == 1)
st.Update(1, 1, N, x, y);
else
fout << st.Query(1, 1, N, x, y) << '\n';
}
return 0;
}