#include <bits/stdc++.h>
using namespace std;
ifstream in("heavypath.in");
ofstream out("heavypath.out");
int n, q, v[100005];
vector<int> g[100005], f[100005];
int t[100005], sz[100005];
int ord[100005], pos[100005], h[100005];
int rep[100005], cr;
bool cmp(int A, int B)
{
return sz[A] > sz[B];
}
void dfs(int nod)
{
sz[nod] = 1;
for (auto vecin : g[nod])
{
if (vecin != t[nod])
{
t[vecin] = nod;
h[vecin] = 1 + h[nod];
f[nod].push_back(vecin);
dfs(vecin);
sz[nod] += sz[vecin];
}
}
sort(f[nod].begin(), f[nod].end(), cmp);
}
void df(int nod)
{
cr++;
ord[cr] = nod;
pos[nod] = cr;
if (f[nod].empty())
return;
rep[f[nod][0]] = rep[nod];
df(f[nod][0]);
for (int i = 1; i < f[nod].size(); i++)
{
rep[f[nod][i]] = f[nod][i];
df(f[nod][i]);
}
}
int aint[400005];
void update(int nod, int l, int r, int pos, int val)
{
if (l == r)
aint[nod] = val;
else
{
int mij = (l + r) / 2;
if (pos <= mij)
update(2 * nod, l, mij, pos, val);
else
update(2 * nod + 1, mij + 1, r, pos, val);
aint[nod] = max(aint[2 * nod], aint[2 * nod + 1]);
}
}
int query(int nod, int l, int r, int st, int dr)
{
if (r < st or dr < l)
return -1;
if (st <= l and r <= dr)
return aint[nod];
int mij = (l + r) / 2;
return max(query(2 * nod, l, mij, st, dr), query(2 * nod + 1, mij + 1, r, st, dr));
}
int lca(int x, int y)
{
if (h[x] < h[y])
swap(x, y);
if (rep[x] == rep[y])
return y;
if (h[rep[x]] > h[rep[y]])
x = t[rep[x]];
else
y = t[rep[y]];
return lca(x, y);
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
in >> n >> q;
for (int i = 1; i <= n; i++)
in >> v[i];
for (int i = 1; i < n; i++)
{
int x, y;
in >> x >> y;
g[x].push_back(y);
g[y].push_back(x);
}
h[0] = -1;
dfs(1);
rep[1] = 1;
df(1);
for (int i = 1; i <= n; i++)
update(1, 1, n, pos[i], v[i]);
for (int iq = 1; iq <= q; iq++)
{
int tip;
in >> tip;
if (tip == 0)
{
int x, y;
in >> x >> y;
update(1, 1, n, pos[x], y);
}
else
{
int x, y;
in >> x >> y;
int l = lca(x, y);
int ans = 0;
while (h[x] >= h[l])
{
int rt = rep[x];
if (h[rt] > h[l])
{
ans = max(ans, query(1, 1, n, pos[rt], pos[x]));
x = t[rt];
}
else
{
ans = max(ans, query(1, 1, n, pos[l], pos[x]));
break;
}
}
x = y;
while (h[x] >= h[l])
{
int rt = rep[x];
if (h[rt] > h[l])
{
ans = max(ans, query(1, 1, n, pos[rt], pos[x]));
x = t[rt];
}
else
{
ans = max(ans, query(1, 1, n, pos[l], pos[x]));
break;
}
}
x = y;
out << ans << '\n';
}
}
return 0;
}