#include <bits/stdc++.h>
using namespace std;
template <typename... Args>
void print(Args... args) {
  ((cout << args << " "), ...);
}
const int MAXN = 200200;
namespace Task {
int leastPrimeDivisor[MAXN + 1];
vector<int> primes;
void sieve() {
  for (int i = 2; i <= MAXN; ++i) {
    if (leastPrimeDivisor[i] == 0) {
      leastPrimeDivisor[i] = i;
      primes.push_back(i);
    }
    for (int j = 0; j < (int)primes.size() &&
                    primes[j] <= leastPrimeDivisor[i] && i * primes[j] <= MAXN;
         ++j)
      leastPrimeDivisor[i * primes[j]] = primes[j];
  }
}
int n, a[MAXN], mark[MAXN], optimalDiameter = 0;
vector<int> link[MAXN], g[MAXN];
int findDiameter(int i) {
  mark[i] = 0;
  int diameter = 1;
  for (int j : g[i]) {
    if (mark[j]) {
      int childDiameter = findDiameter(j);
      optimalDiameter = max(optimalDiameter, diameter + childDiameter);
      diameter = max(diameter, childDiameter + 1);
    }
  }
  return diameter;
}
void solve() {
  sieve();
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &a[i]);
    int x = a[i];
    if (x > 1) {
      optimalDiameter = 1;
    }
    while (x > 1) {
      int d = leastPrimeDivisor[x];
      while (x % d == 0) x /= d;
      link[d].emplace_back(i);
    }
  }
  for (int i = 2; i <= n; ++i) {
    int x, y;
    scanf("%d %d", &x, &y);
    g[x].emplace_back(y);
    g[y].emplace_back(x);
  }
  for (int prime : primes) {
    if (link[prime].size() <= optimalDiameter) {
      continue;
    }
    for (int i : link[prime]) {
      mark[i] = 1;
    }
    for (int i : link[prime]) {
      if (mark[i]) {
        findDiameter(i);
      }
    }
  }
  printf("%d\n", optimalDiameter);
}
}  // namespace Task
int main() {
  Task::solve();
  return 0;
}
