#include <bits/stdc++.h>
// #define in cin
// #define out cout
using namespace std;
ifstream in("heavypath.in");
ofstream out("heavypath.out");
const int nmax = 1e5 + 5e0;
const int lgmax = 17;
int n, m;
int v[nmax];
int depth[nmax];
int pIndex[nmax];
vector<int> adj[nmax];
vector<int> paths;
int aint[3 * nmax];
int aintIndex[nmax];
int parent[nmax];
void update(int poz, int val, int st = 1, int dr = n, int nod = 1)
{
if (st == dr)
{
aint[nod] = val;
}
else
{
int mid = (st + dr) / 2;
if (poz <= mid)
{
update(poz, val, st, mid, 2 * nod);
}
else
{
update(poz, val, mid + 1, dr, 2 * nod + 1);
}
aint[nod] = max(aint[2 * nod], aint[2 * nod + 1]);
}
}
int query(int l, int r, int st = 1, int dr = n, int nod = 1)
{
if (l == st && r == dr)
{
return aint[nod];
}
else
{
int mid = (st + dr) / 2;
if (r <= mid)
return query(l, r, st, mid, 2 * nod);
else if (mid < l)
return query(l, r, mid + 1, dr, 2 * nod + 1);
else
{
return max(
query(l, mid, st, mid, 2 * nod),
query(mid + 1, r, mid + 1, dr, 2 * nod + 1));
}
}
}
int ind = 1;
vector<int> dfs(int nod = 1, int p = 0, int dep = 0)
{
parent[nod] = p;
depth[nod] = dep;
vector<int> path;
vector<vector<int>> tmm;
int maxx = 0;
for (auto i : adj[nod])
{
if (i != p)
{
auto tm = dfs(i, nod, dep + 1);
tmm.push_back(tm);
maxx = max(maxx, (int)tm.size());
}
}
bool found = 0;
for (auto i : tmm)
{
if (i.size() == maxx && found == 0)
{
path = i;
found = 1;
}
else
{
paths.push_back(i.back());
for (auto j : i)
{
pIndex[j] = paths.size() - 1;
aintIndex[j] = ind++;
}
}
}
path.push_back(nod);
return path;
}
void readInput()
{
in >> n >> m;
for (int i = 1; i <= n; i++)
{
in >> v[i];
}
for (int i = 1; i < n; i++)
{
int a, b;
in >> a >> b;
adj[a].push_back(b);
adj[b].push_back(a);
}
}
int q(int x, int y)
{
int ans = 0;
while (1)
{
auto px = paths[pIndex[x]];
auto py = paths[pIndex[y]];
if (px == py)
{
if (depth[x] > depth[y])
{
swap(x, y);
}
ans = max(ans, query(aintIndex[y], aintIndex[x]));
break;
}
else
{
if (depth[px] < depth[py])
{
swap(x, y);
swap(px, py);
}
ans = max(ans, query(aintIndex[x], aintIndex[px]));
x = parent[px];
}
}
return ans;
}
void solve()
{
for (int i = 1; i <= n; i++)
{
update(aintIndex[i], v[i]);
}
for (int i = 0; i < m; i++)
{
int t, x, y;
in >> t >> x >> y;
if (t == 0)
{
v[x] = y;
update(aintIndex[x], y);
}
else
{
out << q(x, y) << '\n';
}
}
}
int main()
{
readInput();
auto i = dfs();
paths.push_back(i.back());
for (auto j : i)
{
pIndex[j] = paths.size() - 1;
aintIndex[j] = ind++;
}
solve();
}