#include <bits/stdc++.h>
#pragma GCC optimize(3)
using namespace std;
long long n, k, a[200005];
long long p[200005], r[200005], sz[200005], ans[200005];
vector<pair<int, int> > G[200005];
vector<int> v[200005];
long long cur;
long long gcd(long long a, long long b) {
  if (b == 0) return a;
  return gcd(b, a % b);
}
long long find(long long x) {
  if (p[x] == x)
    return x;
  else
    return p[x] = find(p[x]);
}
void unite(long long x, long long y) {
  x = find(x);
  y = find(y);
  if (x == y) return;
  cur -= sz[x] * (sz[x] - 1) / 2;
  cur -= sz[y] * (sz[y] - 1) / 2;
  p[x] = y;
  sz[y] += sz[x];
  cur += sz[y] * (sz[y] - 1) / 2;
}
int main() {
  scanf("%lld", &n);
  for (long long i = 1; i <= n; i++) {
    scanf("%lld", &a[i]);
    v[a[i]].push_back(i);
  }
  for (long long i = 0; i < n - 1; i++) {
    long long u, v;
    scanf("%lld%lld", &u, &v);
    G[gcd(a[u], a[v])].push_back(pair<int, int>(u, v));
  }
  for (long long i = 1; i <= 200000; i++) {
    cur = 0;
    for (long long j = i; j <= 200000; j += i) {
      for (long long k = 0; k < (int)v[j].size(); k++) {
        long long node = v[j][k];
        p[node] = node, sz[node] = 1;
        cur++;
      }
    }
    for (long long j = i; j <= 200000; j += i) {
      for (long long k = 0; k < (int)G[j].size(); k++) {
        pair<int, int> e = G[j][k];
        unite(e.first, e.second);
      }
    }
    ans[i] = cur;
  }
  for (long long i = 200000; i >= 1; i--)
    for (long long j = 2 * i; j <= 200000; j += i) ans[i] -= ans[j];
  for (long long i = 1; i <= 200000; i++)
    if (ans[i]) printf("%lld %lld\n", i, ans[i]);
  return 0;
}
