#include <bits/stdc++.h>
#define MN 107171
using namespace std;
ifstream fi("heavypath.in");
ofstream fo("heavypath.out");
int n, m, Val[MN];
vector<int> L[MN];
struct AINT {
int V[4 * MN];
void build(int u, int s, int d, int* O) {
if(s == d) {
V[u] = O[s];
return;
}
build(u * 2, s, (s + d) / 2, O);
build(u * 2 + 1, (s + d) / 2 + 1, d, O);
V[u] = max(V[u * 2], V[u * 2 + 1]);
}
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], FiuAles[MN];
int nrseg, St[MN], Nr[MN], H[MN], Cul[MN]; // AINT
int Par[MN], PaterFam[MN];
int ST[20][MN];
int lca(int u, int v) {
if(Niv[u] < Niv[v]) swap(u, v);
for(int k = 19, d = Niv[u] - Niv[v]; k >= 0; --k)
if(d & (1 << k)) u = ST[k][u];
if(u == v) return u;
for(int k = 19; k >= 0; --k)
if(ST[k][u] != ST[k][v]) u = ST[k][u], v = ST[k][v];
return ST[0][u];
}
void id_dfs(int u, int p, int niv) {
Sum[u] = 1;
Niv[u] = niv;
int ma = 0, sma = -1;
for(auto it : L[u]) if (it != p) {
id_dfs(it, u, niv + 1);
Sum[u] += Sum[it];
if(Sum[it] > sma) {
sma = Sum[it];
ma = it;
}
}
FiuAles[u] = ma;
}
void cul_dfs(int u, int p, int color, int h) {
++Nr[color];
Cul[u] = color;
H[u] = h;
if(!h) PaterFam[color] = u;
Par[u] = p;
for(auto it : L[u]) if (it != p) {
if(it == FiuAles[u]) cul_dfs(it, u, color, h + 1);
else cul_dfs(it, u, ++nrseg, 0);
}
}
void build() {
id_dfs(1, -1, 0);
cul_dfs(1, -1, (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]);
for(int i = 1; i <= n; ++i) ST[0][i] = Par[i];
for(int k = 1; k < 20; ++k)
for(int i = 1; i <= n; ++i) ST[k][i] = ST[k-1][ST[k-1][i]];
}
void update(int p, int v) {
Arbore.update(St[Cul[p]] + H[p], v);
}
int solve(int fiu, int par) {
if(Cul[fiu] == Cul[par]) return Arbore.query(St[Cul[par]] + H[par], St[Cul[fiu]] + H[fiu]);
else return max(solve(fiu, PaterFam[Cul[fiu]]), solve(Par[PaterFam[Cul[fiu]]], par));
}
int query(int u, int v) {
int l = lca(u, v);
return max(solve(u, l), solve(v, l));
}
};
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;
}