#include <bits/stdc++.h>
using namespace std;
const int maxn = 200010, mod = 1e9 + 7;
template <typename Tp>
inline int getmin(Tp &x, Tp y) {
  return y < x ? x = y, 1 : 0;
}
template <typename Tp>
inline int getmax(Tp &x, Tp y) {
  return y > x ? x = y, 1 : 0;
}
template <typename Tp>
inline void read(Tp &x) {
  x = 0;
  int f = 0;
  char ch = getchar();
  while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
  if (ch == '-') f = 1, ch = getchar();
  while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
  if (f) x = -x;
}
int n, ans, a[maxn], id[maxn], f[maxn], g[maxn];
namespace Math {
int tot, pri[maxn], phi[maxn], mu[maxn];
int pls(int x, int y) { return x + y >= mod ? x + y - mod : x + y; }
int dec(int x, int y) { return x < y ? x - y + mod : x - y; }
int power(int x, int y) {
  int res = 1;
  for (; y; y >>= 1, x = (long long)x * x % mod)
    if (y & 1) res = (long long)res * x % mod;
  return res;
}
void init() {
  phi[1] = mu[1] = 1;
  for (int i = 2; i <= n; i++) {
    if (!phi[i]) phi[i] = i - 1, mu[i] = mod - 1, pri[++tot] = i;
    for (int j = 1; j <= tot && i * pri[j] <= n; j++) {
      if (i % pri[j] == 0) {
        phi[i * pri[j]] = phi[i] * pri[j];
        mu[i * pri[j]] = 0;
        break;
      }
      phi[i * pri[j]] = phi[i] * (pri[j] - 1);
      mu[i * pri[j]] = dec(0, mu[i]);
    }
  }
}
}  // namespace Math
using Math::dec;
using Math::mu;
using Math::phi;
using Math::pls;
using Math::power;
namespace Tree {
struct data {
  int v, nxt;
} edge[maxn << 1];
int p, dfc, head[maxn], dfn[maxn], f[maxn], dep[maxn], sz[maxn], hs[maxn],
    top[maxn];
int cmp(const int &x, const int &y) { return dfn[x] < dfn[y]; }
void insert(int u, int v) {
  edge[++p] = (data){v, head[u]};
  head[u] = p;
  edge[++p] = (data){u, head[v]};
  head[v] = p;
}
void dfs1(int x) {
  sz[x] = 1;
  dep[x] = dep[f[x]] + 1;
  dfn[x] = ++dfc;
  for (int i = head[x]; i; i = edge[i].nxt)
    if (edge[i].v ^ f[x]) {
      f[edge[i].v] = x;
      dfs1(edge[i].v);
      sz[x] += sz[edge[i].v];
      if (sz[edge[i].v] > sz[hs[x]]) hs[x] = edge[i].v;
    }
}
void dfs2(int x, int s) {
  top[x] = s;
  if (hs[x]) dfs2(hs[x], s);
  for (int i = head[x]; i; i = edge[i].nxt)
    if (edge[i].v ^ f[x] && edge[i].v ^ hs[x]) dfs2(edge[i].v, edge[i].v);
}
int getlca(int x, int y) {
  int fx = top[x], fy = top[y];
  while (fx ^ fy) {
    if (dep[fx] < dep[fy]) swap(x, y), swap(fx, fy);
    x = f[fx];
    fx = top[x];
  }
  return dep[x] < dep[y] ? x : y;
}
}  // namespace Tree
using Tree::cmp;
using Tree::dep;
using Tree::getlca;
using Tree::insert;
namespace Virtual_Tree {
struct data {
  int v, nxt;
} edge[maxn << 1];
int p, m, top, rt, sum, res, head[maxn], q[maxn], stk[maxn], tag[maxn];
void insert(int u, int v) {
  edge[++p] = (data){v, head[u]};
  head[u] = p;
  edge[++p] = (data){u, head[v]};
  head[v] = p;
}
void build() {
  int t = 0;
  top = 0;
  sort(q + 1, q + m + 1, cmp);
  for (int i = 1; i <= m; i++) {
    while (top) {
      t = getlca(q[i], stk[top]);
      if (top > 1 && dep[t] < dep[stk[top - 1]]) {
        insert(stk[top - 1], stk[top]);
        --top;
      } else if (dep[t] < dep[stk[top]]) {
        insert(t, stk[top]);
        --top;
        break;
      } else
        break;
    }
    if (stk[top] ^ t) {
      stk[++top] = t;
      if (!rt || dep[t] < dep[rt]) rt = t;
    }
    stk[++top] = q[i];
    tag[q[i]] = 1;
    if (!rt || dep[q[i]] < dep[rt]) rt = t;
  }
  for (; top > 1; --top) insert(stk[top - 1], stk[top]);
}
int dfs(int x, int pre) {
  int sp = tag[x] ? phi[a[x]] : 0, sum = 0, tmp;
  for (int i = head[x]; i; i = edge[i].nxt)
    if (edge[i].v ^ pre) {
      tmp = dfs(edge[i].v, x);
      sum = (sum + (long long)sp * tmp) % mod;
      sp = pls(sp, tmp);
    }
  head[x] = 0;
  res = dec(res, 4ll * dep[x] * sum % mod);
  return sp;
}
int work() {
  res = sum = rt = 0;
  build();
  for (int i = 1; i <= m; i++) sum = pls(sum, phi[a[q[i]]]);
  for (int i = 1; i <= m; i++)
    res = (res +
           (long long)phi[a[q[i]]] * dep[q[i]] % mod * dec(sum, phi[a[q[i]]])) %
          mod;
  sum = 0;
  for (int i = 1; i <= m; i++)
    sum = (sum + (long long)phi[a[q[i]]] * dep[q[i]]) % mod;
  for (int i = 1; i <= m; i++)
    res = (res + (long long)phi[a[q[i]]] *
                     dec(sum, (long long)phi[a[q[i]]] * dep[q[i]] % mod)) %
          mod;
  dfs(rt, rt);
  p = 0;
  for (int i = 1; i <= m; i++) tag[q[i]] = 0;
  return res;
}
}  // namespace Virtual_Tree
using Virtual_Tree::m;
using Virtual_Tree::q;
using Virtual_Tree::work;
void input() {
  int u, v;
  read(n);
  for (int i = 1; i <= n; i++) {
    read(a[i]);
    id[a[i]] = i;
  }
  for (int i = 1; i < n; i++) {
    read(u);
    read(v);
    insert(u, v);
  }
  Math::init();
  Tree::dfs1(1);
  Tree::dfs2(1, 1);
}
int main() {
  input();
  for (int i = 1; i <= n; i++) {
    m = 0;
    for (int j = i; j <= n; j += i) q[++m] = id[j];
    g[i] = work();
  }
  for (int i = 1; i <= n; i++) {
    for (int j = i, r = 1; j <= n; j += i, ++r)
      f[i] = (f[i] + (long long)mu[r] * g[j]) % mod;
    ans = (ans + (long long)f[i] * i % mod * power(phi[i], mod - 2)) % mod;
  }
  ans = (long long)ans * power((long long)n * (n - 1) % mod, mod - 2) % mod;
  printf("%d\n", ans);
  return 0;
}
