#include <bits/stdc++.h>
using namespace std;
int n, tot;
int a[200005], pos[200005], dfn[200005], dep[200005], fa[200005][21];
struct edge {
  int t, first[200005], v[200005 << 1], nxt[200005 << 1];
  void add(int x, int y) { nxt[++t] = first[x], first[x] = t, v[t] = y; }
} T, VT;
int add(int x, int y) {
  return x + y >= 1000000007 ? x + y - 1000000007 : x + y;
}
int dec(int x, int y) { return x - y < 0 ? x - y + 1000000007 : x - y; }
int mul(int x, int y) { return 1ll * x * y % 1000000007; }
int power(int a, int b) {
  int ans = 1;
  for (; b; b >>= 1, a = mul(a, a))
    if (b & 1) ans = mul(ans, a);
  return ans;
}
int inv(int x) { return power(x, 1000000007 - 2); }
bool comp(const int &p, const int &q) { return dfn[p] < dfn[q]; }
int sum, prime[200005], mark[200005], mu[200005], phi[200005], f[200005];
void linear_sieves() {
  phi[1] = mu[1] = 1;
  for (int i = 2; i < 200005; ++i) {
    if (!mark[i]) prime[++sum] = i, mu[i] = 1000000007 - 1, phi[i] = i - 1;
    for (int j = 1; j <= sum && i * prime[j] < 200005; ++j) {
      mark[i * prime[j]] = 1;
      if (i % prime[j])
        mu[i * prime[j]] = 1000000007 - mu[i],
               phi[i * prime[j]] = phi[i] * (prime[j] - 1);
      else {
        mu[i * prime[j]] = 0, phi[i * prime[j]] = phi[i] * prime[j];
        break;
      }
    }
  }
  for (int i = 1; i < 200005; ++i) {
    int Inv = inv(phi[i]);
    for (int j = 1; i * j < 200005; ++j)
      f[i * j] = add(f[i * j], mul(mul(i, mu[j]), Inv));
  }
}
void dfs(int x) {
  dfn[x] = ++tot;
  for (int i = 1; i <= 20; ++i) fa[x][i] = fa[fa[x][i - 1]][i - 1];
  for (int i = T.first[x]; i; i = T.nxt[i]) {
    int to = T.v[i];
    if (to == fa[x][0]) continue;
    fa[to][0] = x, dep[to] = dep[x] + 1;
    dfs(to);
  }
}
int LCA(int x, int y) {
  if (dep[x] < dep[y]) swap(x, y);
  for (int i = 20; ~i; --i)
    if (dep[fa[x][i]] >= dep[y]) x = fa[x][i];
  if (x == y) return x;
  for (int i = 20; ~i; --i)
    if (fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];
  return fa[x][0];
}
namespace Virtual_Tree {
int sum, res, cnt, top;
int p[200005], S[200005], stk[200005];
void Insert(int x) {
  if (top == 1) {
    stk[++top] = x;
    return;
  }
  int lca = LCA(x, stk[top]);
  if (lca == stk[top]) {
    stk[++top] = x;
    return;
  }
  while (top > 1 && dfn[lca] <= dfn[stk[top - 1]])
    VT.add(stk[top - 1], stk[top]), top--;
  if (lca != stk[top]) VT.add(lca, stk[top]), stk[top] = lca;
  stk[++top] = x;
}
int dis(int x, int y) { return dep[x] + dep[y] - 2 * dep[LCA(x, y)]; }
void dp(int x) {
  for (int i = VT.first[x]; i; i = VT.nxt[i]) {
    int to = VT.v[i], len = dis(x, to);
    dp(to);
    res = add(res, mul(len, mul(dec(sum, S[to]), S[to])));
    S[x] = add(S[x], S[to]);
  }
}
void Clear(int x) {
  for (int i = VT.first[x]; i; i = VT.nxt[i]) Clear(VT.v[i]);
  S[x] = VT.first[x] = 0;
}
int calc(int x) {
  VT.t = cnt = sum = res = 0;
  for (int i = 1; i * x <= n; ++i)
    p[++cnt] = pos[i * x], S[p[cnt]] = phi[i * x], sum = add(sum, phi[i * x]);
  sort(p + 1, p + cnt + 1, comp), stk[top = 1] = 1;
  for (int i = 1; i <= cnt; ++i)
    if (p[i] != 1) Insert(p[i]);
  while (--top) VT.add(stk[top], stk[top + 1]);
  dp(1), Clear(1);
  res = mul(add(res, res), f[x]);
  return res;
}
}  // namespace Virtual_Tree
using namespace Virtual_Tree;
int main() {
  scanf("%d", &n), linear_sieves();
  for (int i = 1; i <= n; ++i) scanf("%d", &a[i]), pos[a[i]] = i;
  for (int i = 1, x, y; i < n; ++i) {
    scanf("%d%d", &x, &y);
    T.add(x, y), T.add(y, x);
  }
  dep[1] = 1, dfs(1);
  int ans = 0;
  for (int i = 1; i <= n; ++i) ans = add(ans, calc(i));
  printf("%d\n", mul(ans, inv(mul(n, n - 1))));
  return 0;
}
