/*
Author: Paul Ciumandru
Hard work beats talent!
*/
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#include <bits/stdc++.h>
using namespace std;
#define NMAX 100000
#define MMAX 20
#define PMAX 500
#define LOG 30
#define INF_INT 2e9
#define INF_LL 1e18
#define BS 666013
#define MOD 1000000007
#define debug(x) cout << #x << " = " << x << "\n";
#define vdebug(a) cout << #a << " = "; for(auto x: a) cout << x << " "; cout << "\n";
#define ll long long
#define ull unsigned long long
#define dbl double
#define ldb long double
#define pii pair<int, int>
#define pll pair<ll, ll>
#define piv pair<int, vector<int>>
#define pipii pair<int, pair<pii, pii>>
#define tpl tuple<int, int, int>
#define tpl2 tuple<int, int, vector<int>>
#define vpi vector<pii>
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int n, m, op, x, a, b;
vector<int> tree(NMAX * 4 + 3);
void build(int node, int st, int dr) {
if (st == dr) {
fin >> tree[node];
return;
}
int mij = (st + dr) >> 1;
build((node << 1), st, mij);
build((node << 1) | 1, mij + 1, dr);
tree[node] = max(tree[(node << 1)], tree[(node << 1) | 1]);
}
void update(int node, int st, int dr, int poz, int val) {
if (st == dr) {
tree[node] = val;
return;
}
int mij = (st + dr) >> 1;
if (poz <= mij) {
update((node << 1), st, mij, poz, val);
}
else {
update((node << 1) | 1, mij + 1, dr, poz, val);
}
tree[node] = max(tree[(node << 1)], tree[(node << 1) | 1]);
}
int query(int node, int st, int dr, int a, int b) {
if (dr < a || st > b) {
return 0;
}
if (a <= st && dr <= b) {
return tree[node];
}
int mij = (st + dr) >> 1;
int v1 = query((node << 1), st, mij, a, b);
int v2 = query((node << 1) | 1, mij + 1, dr, a, b);
return max(v1, v2);
}
int main() {
ios_base::sync_with_stdio(false);
fin.tie(NULL);
fout.tie(NULL);
fin >> n >> m;
build(1, 1, n);
while (m--) {
fin >> op >> a >> b;
if (op == 0) {
fout << query(1, 1, n, a, b) << "\n";
}
else {
update(1, 1, n, a, b);
}
}
return 0;
}