// #pragma GCC optimize("Ofast,no-stack-protector")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native")
#include <bits/stdc++.h>
#define all(x) (x).begin(), (x).end()
#define itn int
#define make_unique(x) sort((x).begin(), (x).end()); (x).erase(unique((x).begin(), (x).end()), (x).end())
using namespace std;
inline int nxt() {
int x;
scanf("%d", &x);
return x;
}
const int N = 111111;
int k[N];
int b[N];
inline long long get(int l, int r) {
int ans = -1e9;
for (int i = l; i < r; ++i) {
ans = max(ans, k[i]);
}
return ans;
}
void inc(int l, int r, int kk) {
for (int i = l; i < r; ++i) {
k[i] = kk;
}
}
vector<int> a[N];
int sz[N];
int level[N];
int par[N];
int tin[N], tout[N];
int timer = 0;
void dfs(int v, int p = -1) {
par[v] = p;
auto it = find(all(a[v]), p);
if (it != a[v].end()) {
a[v].erase(it);
}
for (int x : a[v]) {
level[x] = level[v] + 1;
dfs(x, v);
sz[v] += sz[x];
}
++sz[v];
sort(all(a[v]), [&](int x, int y) {
return sz[x] > sz[y];
});
}
int w[N];
void dfsOrder(int v) {
tin[v] = timer++;
if (!a[v].empty()) {
w[a[v][0]] = w[v];
}
for (int x : a[v]) {
dfsOrder(x);
}
tout[v] = timer;
}
bool isPar(int u, int v) {
return tin[u] <= tin[v] && tout[u] >= tout[v];
}
int getAnswer(int u, int v) {
int ans = -1e9;
while (!isPar(w[u], v)) {
ans = max(ans, get(tin[w[u]], tin[u] + 1));
u = par[w[u]];
}
while (w[v] != w[u]) {
ans = max(ans, get(tin[w[v]], tin[v] + 1));
v = par[w[v]];
}
return max(ans, get(min(tin[u], tin[v]), max(tin[u], tin[v]) + 1));
}
void incAll(int u, int v, int kk) {
while (!isPar(w[u], v)) {
inc(tin[w[u]], tin[u] + 1, kk);
u = par[w[u]];
}
while (w[v] != w[u]) {
inc(tin[w[v]], tin[v] + 1, kk);
v = par[w[v]];
}
inc(min(tin[u], tin[v]), max(tin[u], tin[v]) + 1, kk);
}
int main() {
freopen("heavypath.in", "r", stdin);
freopen("heavypath.out", "w", stdout);
int n = nxt(), q = nxt();
vector<int> curk(n);
vector<long long> curb(n);
for (int i = 0; i < n; ++i) {
curk[i] = nxt();
}
for (int i = 0; i < n - 1; ++i) {
int u = nxt() - 1, v = nxt() - 1;
a[u].push_back(v);
a[v].push_back(u);
}
dfs(0);
iota(w, w + n, 0);
dfsOrder(0);
for (int i = 0; i < n; ++i) {
k[tin[i]] = curk[i];
b[tin[i]] = curb[i];
}
while (q--) {
int t, u, v;
scanf("%d %d %d", &t, &u, &v);
u--, v--;
if (t == 0)
incAll(u, u, v);
else printf("%d\n", getAnswer(u, v));
}
return 0;
}