#include <bits/stdc++.h>
using namespace std;
const int NMAX = 1e5 + 7;
int n;
int a[NMAX];
vector<int> adj[NMAX];
int aint[NMAX * 4];
int weight[NMAX];
int head[NMAX];
int pos[NMAX];
int par[NMAX];
int val[NMAX];
void dfs(int u) {
weight[u] = 1;
for (int v : adj[u]) {
if (v != par[u]) {
par[v] = u;
dfs(v);
weight[u] += weight[v];
}
}
}
void decomp(int u) {
static int pos_cur = 0;
pos[u] = ++pos_cur;
if (par[u] && adj[u].size() == 1) return;
int s = 0;
for (int v : adj[u]) if (v != par[u] && weight[v] > weight[s]) s = v;
head[s] = head[u];
decomp(s);
for (int v : adj[u]) {
if (v == s || v == par[u]) continue;
head[v] = v;
decomp(v);
}
}
void build(int b, int e, int i) {
if (b == e) {
aint[i] = val[b];
return;
}
int m = (b + e) / 2;
build(b, m, i * 2 + 1);
build(m + 1, e, i * 2 + 2);
aint[i] = max(aint[i * 2 + 1], aint[i * 2 + 2]);
}
void update(int b, int e, int i, int j, int v){
if (b == e) {
aint[i] = v;
return;
}
int m = (b + e) / 2;
if (j <= m) update(b, m, i * 2 + 1, j, v);
else update(m + 1, e, i * 2 + 2, j, v);
aint[i] = max(aint[i * 2 + 1], aint[i * 2 + 2]);
}
int query(int b, int e, int i, int l, int r) {
if (l <= b && e <= r) return aint[i];
int m = (b + e) / 2;
if (r <= m) return query(b, m, i * 2 + 1, l, r);
if (l >= m + 1) return query(m + 1, e, i * 2 + 2, l, r);
return max(query(b, m, i * 2 + 1, l, r), query(m + 1, e, i * 2 + 2, l, r));
}
void solve() {
int q;
cin >> n >> q;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 0; i < n - 1; i++) {
int u, v;
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
dfs(1);
head[1] = 1;
decomp(1);
for (int i = 1; i <= n; i++) val[pos[i]] = a[i];
build(1, n, 0);
#ifdef LOCAL
for (int i = 1; i <= n; i++) cout << head[i] << ' ';
cout << endl;
for (int i = 1; i <= n; i++) cout << pos[i] << ' ';
cout << endl;
#endif
while (q--) {
int c, x, y;
cin >> c >> x >> y;
if (c == 0) {
#ifdef LOCAL
cout << "update " << x << ' ' << par[x] << ' ' << y << endl;
#endif
update(1, n, 0, pos[x], y);
}
else {
int ans = 0;
while (head[x] != head[y]) {
if (weight[head[x]] > weight[head[y]]) swap(x, y);
ans = max(ans, query(1, n, 0, pos[head[x]], pos[x]));
#ifdef LOCAL
cout << "query " << x << ' ' << head[x] << ' ' << pos[head[x]] << ' ' << pos[x] << endl;
#endif
x = par[head[x]];
}
if (weight[x] < weight[y]) swap(x, y);
ans = max(ans, query(1, n, 0, pos[x], pos[y]));
#ifdef LOCAL
cout << "query " << x << ' ' << y << ' ' << pos[x] << ' ' << pos[y] << endl;
#endif
cout << ans << '\n';
}
}
}
int main() {
#ifdef LOCAL
freopen("file.in", "r", stdin);
#else
freopen("heavypath.in", "r", stdin);
freopen("heavypath.out", "w", stdout);
#endif
ios_base::sync_with_stdio(false), cin.tie(NULL);
solve();
}