#include <bits/stdc++.h>
using namespace std;
const int N = 200043;
int d[N];
void sieve() {
  vector<int> pr;
  for (int i = 2; i < N; i++) {
    if (d[i] == 0) {
      d[i] = i;
      pr.push_back(i);
    }
    for (auto x : pr) {
      if (x > d[i] || x * 1ll * i >= N) break;
      d[i * x] = x;
    }
  }
}
int mobius(int x) {
  int last = -1;
  int res = 1;
  while (x != 1) {
    if (last == d[x])
      res = 0;
    else
      res = -res;
    last = d[x];
    x /= d[x];
  }
  return res;
}
int mb[N];
vector<int> need_bfs[N];
int used[N];
vector<int> g[N];
int a[N];
int cc = 0;
int q[N];
int hd, tl;
int good[N];
int bfs(int x, int gc) {
  hd = 0;
  tl = 0;
  q[tl++] = x;
  used[x] = cc;
  while (hd < tl) {
    int z = q[hd++];
    for (auto y : g[z]) {
      if (good[a[y]] == cc && used[y] < cc) {
        used[y] = cc;
        q[tl++] = y;
      }
    }
  }
  return tl;
}
long long ans1[N];
long long ans2[N];
int main() {
  sieve();
  for (int i = 1; i < N; i++) mb[i] = mobius(i);
  int n;
  scanf("%d", &n);
  for (int i = 0; i < n; i++) scanf("%d", &a[i]);
  for (int i = 0; i < n - 1; i++) {
    int x, y;
    scanf("%d %d", &x, &y);
    --x;
    --y;
    g[x].push_back(y);
    g[y].push_back(x);
  }
  for (int i = 0; i < n; i++) {
    need_bfs[a[i]].push_back(i);
  }
  for (int i = 200000; i >= 1; i--) {
    cc++;
    for (int j = i; j <= 200000; j += i) good[j] = cc;
    for (int j = i; j <= 200000; j += i)
      for (auto x : need_bfs[j]) {
        if (used[x] == cc) continue;
        int z = bfs(x, i);
        ans1[i] += z * 1ll * (z + 1) / 2;
      }
    for (int j = i, k = 1; j <= 200000; j += i, k++) ans2[i] += mb[k] * ans1[j];
  }
  for (int i = 1; i <= 200000; i++)
    if (ans2[i]) printf("%d %lld\n", i, ans2[i]);
  return 0;
}
