# include <bits/stdc++.h>
using namespace std;
const int Nmax = 32001 + 5;
struct per
{
int first, second, third;
};
per ans;
vector <int> G[Nmax];
int rmq[20][2 * Nmax], Log[2 * Nmax], euler[2 * Nmax], root[Nmax], score[Nmax], node_pos[Nmax], depth[Nmax];
int x, y, i, j, n, m, N, Root;
void dfs(int node, int lvl)
{
euler[++N] = node, depth[node] = lvl, node_pos[node] = N;
for (auto &it: G[node])
{
dfs(it, lvl + 1);
euler[++N] = node;
}
}
void build_rmq()
{
Log[1] = 0;
for (i = 2; i <= N; ++i)
Log[i] = Log[i / 2] + 1;
for (i = 1; i <= N; ++i)
rmq[0][i] = euler[i];
for (i = 1; i <= Log[N]; ++i)
for (j = 1; j <= N - (1 << (i - 1)); ++j)
{
int a = rmq[i - 1][j], b = rmq[i - 1][j + (1 << (i - 1))];
if (depth[a] < depth[b]) rmq[i][j] = a;
else rmq[i][j] = b;
}
}
int LCA(int x, int y)
{
x = node_pos[x], y = node_pos[y];
if (x > y) swap(x, y);
int len = Log[y - x + 1];
int a = rmq[len][x], b = rmq[len][y - (1 << len) + 1];
if (depth[a] < depth[b]) return a;
return b;
}
int main ()
{
freopen("concurs.in", "r", stdin);
freopen("concurs.out", "w", stdout);
scanf("%d %d\n", &n, &m);
for (i = 1; i <= n; ++i)
scanf("%d ", &score[i]);
for (i = 1; i < n; ++i)
{
scanf("%d %d\n", &x, &y);
G[x].push_back(y);
root[y] = 1;
}
for (i = 1; i <= n; ++i)
if (!root[i])
{
Root = i;
break;
}
dfs(Root, 0);
assert (N == 2 * n - 1);
build_rmq();
ans.first = -INT_MAX, ans.second = INT_MAX, ans.third = INT_MAX;
for (i = 1; i <= m; ++i)
{
scanf("%d %d\n", &x, &y);
int val = LCA(x, y);
int sol = score[val];
if (sol == ans.first)
{
if (ans.second == x) ans.third = y;
if (ans.second > x) ans.second = x, ans.third = y;
}
if (sol > ans.first)
ans.first = sol, ans.second = x, ans.third = y;
}
printf("%d %d %d\n", ans.first, ans.second, ans.third);
return 0;
}