#include <fstream>
#include <algorithm>
using namespace std;
const int NMAX = 1000005;
struct node {
int st, dr;
int maxim;
node (int _st = 0, int _dr = 0, int _maxim = 0): st(_st), dr(_dr), maxim(_maxim) {}
} arb[4 * NMAX];
int v[NMAX];
void build (int st, int dr, int pos) {
arb[pos].st = st, arb[pos].dr = dr;
if (st == dr) {
arb[pos].maxim = v[st];
return ;
}
int mijl = (st + dr) / 2;
build(st, mijl, 2 * pos);
build(mijl + 1, dr, 2 * pos + 1);
arb[pos].maxim = max(arb[2 * pos].maxim, arb[2 * pos + 1].maxim);
}
void update (int where, int val, int pos) {
if (arb[pos].st == arb[pos].dr) {
arb[pos].maxim = val;
return ;
}
int mijl = (arb[pos].st + arb[pos].dr) / 2;
if (where <= mijl)
update(where, val, 2 * pos);
else
update(where, val, 2 * pos + 1);
arb[pos].maxim = max(arb[2 * pos].maxim, arb[2 * pos + 1].maxim);
}
int query (int st, int dr, int pos) {
if (arb[pos].st == st && arb[pos].dr == dr)
return arb[pos].maxim;
int mijl = (arb[pos].st + arb[pos].dr) / 2;
if (dr <= mijl)
return query(st, dr, 2 * pos);
else if (st > mijl)
return query(st, dr, 2 * pos + 1);
else
return max(query(st, mijl, 2 * pos), query(mijl + 1, dr, 2 * pos + 1));
}
int main()
{
ifstream cin("arbint.in");
ofstream cout("arbint.out");
int n = 1, m = 0;
cin >> n >> m;
for (int i = 1; i <= n; ++ i)
cin >> v[i];
build(1, n, 1);
bool type;
int a, b;
while (m --) {
cin >> type >> a >> b;
if (!type)
cout << query(a, b, 1) << '\n';
else
update(a, b, 1);
}
cin.close();
cout.close();
return 0;
}