#include <bits/stdc++.h>
using namespace std;
const long long N = 2e5 + 5;
long long a[N], n, f[N], mob[N], lst[N], cc, gud[N];
vector<long long> adj[N], idx[N], primes;
bitset<N> bs;
void sieve() {
  bs.set();
  bs[0] = bs[1] = false;
  for (long long i = 2; i <= N - 5; ++i)
    if (bs[i]) {
      for (long long j = i * i; j <= N - 5; j += i) bs[j] = false;
      primes.push_back(i);
    }
}
long long mobius(long long a) {
  long long PF_idx = 0, PF = primes[0];
  vector<long long> d;
  d.clear();
  while (PF * PF <= a) {
    long long cnt = 0;
    while (a % PF == 0) {
      a /= PF;
      cnt++;
    }
    if (cnt > 1) return 0;
    if (cnt == 1) d.push_back(PF);
    PF = primes[++PF_idx];
  }
  if (a) d.push_back(a);
  if ((long long)d.size() & 1)
    return -1;
  else
    return 1;
}
long long dfs(long long u, long long val) {
  long long t = 0;
  lst[u] = cc;
  for (long long v : adj[u])
    if (gud[a[v]] == cc && lst[v] != cc) t += dfs(v, val);
  return t + 1;
}
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  sieve();
  cin >> n;
  for (long long i = 1; i <= n; ++i) {
    cin >> a[i];
    idx[a[i]].push_back(i);
  }
  for (long long i = 1; i < n; ++i) {
    long long u, v;
    cin >> u >> v;
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  for (long long i = 1; i <= N - 5; ++i) {
    ++cc;
    long long tmp = 0;
    for (long long j = i; j <= N - 5; j += i) gud[j] = cc;
    for (long long j = i; j <= N - 5; j += i) {
      for (long long u : idx[j])
        if (lst[u] != cc) {
          long long sz = dfs(u, i);
          tmp += sz * (sz + 1) / 2;
        }
    }
    f[i] = tmp;
  }
  for (long long i = 1; i <= N - 5; ++i) mob[i] = mobius(i);
  for (long long i = 1; i <= N - 5; ++i) {
    long long res = f[i];
    for (long long j = 2; j <= (N - 5) / i; j++) res += f[i * j] * mob[j];
    if (res > 0) cout << i << ' ' << res << endl;
  }
  return 0;
}
