#include <bits/stdc++.h>
using namespace std;
char ch;
bool fh;
inline void read(int &a) {
  for (fh = 0, ch = getchar(); ch < '0' || ch > '9'; ch = getchar())
    if (ch == '-') fh = 1;
  for (a = 0; ch >= '0' && ch <= '9'; ch = getchar()) (a *= 10) += ch - '0';
  if (fh) a = -a;
}
inline int randx0(int x) { return (rand() * rand() % x); }
int n;
int val[200010];
struct rec {
  int x, ne;
} Arre[400010];
int Arrmap[200010];
int Atop;
inline void ins(int f, int s) {
  Arre[++Atop].x = s;
  Arre[Atop].ne = Arrmap[f];
  Arrmap[f] = Atop;
}
int ans = 0;
bool Cut[200010];
int vis[200010];
int tim;
int Size[200010];
int pos, posf, area;
void focusDFS(int x) {
  int v, f = 0;
  vis[x] = tim;
  Size[x] = 1;
  for (v = Arrmap[x]; v; v = Arre[v].ne)
    if ((vis[Arre[v].x] != tim) && (!Cut[Arre[v].x])) {
      focusDFS(Arre[v].x);
      Size[x] += Size[Arre[v].x];
      f = max(f, Size[Arre[v].x]);
    }
  f = max(f, area - Size[x]);
  if (f < posf) pos = x, posf = f;
}
int Prime[200010];
int Ptop;
bool Unp[200010];
void PrimeGet(int uplen) {
  int vi, vj;
  for (vi = 2; vi <= uplen; vi++) {
    if (!Unp[vi]) Prime[++Ptop] = vi;
    for (vj = 1; vi * Prime[vj] <= uplen; vj++) {
      Unp[vi * Prime[vj]] = 1;
      if (!(vi % Prime[vj])) break;
    }
  }
}
inline int gcd(int a, int b) {
  for (int c = a % b; c; a = b, b = c, c = a % b)
    ;
  return b;
}
inline int power(int a, int b, int p) {
  long long s = 1, w = a;
  for (; b; b >>= 1) {
    if (b & 1) s = s * w % p;
    w = w * w % p;
  }
  return s;
}
int Fin[200010];
int Ftop;
int Pollar(int num, int c) {
  int x = 1 + randx0(num - 2), y = x, d, s = 1, t = 2;
  for (;;) {
    x = ((long long)x * x % num + c) % num;
    d = gcd(abs(x - y), num);
    if ((d != 1) && (d != num)) return d;
    if (x == y) return num;
    s++;
    if (s == t) {
      y = x;
      t <<= 1;
    }
  }
}
void decompose(int x) {
  if (!Unp[x]) {
    Fin[++Ftop] = x;
    return;
  }
  int y = x;
  for (; y >= x;) y = Pollar(x, 2 + randx0(x - 2));
  decompose(y);
  decompose(x / y);
}
int dist[2][200010], distvis[2][200010];
int Stk[200010];
int stktop;
bool INstk[200010];
void distDFS(int x, int gys, int step) {
  int v;
  vis[x] = tim;
  if (gys != 1) decompose(gys);
  for (v = 1; v <= Ftop; v++) {
    ans = max(ans, (dist[0][Fin[v]] - 1) * (distvis[0][Fin[v]] == tim) + step);
    dist[1][Fin[v]] = max(dist[1][Fin[v]] * (distvis[1][Fin[v]] == tim), step);
    distvis[1][Fin[v]] = tim;
    if (!INstk[Fin[v]]) {
      Stk[++stktop] = Fin[v];
      INstk[Fin[v]] = 1;
    }
  }
  Ftop = 0;
  for (v = Arrmap[x]; v; v = Arre[v].ne)
    if ((vis[Arre[v].x] != tim) && (!Cut[Arre[v].x]))
      distDFS(Arre[v].x, gcd(gys, val[Arre[v].x]), step + 1);
}
void Copy() {
  int x;
  for (; stktop; stktop--) {
    x = Stk[stktop];
    INstk[x] = 0;
    distvis[1][x] = tim - 1;
    dist[0][x] = max(dist[0][x] * (distvis[0][x] == tim), dist[1][x]);
    distvis[0][x] = tim;
    Stk[stktop] = 0;
  }
}
void Div(int root) {
  int v;
  if (area == 1) return;
  tim++;
  posf = area + 1;
  focusDFS(root);
  v = pos;
  tim++;
  posf = area + 1;
  focusDFS(pos);
  pos = v;
  Cut[pos] = 1;
  tim++;
  for (v = Arrmap[pos]; v; v = Arre[v].ne)
    if (!Cut[Arre[v].x]) {
      distDFS(Arre[v].x, gcd(val[pos], val[Arre[v].x]), 2);
      Copy();
    }
  for (v = Arrmap[pos]; v; v = Arre[v].ne)
    if (!Cut[Arre[v].x]) {
      area = Size[Arre[v].x];
      Div(Arre[v].x);
    }
}
int main() {
  int vi, u, v, maxv = 0;
  srand(time(NULL));
  read(n);
  for (vi = 1; vi <= n; vi++) read(val[vi]), maxv = max(maxv, val[vi]);
  PrimeGet(maxv);
  for (vi = 1; vi < n; vi++) {
    read(u);
    read(v);
    ins(u, v);
    ins(v, u);
  }
  area = n;
  Div(1);
  if (!ans)
    for (vi = 1; vi <= n; vi++)
      if (val[vi] != 1) {
        ans = 1;
        break;
      }
  printf("%d\n", ans);
}
