#include <bits/stdc++.h>
using namespace std;
const long long mx = 200000;
vector<long long> val[mx + 1];
vector<pair<long long, long long>> tr[mx + 1];
long long gcd(long long a, long long b) {
  while (b) tie(a, b) = make_tuple(b, a % b);
  return a;
}
template <typename t>
class DisjointSet {
 public:
  vector<t> dsu, SIZE;
  DisjointSet(t n) {
    dsu.resize(n + 1);
    SIZE.assign(n + 1, 1);
    iota(dsu.begin(), dsu.end(), 0);
  }
  t root(t a) { return dsu[a] == a ? a : dsu[a] = root(dsu[a]); }
  void join(t a, t b, t &res) {
    a = root(a);
    b = root(b);
    if (a == b) return;
    res -= (SIZE[a] * (SIZE[a] + 1) >> 1);
    res -= (SIZE[b] * (SIZE[b] + 1) >> 1);
    if (SIZE[a] < SIZE[b])
      dsu[a] = b, SIZE[b] += SIZE[a], res += (SIZE[b] * (SIZE[b] + 1) >> 1);
    else
      dsu[b] = a, SIZE[a] += SIZE[b], res += (SIZE[a] * (SIZE[a] + 1) >> 1);
  }
};
void solve() {
  long long n, x, y;
  cin >> n;
  long long a[n + 1], res[mx + 1];
  memset(res, 0, sizeof res);
  DisjointSet<long long> tree(n);
  for (long long i = 1; i <= n; i++) cin >> a[i], val[a[i]].push_back(i);
  for (long long i = 1; i < n; i++)
    cin >> x >> y, tr[(gcd(a[x], a[y]))].push_back({x, y});
  for (long long i = mx; i > 0; i--) {
    res[i] = 0;
    for (long long j = i; j <= mx; j += i) {
      res[i] -= res[j];
      for (auto &k : val[j]) tree.dsu[k] = k, tree.SIZE[k] = 1, res[i]++;
    }
    for (long long j = i; j <= mx; j += i)
      for (auto &k : tr[j]) tree.join(k.first, k.second, res[i]);
  }
  for (long long i = 1; i <= mx; i++)
    if (res[i] > 0) cout << i << " " << res[i] << "\n";
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  long long t(1);
  for (long long i = 1; i <= t; solve(), i++)
    ;
  return 0;
}
