#include <bits/stdc++.h>   using namespace std;   template <class T>   inline T bigmod(T p, T e, T M) {     long long ret = 1;     for (; e > 0; e >>= 1) {       if (e & 1) ret = (ret * p) % M;       p = (p * p) % M;     }     return (T)ret;   }   template <class T>   inline T gcd(T a, T b) {     if (b == 0) return a;     return gcd(b, a % b);   }   template <class T>   inline T lcm(T a, T b) {     return (a / gcd(a, b)) * b;   }   template <class T>   inline T modinverse(T a, T M) {     return bigmod(a, M - 2, M);   }   template <class T>   inline T bpow(T p, T e) {     long long ret = 1;     for (; e > 0; e >>= 1) {       if (e & 1) ret = (ret * p);       p = (p * p);     }     return (T)ret;   }   template <class T>   inline T gethash(T h[], T power[], int l, int r) {     if (r < l) return (T)0;     return h[l] - h[r + 1] * power[r - l + 1];   }   struct data {     data() {}     bool friend operator<(data a, data b) { return 0; }   };   int n, m, k;   long long N, M, K;   int a[200005];   long long ans[200005];   vector<int> adj[200005];   int subtree[200005];   bool bad[200005];   int tot = 0;   int cnt[200005];   unordered_set<int> st;   unordered_set<int>::iterator it;   unordered_map<int, int> mm[200005];   int _gcd(int a, int b) {     if (a == 0) return b;     if (b == 0) return a;     int p = _gcd(b, a % b);     return p;   }   void dfs(int u, int p) {     subtree[u] = 1;     tot++;     for (int i = 0; i < adj[u].size(); i++) {       int v = adj[u][i];       if (v == p || bad[v]) continue;       dfs(v, u);       subtree[u] += subtree[v];     }   }   int getcenter(int u, int p) {     for (int i = 0; i < adj[u].size(); i++) {       int v = adj[u][i];       if (v == p || bad[v]) continue;       if (subtree[v] > tot / 2) return getcenter(v, u);     }     return u;   }   void query(int u, int p, int g) {     g = _gcd(g, a[u]);     for (it = st.begin(); it != st.end(); it++) {       int x = *it;       int gc = _gcd(g, x);       ans[gc] += cnt[x];     }     for (int i = 0; i < adj[u].size(); i++) {       int v = adj[u][i];       if (v == p || bad[v]) continue;       query(v, u, g);     }   }   void update(int u, int p, int g) {     g = _gcd(a[u], g);     st.insert(g);     cnt[g]++;     for (int i = 0; i < adj[u].size(); i++) {       int v = adj[u][i];       if (v == p || bad[v]) continue;       update(v, u, g);     }   }   void decompose(int u, int p) {     tot = 0;     dfs(u, p);     int c = getcenter(u, p);     ans[a[c]]++;     cnt[a[c]] = 1;     st.insert(a[c]);     bad[c] = 1;     for (int i = 0; i < adj[c].size(); i++) {       int v = adj[c][i];       if (v == p || bad[v]) continue;       query(v, c, 0);       update(v, c, a[c]);     }     for (it = st.begin(); it != st.end(); it++) {       int x = *it;       cnt[x] = 0;     }     st.clear();     for (int i = 0; i < adj[c].size(); i++) {       int v = adj[c][i];       if (v == p || bad[v]) continue;       decompose(v, c);     }   }   int main() {     int t, tc = 1;     scanf( %d , &n);     for (int i = 1; i <= n; i++) {       scanf( %d , &a[i]);     }     for (int i = 1; i < n; i++) {       int u, v;       scanf( %d %d , &u, &v);       adj[u].push_back(v);       adj[v].push_back(u);     }     decompose(1, -1);     for (int i = 1; i <= 200000; i++) {       if (ans[i]) {         printf( %d %lld n , i, ans[i]);       }     }     return 0;   }