#include <bits/stdc++.h>
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int rand(int a, int b)
{
int ans = uniform_int_distribution<int>(a, b)(rng);
return ans;
}
#define fastio std::ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
#define test " test "
#define yes "YES"
#define no "NO"
#define bn '\n'
#define ll long long
#define pb push_back
#define all(x) x.begin(), x.end()
//#define int long long
#define deb(a) cout << #a << "=" << (a) << bn
#define deb2(a, b) cout << #a << "=" << (a) << " " << #b << "=" << b << bn
#define readV(v, n) \
for (int i = 0; i < n; i++) \
cin >> v[i];
#define printV(v) \
for (auto i : v) \
cout << i << " ";
#define FILES \
freopen("txt.in", "r", stdin); \
freopen("txt.out", "w", stdout);
const int mod = 1e9 + 7;
const int NMAX = 1e5 + 10;
int maxi = INT_MIN, mini = INT_MAX;
int n, q, fr;
int v[NMAX], dp[NMAX], tatal[NMAX], nivel[NMAX];
int lnt[NMAX];
int pos[NMAX];
vector<vector<int>> lant;
vector<vector<int>> tree;
vector<int> adj[NMAX];
void dfs(int node, int tata);
void dfs2(int node, int tata);
void build(int node, int st, int dr, int id);
void update(int node, int st, int dr, int pos, int val, int id);
int query(int node, int st, int dr, int x, int y, int id);
void solve()
{
cin >> n >> q;
int a, b;
for (int i = 1; i <= n; i++)
cin >> v[i];
for (int i = 1; i < n; i++)
{
cin >> a >> b;
adj[b].pb(a);
adj[a].pb(b);
}
dfs(1, 0);
lant.resize(n + 1);
tree.resize(n + 1);
fr = 0;
dfs2(1, 0);
for (int i = 1; i <= fr; i++)
{
tree[i].resize(4 * lant[i].size() + 5);
build(1, 1, lant[i].size(), i);
}
//cout << test;
int x, y, c;
while (q--)
{
cin >> c >> x >> y;
int idx = lnt[x], idy = lnt[y];
if (c == 0)
{
update(1, 1, lant[idx].size(), pos[x], y, lnt[x]);
continue;
}
int ans = 0;
while (idx != idy)
{
idx = lnt[x];
idy = lnt[y];
if (nivel[lant[idx].back()] > nivel[lant[idy].back()])
{ // find max from x -> root of chain
ans = max(ans, query(1, 1, lant[idx].size(), pos[x], lant[idx].size(), idx));
/// x= tatal root chain
x = tatal[lant[idx].back()];
idx = lnt[x];
}
else
{
ans = max(ans, query(1, 1, lant[idy].size(), pos[y], lant[idy].size(), idy));
y = tatal[lant[idy].back()];
idy = lnt[y];
}
}
if (nivel[x] < nivel[y])
{
swap(x, y);
}
idx = lnt[x];
idy = lnt[y];
ans = max(ans, query(1, 1, lant[idx].size(), pos[x], pos[y], idx));
cout << ans << bn;
}
}
void dfs(int node, int tata)
{
nivel[node] = nivel[tata] + 1;
tatal[node] = tata;
dp[node] = 1;
for (auto &it : adj[node])
if (it != tata)
{
dfs(it, node);
dp[node] += dp[it];
}
if (dp[node] == 1)
fr++;
}
void dfs2(int node, int tata)
{
for (auto &it : adj[node])
if (it != tata)
dfs2(it, node);
if (dp[node] == 1)
{
lnt[node] = ++fr; /// id-ul lantului
lant[fr].pb(node); /// adaug un node in lant
pos[node] = 1; // node-ul frunza este primul
return;
}
int best = -1, newNode;
for (auto it : adj[node])
if (it != tata and best < dp[it])
{
best = dp[it];
newNode = it;
}
/// adaugam la lantul copilului cu cel mai mare dp
int id = lnt[newNode];
lnt[node] = id;
lant[id].pb(node);
pos[node] = lant[id].size();
}
void build(int node, int st, int dr, int id)
{
if (st == dr)
{ //-1, st=1,dr=.size()
tree[id][node] = v[lant[id][st - 1]];
return;
}
int mid = (st + dr) >> 1;
build(node << 1, st, mid, id);
build((node << 1) + 1, mid + 1, dr, id);
tree[id][node] = max(tree[id][node << 1], tree[id][(node << 1) + 1]);
}
void update(int node, int st, int dr, int pos, int val, int id)
{
if (st == dr)
{
tree[id][node] = val;
return;
}
int mid = (st + dr) >>1;
if (pos <= mid)
update(node<<1, st, mid, pos, val, id);
else
update((node<<1) + 1, mid + 1, dr, pos, val, id);
tree[id][node] = max(tree[id][node << 1], tree[id][(node << 1) + 1]);
}
int query(int node, int st, int dr, int x, int y, int id)
{
if (x <= st and dr <= y)
return tree[id][node];
int mid = (st + dr) >> 1;
int ans = 0;
if (x <= mid)
ans = query(node << 1, st, mid, x, y, id);
if (y > mid)
ans = max(ans, query((node << 1) + 1, mid + 1, dr, x, y, id));
return ans;
}
signed main()
{
fastio;
// FILES;
int __t = 1;
// cin >> __t;
while (__t--)
solve();
return 0;
}