#include <bits/stdc++.h>
using namespace std;
const int NMAX = 1e5 + 7;
int n, m;
int a[NMAX];
vector<int> adj[NMAX];
int pos[NMAX];
int par[NMAX];
int val[NMAX];
int head[NMAX];
int aint[NMAX * 4];
int weight[NMAX];
void dfs(int u) {
weight[u] = 1;
for (int v : adj[u]) {
if (v == par[u]) continue;
par[v] = u;
dfs(v);
weight[u] += weight[v];
}
}
void decomp(int u) {
static int aint_pos = 0;
pos[u] = aint_pos++;
if (adj[u].empty() || (u != 1 && adj[u].size() == 1)) return;
int next = 0;
for (int v : adj[u]) {
if (v == par[u]) continue;
next = weight[v] > weight[next] ? v : next;
}
head[next] = head[u];
decomp(next);
for (int v : adj[u]) {
if (v == par[u] || v == next) 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 hld_update(int node, int value) {
update(0, n - 1, 0, pos[node], value);
}
int hld_query(int node1, int node2) {
int res = 0;
while (head[node1] != head[node2]) {
if (weight[head[node1]] > weight[head[node2]]) swap(node1, node2);
res = max(res, query(0, n - 1, 0, pos[head[node1]], pos[node1]));
node1 = par[head[node1]];
}
if (weight[node1] < weight[node2]) swap(node1, node2);
return max(res, query(0, n - 1, 0, pos[node1], pos[node2]));
}
void solve() {
cin >> n >> m;
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(0, n - 1, 0);
for (int i = 0; i < m; i++) {
int c, u, v;
cin >> c >> u >> v;
if (c == 0) hld_update(u, v);
else cout << hld_query(u, v) << '\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();
}