#include <bits/stdc++.h>
#define MN 100001
using namespace std;
ifstream fi("heavypath.in");
ofstream fo("heavypath.out");
int n, m, Val[MN];
vector<int> L[MN];
struct AINT {
int V[3 * MN];
void update(int p, int v, int u = 1, int s = 1, int d = MN - 1) {
if(d < p || p < s) return;
if(s == d) {
V[u] = v;
return;
}
update(p, v, u * 2, s, (s + d) / 2);
update(p, v, u * 2 + 1, (s + d) / 2 + 1, d);
V[u] = max(V[u * 2], V[u * 2 + 1]);
}
int query(int l, int r, int u = 1, int s = 1, int d = MN - 1) {
if(d < l || r < s) return 0;
if(l <= s && d <= r) return V[u];
return max(query(l, r, u * 2, s, (s + d) / 2), query(l, r, u * 2 + 1, (s + d) / 2 + 1, d));
}
};
struct HeavyPath {
AINT Arbore;
int Sum[MN], Niv[MN];
int nrseg, St[MN], Nr[MN], H[MN], Cul[MN]; // AINT
int Par[MN];
vector<int> PaterFam{0};
void id_dfs(int u, int p, int niv) {
Sum[u] = 1;
Niv[u] = niv;
vector<int> nou;
for(auto it : L[u]) if (it != p) {
id_dfs(it, u, niv + 1);
Sum[u] += Sum[it];
nou.push_back(it);
}
L[u] = move(nou);
}
void cul_dfs(int u, int p, int color, int h) {
++Nr[color];
Cul[u] = color;
H[u] = h;
if(!h) PaterFam.push_back(u);
Par[u] = p;
int ma = 0, sma = -1;
for(auto it : L[u]) if (it != p && Sum[it] > sma) {
sma = Sum[it];
ma = it;
}
for(auto it : L[u]) if (it != p) {
if(it == ma) cul_dfs(it, u, color, h + 1);
else cul_dfs(it, u, ++nrseg, 0);
}
}
void build() {
id_dfs(1, 0, 0);
cul_dfs(1, 0, (nrseg = 1), 0);
for(int i = 1; i <= nrseg; ++i) {
St[i] = Nr[i - 1] + 1;
Nr[i] += Nr[i - 1];
}
for(int i = 1; i <= n; ++i) Arbore.update(St[Cul[i]] + H[i], Val[i]);
}
void update(int p, int v) { Arbore.update(St[Cul[p]] + H[p], v); }
int query(int u, int v) {
int re = 0;
while(1) {
if(Cul[u] == Cul[v])
return max(re, Arbore.query(St[Cul[u]] + min(H[u], H[v]), St[Cul[u]] + max(H[u], H[v])));
if(Niv[PaterFam[Cul[u]]] < Niv[PaterFam[Cul[v]]]) swap(u, v);
re = max(re, Arbore.query(St[Cul[u]], St[Cul[u]] + H[u]));
u = Par[PaterFam[Cul[u]]];
}
return re;
}
};
HeavyPath Sol;
int main() {
fi >> n >> m;
for(int i = 1; i <= n; ++i) fi >> Val[i];
for(int i = 1, u, v; i < n; ++i) {
fi >> u >> v;
L[u].push_back(v);
L[v].push_back(u);
}
Sol.build();
for(int i = 1, tip, a, b; i <= m; ++i) {
fi >> tip >> a >> b;
if(tip) fo << Sol.query(a, b) << "\n";
else Sol.update(a, b);
}
return 0;
}