#include <bits/stdc++.h>
using namespace std;
template <class T>
bool umin(T& a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
bool umax(T& a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
const int N = 2e5 + 6;
int arr[N];
vector<int> adj[N], mem[N];
long long dp[N];
int ata[N], sz[N], vis[N];
long long all = 0;
int tap(int x) {
  if (ata[x] == x) return x;
  return ata[x] = tap(ata[x]);
}
long long f(int x) { return (x * 1LL * (x + 1)) / 2; }
void merge(int x, int y) {
  if ((x = tap(x)) == (y = tap(y))) return;
  if (sz[x] < sz[y]) swap(x, y);
  all -= f(sz[x]);
  all -= f(sz[y]);
  all += f(sz[x] + sz[y]);
  sz[x] += sz[y];
  ata[y] = x;
}
int main() {
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    int x;
    scanf("%d", &x);
    mem[x].push_back(i);
  }
  for (int i = 1; i < n; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  stack<int> st;
  for (int i = 1; i <= n; i++) ata[i] = i, sz[i] = 1;
  all = 0;
  for (int i = N - 4; i >= 1; i--) {
    for (int j = i; j < N; j += i) {
      if (i < j) dp[i] -= dp[j];
      for (__typeof((mem[j]).begin()) it = (mem[j]).begin();
           it != (mem[j]).end(); it++) {
        int nd = *it;
        vis[nd] = 1;
        st.push(nd);
        all++;
        for (int k = 0; k < int(adj[nd].size()); k++) {
          int to = adj[nd][k];
          if (vis[to]) merge(to, nd);
        }
      }
    }
    dp[i] += all;
    all = 0;
    while (!st.empty()) {
      int nd = st.top();
      st.pop();
      ata[nd] = nd;
      sz[nd] = 1;
      vis[nd] = 0;
    }
  }
  for (int i = 1; i < N; i++)
    if (dp[i]) printf("%d %lld\n", i, dp[i]);
  return 0;
}
