#include <bits/stdc++.h>
using namespace std;
const int DIM = 100005;
int szt[DIM], lev[DIM], wch[DIM], ftc[DIM], val[DIM];
int ord[DIM], fis[DIM], pos[DIM], sgt[DIM << 2];
vector<int> edg[DIM];
void dfs1 (int x, int f = 0)
{
static int nr = 0; int mx = -1;
szt[x] = 1; lev[x] = lev[f] + 1;
if (f) {
edg[x].erase(find(edg[x].begin(), edg[x].end(), f)); }
for (int y : edg[x]) {
dfs1(y, x); szt[x] += szt[y];
mx = max(mx, szt[y]); }
for (int it = 0; it < edg[x].size(); ++it) {
int y = edg[x][it];
if (szt[y] == mx) {
swap(edg[x][0], edg[x][it]); break; } }
if (mx == -1) {
wch[x] = ++nr; }
else {
wch[x] = wch[edg[x][0]];
for (int y : edg[x]) {
if (wch[y] != wch[x]) {
ftc[wch[y]] = x; } } }
}
void dfs2 (int x)
{
static int nr = 0;
ord[++nr] = x; pos[x] = nr;
for (int y : edg[x]) {
dfs2(y); }
}
void build (int nd, int le, int ri)
{
if (le == ri) {
sgt[nd] = val[ord[le]]; }
else {
int md = (le + ri) >> 1;
build(nd << 1, le, md);
build(nd << 1 | 1, md + 1, ri);
sgt[nd] = max(sgt[nd << 1], sgt[nd << 1 | 1]); }
}
void update (int nd, int le, int ri, int ps, int vl)
{
if (le == ri) {
sgt[nd] = vl; }
else {
int md = (le + ri) >> 1;
if (ps <= md) {
update(nd << 1, le, md, ps, vl); }
else {
update(nd << 1 | 1, md + 1, ri, ps, vl); }
sgt[nd] = max(sgt[nd << 1], sgt[nd << 1 | 1]); }
}
int query (int nd, int le, int ri, int st, int en)
{
if (st == le && en == ri) {
return sgt[nd]; }
else {
int md = (le + ri) >> 1;
if (en <= md) {
return query(nd << 1, le, md, st, en); }
else if (md < st) {
return query(nd << 1 | 1, md + 1, ri, st, en); }
else {
return max(query(nd << 1, le, md, st, md),
query(nd << 1 | 1, md + 1, ri, md + 1, en)); } }
}
int query_heavy (int x, int y, int n)
{
if (wch[x] == wch[y]) {
if (pos[x] > pos[y]) {
swap(x, y); }
return query(1, 1, n, pos[x], pos[y]); }
else {
if (lev[ftc[wch[x]]] > lev[ftc[wch[y]]]) {
swap(x, y); }
return max(query(1, 1, n, fis[wch[y]], pos[y]),
query_heavy(x, ftc[wch[y]], n)); }
}
int main (void)
{
freopen("heavypath.in", "r", stdin);
freopen("heavypath.out", "w", stdout);
int n, q; cin >> n >> q;
for (int i = 1; i <= n; ++i) {
cin >> val[i]; }
for (int i = 1; i < n; ++i) {
int x, y; cin >> x >> y;
edg[x].push_back(y);
edg[y].push_back(x); }
dfs1(1); dfs2(1);
for (int i = 1; i <= n; ++i) {
int x = ord[i - 1], y = ord[i];
if (wch[x] != wch[y]) {
fis[wch[y]] = i; } }
build(1, 1, n);
while (q--) {
int t, x, y; cin >> t >> x >> y;
if (t == 0) {
update(1, 1, n, pos[x], y); }
else {
cout << query_heavy(x, y, n) << "\n"; } }
return 0;
}