#include <bits/stdc++.h>
using namespace std;
using arr = int[500000];
arr Agg, Depth, Parent, Link, Value, Jump, Enter;
vector<int> G[500000];
const int kMagic = 512;
int timer;
void DFS(int node, int par, int depth) {
Parent[node] = par;
Jump[node] = (depth % kMagic == 0 ? node : Jump[par]);
Enter[node] = timer++;
Depth[node] = depth;
for (auto vec : G[node]) {
if (vec != par)
DFS(vec, node, depth + 1);
}
}
int GetLCA(int a, int b) {
while (a != b) {
if (Depth[a] < Depth[b]) swap(a, b);
if (Depth[Jump[a]] >= Depth[b]) a = Jump[a];
else a = Parent[a];
}
return a;
}
vector<int> CompressTree(vector<int> v, arr ret) {
auto cmp = [&](int a, int b) {
return Enter[a] < Enter[b];
};
sort(v.begin(), v.end(), cmp);
v.erase(unique(v.begin(), v.end()), v.end());
for (int i = (int)v.size() - 1; i > 0; --i)
v.push_back(GetLCA(v[i - 1], v[i]));
sort(v.begin(), v.end(), cmp);
v.erase(unique(v.begin(), v.end()), v.end());
for (int i = 0; i < (int)v.size(); ++i)
ret[v[i]] = (i == 0 ? -1 : GetLCA(v[i - 1], v[i]));
return v;
}
int main() {
ifstream cin("heavypath.in");
ofstream cout("heavypath.out");
int n, m; cin >> n >> m;
for (int i = 0; i < n; ++i) {
cin >> Value[i];
}
for (int i = 1; i < n; ++i) {
int a, b; cin >> a >> b;
G[a - 1].push_back(b - 1);
G[b - 1].push_back(a - 1);
}
DFS(0, -1, 0);
for (int i = 0; i < m; i += kMagic) {
vector<tuple<int, int, int>> qs;
vector<int> sub;
for (int j = i; j < m && j < i + kMagic; ++j) {
int t, a, b; cin >> t >> a >> b;
sub.push_back(--a); if (t == 1) sub.push_back(--b);
qs.emplace_back(t, a, b);
}
sub = CompressTree(sub, Link);
for (auto& node : sub) {
Agg[node] = 0; int anc = Link[node];
for (node = Parent[node]; node != anc; node = Parent[node])
Agg[node] = max(Agg[node], Value[node]);
}
for (auto q : qs) {
int t, a, b; tie(t, a, b) = q;
if (t == 0) Value[a] = b;
else {
int res = 0;
while (a != b) {
if (Depth[a] < Depth[b]) swap(a, b);
res = max(res, Value[a]);
res = max(res, Agg[a]);
a = Link[a];
}
cout << max(res, Value[a]) << '\n';
}
}
}
return 0;
}