#include<bits/stdc++.h>

typedef long long ll;
typedef long double ld;
using namespace std;
//mt19937_64 mrand(chrono::steady_clock::now().time_since_epoch().count());
#define ii for(int i=1;i<=n;++i)
#define ji for(int j=1;j<=n;++j)
#define jj for(int j=1;j<=m;++j)
#define ij for(int i=1;i<=m;++i)
#define sz(x) ((ll)x.size())
#define all(x) x.begin(),x.end()
#define al(x) x+1,x+1+n
#define asd cout<<"ok"<<endl;
#define asdd cout<<"okok"<<endl;
#define pii pair<int,int>
#define vi vector<int>
#define vvi vector<vector<int>>
#define vl vector<ll>
#define vii vector<pair<int,int>>
#define pr(v) for(auto i:v) cout<<i<<" ";cout<<endl
#define prt(a, l, r) for(auto i=l;i<=r;++i) cout<<a[i]<<" ";cout<<endl;
#define pc(x) __builtin_popcount(x)
#define pb push_back

const int maxn = 200005;
int sz[maxn], mx[maxn], vis[maxn], a[maxn];
int N,rt;
vector<int> g[maxn];
void getrt(int u, int fa) {
    sz[u] = 1; mx[u] = 0;
    for(int v : g[u]) {
        if(vis[v] || v == fa) continue;
        getrt(v, u);
        sz[u] += sz[v];
        mx[u] = max(mx[u], sz[v]);
    }
    mx[u] = max(mx[u], N - sz[u]);
    if(mx[u] < mx[rt]) rt = u;
}
int cnt[maxn];

int G[505][505];
int Gcd(int a,int b) {return b == 0 ? a : Gcd(b, a % b);}
void init() {
    for(int i=0;i<=500;++i) for(int j=0;j<=500;++j) G[i][j]=Gcd(i,j);
}
inline int gcd(int a, int b) {
    if(a <= 500 && b <= 500) return G[a][b];
    return b == 0 ? a : gcd(b, a % b);
}

unordered_map<int,int> mp;
void cal(int u,int fa,int w) {
    for(auto p : mp) cnt[gcd(p.first, w)] += p.second;
    for(int v : g[u]) {
        if(v == fa || vis[v]) continue;
        cal(v, u, gcd(w, a[v]));
    }
}

void add(int u,int fa,int w) {
    mp[w]++;
    for(int v : g[u]) {
        if(v == fa || vis[v]) continue;
        add(v, u, gcd(w, a[v]));
    }
}
void calc(int u) {
    mp[a[u]]++;
    for(int v : g[u]) {
        if(vis[v]) continue;
        cal(v, u, gcd(a[u], a[v]));
        add(v, u, gcd(a[u], a[v]));
    }
    mp.clear();
}
void solve(int u) {
    vis[u] = 1; calc(u);
    for(int v : g[u]) {
        if(vis[v]) continue;
        N = sz[v]; rt = 0;
        getrt(v, u);
        solve(rt);
    }
}
inline int read()
{
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
    return x*f;
}
int main() {
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    init();
    int n = read();
    for(int i=1;i<=n;++i) cin >> a[i], cnt[a[i]]++;
    for(int i=1;i<n;++i) {
        int u = read(), v = read();
        g[u].push_back(v);
        g[v].push_back(u);
    }
    N = n; mx[0] = 1e9; rt = 0;
    getrt(1, -1);
    solve(rt);
    for(int i=1;i<maxn;++i) {
        if(cnt[i]) cout << i << " " << cnt[i] << endl;
    }
}


#include<bits/stdc++.h>

typedef long long ll;
typedef long double ld;
using namespace std;
//mt19937_64 mrand(chrono::steady_clock::now().time_since_epoch().count());
#define ii for(int i=1;i<=n;++i)
#define ji for(int j=1;j<=n;++j)
#define jj for(int j=1;j<=m;++j)
#define ij for(int i=1;i<=m;++i)
#define sz(x) ((ll)x.size())
#define all(x) x.begin(),x.end()
#define al(x) x+1,x+1+n
#define asd cout<<"ok"<<endl;
#define asdd cout<<"okok"<<endl;
#define pii pair<int,int>
#define vi vector<int>
#define vvi vector<vector<int>>
#define vl vector<ll>
#define vii vector<pair<int,int>>
#define pr(v) for(auto i:v) cout<<i<<" ";cout<<endl
#define prt(a, l, r) for(auto i=l;i<=r;++i) cout<<a[i]<<" ";cout<<endl;
#define pc(x) __builtin_popcount(x)
#define pb push_back

const int maxn = 200005;
int sz[maxn], mx[maxn], vis[maxn], a[maxn];
int N,rt;
vector<int> g[maxn];
void getrt(int u, int fa) {
    sz[u] = 1; mx[u] = 0;
    for(int v : g[u]) {
        if(vis[v] || v == fa) continue;
        getrt(v, u);
        sz[u] += sz[v];
        mx[u] = max(mx[u], sz[v]);
    }
    mx[u] = max(mx[u], N - sz[u]);
    if(mx[u] < mx[rt]) rt = u;
}
int cnt[maxn];

int G[505][505];
int Gcd(int a,int b) {return b == 0 ? a : Gcd(b, a % b);}
void init() {
    for(int i=0;i<=500;++i) for(int j=0;j<=500;++j) G[i][j]=Gcd(i,j);
}
inline int gcd(int a, int b) {
    if(a <= 500 && b <= 500) return G[a][b];
    return b == 0 ? a : gcd(b, a % b);
}

unordered_map<int,int> mp;
void cal(int u,int fa,int w) {
    for(auto p : mp) cnt[gcd(p.first, w)] += p.second;
    for(int v : g[u]) {
        if(v == fa || vis[v]) continue;
        cal(v, u, gcd(w, a[v]));
    }
}

void add(int u,int fa,int w) {
    mp[w]++;
    for(int v : g[u]) {
        if(v == fa || vis[v]) continue;
        add(v, u, gcd(w, a[v]));
    }
}
void calc(int u) {
    mp[a[u]]++;
    for(int v : g[u]) {
        if(vis[v]) continue;
        cal(v, u, gcd(a[u], a[v]));
        add(v, u, gcd(a[u], a[v]));
    }
    mp.clear();
}
void solve(int u) {
    vis[u] = 1; calc(u);
    for(int v : g[u]) {
        if(vis[v]) continue;
        N = sz[v]; rt = 0;
        getrt(v, u);
        solve(rt);
    }
}
inline int read()
{
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
    return x*f;
}
int main() {
    init();
    int n = read();
    for(int i=1;i<=n;++i) a[i] = read(), cnt[a[i]]++;
    for(int i=1;i<n;++i) {
        int u = read(), v = read();
        g[u].push_back(v);
        g[v].push_back(u);
    }
    N = n; mx[0] = 1e9; rt = 0;
    getrt(1, -1);
    solve(rt);
    for(int i=1;i<maxn;++i) {
        if(cnt[i]) cout << i << " " << cnt[i] << endl;
    }
}


#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stdlib.h>
#include <time.h>
#include <iomanip>
#include <math.h>
#include <bitset>
#include <string.h>

using namespace std;

#define taskname "A"
#define LL long long
#define uLL unsigned long long
#define FOR(i,l,r) for(int i = l; i <= r; ++i)
#define REP(i,l,r) for(int i = l; i < r; ++i)
#define FORD(i,r,l) for(int i = r; i >= l; --i)
#define REPD(i,r,l) for(int i = r; i > l; --i)
#define sz(x) (int)((x).size())
#define all(x) (x).begin(), (x).end()
#define debug(x) { cerr << #x << " = " << x << endl; }
#define sci(x) int x; scanf("%d", &x);
#define scii(x, y) int x, y; scanf("%d %d", &x, &y);
#define sciii(x, y, z) int x, y, z; scanf("%d %d %d", &x, &y, &z);
#define pi pair<int,int>
#define pii pair<int,pi>
#define mp make_pair
#define fi first
#define se second
#define pb push_back
#define _USE_MATH_DEFINES
/* M_PI */
#define SetLength2(a, n, t) a=((t*) calloc(n, sizeof(t))) + (n)/2

const int N = 2e5 + 1;
const LL oo = 1e17 + 11;

int tcases = 1;

int n,m,a[N],sz[N],val[N];
vector <int> e[N],divisors[N];
long long res[N];
bool cen[N];

int gcd(int x,int y){
    return y == 0 ? x : gcd(y,x % y);
}
void dfs(int u,int p = 0){
    sz[u] = 1;
    for(int v : e[u]){
        if(v == p || cen[v]) continue;
        dfs(v,u);
        sz[u] += sz[v];
    }
}
int find(int u,int p = 0,int total = 0){
    for(int v : e[u]){
        if(v == p || cen[v]) continue;
        if(sz[v] * 2 > total) return find(v,u,total);
    }
    return u;
}
void dfs0(int u,int root,int curGcd,int p = 0){
    val[u] = curGcd;
    for(int x : divisors[curGcd]){
        ++res[x];
    }
    for(int v : e[u]){
        if(v == p || cen[v]) continue;
        dfs0(v,root,gcd(curGcd,a[v]),u);
    }
}
int cnt[N];

void dfs1(int u,int p = 0,bool added = 0){
    for(int x : divisors[val[u]]){
        if(added) ++cnt[x];
        else{
            res[x] += cnt[x];
        }
    }
    for(int v : e[u]){
        if(v == p || cen[v]) continue;
        dfs1(v,u,added);
    }
}

void dfs2(int u,int p = 0){
    for(int x : divisors[val[u]]) cnt[x] = 0;
    for(int v : e[u]){
        if(v == p || cen[v]) continue;
        dfs2(v,u);
    }
}
void calculate(int u){
    dfs(u);
    int centroid = find(u,u,sz[u]);
    cen[centroid] = 1;
    dfs0(centroid,centroid,a[centroid]);

    for(int v : e[centroid]) if(!cen[v]){
        dfs1(v);
        dfs1(v,v,1);
    }

    dfs2(centroid); // delete

    for(int v : e[centroid]) if(!cen[v]){
        calculate(v);
    }
}
void testcase(){
    scanf("%d",&n);
    FOR(i,1,n) scanf("%d",&a[i]);
    REP(i,1,n){
        int u,v;
        scanf("%d%d",&u,&v);
        e[u].pb(v);
        e[v].pb(u);
    }

    int total = 0;
    REP(i,1,N){
        FOR(j,1,(N - 1)/i){
            divisors[j * i].pb(i);
            ++total;
        }
    }

    calculate(1);

    FORD(i,N - 1,1){
        FOR(j,2,(N - 1)/i){
            int k = j * i;
            res[i] -= res[k];
        }
    }

    REP(i,1,N){
        if(res[i] > 0){
            printf("%d %lli\n",i,res[i]);
        }
    }
}

int main(){
    #ifndef ONLINE_JUDGE
        freopen(taskname".INP","r",stdin);
        freopen(taskname".OUT","w",stdout);
    #else
        // online submission
    #endif

    //scanf("%d",&tcases);

    FOR(i,1,tcases) testcase();

    cerr << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";

    return 0;
}


#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stdlib.h>
#include <time.h>
#include <iomanip>
#include <math.h>
#include <bitset>
#include <string.h>

using namespace std;

#define taskname "A"
#define LL long long
#define uLL unsigned long long
#define FOR(i,l,r) for(int i = l; i <= r; ++i)
#define REP(i,l,r) for(int i = l; i < r; ++i)
#define FORD(i,r,l) for(int i = r; i >= l; --i)
#define REPD(i,r,l) for(int i = r; i > l; --i)
#define sz(x) (int)((x).size())
#define all(x) (x).begin(), (x).end()
#define debug(x) { cerr << #x << " = " << x << endl; }
#define sci(x) int x; scanf("%d", &x);
#define scii(x, y) int x, y; scanf("%d %d", &x, &y);
#define sciii(x, y, z) int x, y, z; scanf("%d %d %d", &x, &y, &z);
#define pi pair<int,int>
#define pii pair<int,pi>
#define mp make_pair
#define fi first
#define se second
#define pb push_back
#define _USE_MATH_DEFINES
/* M_PI */
#define SetLength2(a, n, t) a=((t*) calloc(n, sizeof(t))) + (n)/2

const int N = 2e5 + 1;
const LL oo = 1e17 + 11;

int tcases = 1;

int n,m,a[N],sz[N],val[N];
vector <int> e[N],divisors[N];
long long res[N];
bool cen[N];

int gcd(int x,int y){
    return y == 0 ? x : gcd(y,x % y);
}
void dfs(int u,int p = 0){
    for(int x : divisors[val[u]]) cnt[x] = 0;
    sz[u] = 1;
    for(int v : e[u]){
        if(v == p || cen[v]) continue;
        dfs(v,u);
        sz[u] += sz[v];
    }
}
int find(int u,int p = 0,int total = 0){
    for(int v : e[u]){
        if(v == p || cen[v]) continue;
        if(sz[v] * 2 > total) return find(v,u,total);
    }
    return u;
}
void dfs0(int u,int root,int curGcd,int p = 0){
    val[u] = curGcd;
    for(int x : divisors[curGcd]){
        ++res[x];
    }
    for(int v : e[u]){
        if(v == p || cen[v]) continue;
        dfs0(v,root,gcd(curGcd,a[v]),u);
    }
}
int cnt[N];

void dfs1(int u,int p = 0,bool added = 0){
    for(int x : divisors[val[u]]){
        if(added) ++cnt[x];
        else{
            res[x] += cnt[x];
        }
    }
    for(int v : e[u]){
        if(v == p || cen[v]) continue;
        dfs1(v,u,added);
    }
}

void dfs2(int u,int p = 0){
    for(int x : divisors[val[u]]) cnt[x] = 0;
    for(int v : e[u]){
        if(v == p || cen[v]) continue;
        dfs2(v,u);
    }
}
void calculate(int u){
    dfs(u); // delete old values
    int centroid = find(u,u,sz[u]);
    cen[centroid] = 1;
    dfs0(centroid,centroid,a[centroid]);

    for(int v : e[centroid]) if(!cen[v]){
        dfs1(v);
        dfs1(v,v,1);
    }

    for(int v : e[centroid]) if(!cen[v]){
        calculate(v);
    }
}
void testcase(){
    scanf("%d",&n);
    FOR(i,1,n) scanf("%d",&a[i]);
    REP(i,1,n){
        int u,v;
        scanf("%d%d",&u,&v);
        e[u].pb(v);
        e[v].pb(u);
    }

    int total = 0;
    REP(i,1,N){
        FOR(j,1,(N - 1)/i){
            divisors[j * i].pb(i);
            ++total;
        }
    }

    calculate(1);

    FORD(i,N - 1,1){
        FOR(j,2,(N - 1)/i){
            int k = j * i;
            res[i] -= res[k];
        }
    }

    REP(i,1,N){
        if(res[i] > 0){
            printf("%d %lli\n",i,res[i]);
        }
    }
}

int main(){
    #ifndef ONLINE_JUDGE
        freopen(taskname".INP","r",stdin);
        freopen(taskname".OUT","w",stdout);
    #else
        // online submission
    #endif

    //scanf("%d",&tcases);

    FOR(i,1,tcases) testcase();

    cerr << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";

    return 0;
}


#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stdlib.h>
#include <time.h>
#include <iomanip>
#include <math.h>
#include <bitset>
#include <string.h>

using namespace std;

#define taskname "A"
#define LL long long
#define uLL unsigned long long
#define FOR(i,l,r) for(int i = l; i <= r; ++i)
#define REP(i,l,r) for(int i = l; i < r; ++i)
#define FORD(i,r,l) for(int i = r; i >= l; --i)
#define REPD(i,r,l) for(int i = r; i > l; --i)
#define sz(x) (int)((x).size())
#define all(x) (x).begin(), (x).end()
#define debug(x) { cerr << #x << " = " << x << endl; }
#define sci(x) int x; scanf("%d", &x);
#define scii(x, y) int x, y; scanf("%d %d", &x, &y);
#define sciii(x, y, z) int x, y, z; scanf("%d %d %d", &x, &y, &z);
#define pi pair<int,int>
#define pii pair<int,pi>
#define mp make_pair
#define fi first
#define se second
#define pb push_back
#define _USE_MATH_DEFINES
/* M_PI */
#define SetLength2(a, n, t) a=((t*) calloc(n, sizeof(t))) + (n)/2

const int N = 2e5 + 1;
const LL oo = 1e17 + 11;

int tcases = 1;

int n,m,a[N],sz[N],val[N];
vector <int> e[N],divisors[N];
long long res[N];
bool cen[N];

int gcd(int x,int y){
    return y == 0 ? x : gcd(y,x % y);
}
void dfs(int u,int p = 0){
    sz[u] = 1;
    for(int v : e[u]){
        if(v == p || cen[v]) continue;
        dfs(v,u);
        sz[u] += sz[v];
    }
}
int find(int u,int p = 0,int total = 0){
    for(int v : e[u]){
        if(v == p || cen[v]) continue;
        if(sz[v] * 2 > total) return find(v,u,total);
    }
    return u;
}
void dfs0(int u,int root,int curGcd,int p = 0){
    val[u] = curGcd;
    for(int x : divisors[curGcd]){
        ++res[x];
    }
    for(int v : e[u]){
        if(v == p || cen[v]) continue;
        dfs0(v,root,gcd(curGcd,a[v]),u);
    }
}
int cnt[N];

void dfs1(int u,int p = 0,bool added = 0){
    for(int x : divisors[val[u]]){
        if(added) ++cnt[x];
        else{
            res[x] += cnt[x];
        }
    }
    for(int v : e[u]){
        if(v == p || cen[v]) continue;
        dfs1(v,u,added);
    }
}

void dfs2(int u,int p = 0){
    for(int x : divisors[val[u]]) cnt[x] = 0;
    for(int v : e[u]){
        if(v == p || cen[v]) continue;
        dfs2(v,u);
    }
}
void calculate(int u){
    dfs(u);
    int centroid = find(u,u,sz[u]);
    cen[centroid] = 1;
    dfs0(centroid,centroid,a[centroid]);

    for(int v : e[centroid]) if(!cen[v]){
        dfs1(v);
        dfs1(v,v,1);
    }

    dfs2(centroid); // delete

    for(int v : e[centroid]) if(!cen[v]){
        calculate(v);
    }
}
void testcase(){
    scanf("%d",&n);
    FOR(i,1,n) scanf("%d",&a[i]);
    REP(i,1,n){
        int u,v;
        scanf("%d%d",&u,&v);
        e[u].pb(v);
        e[v].pb(u);
    }

    int total = 0;
    REP(i,1,N){
        REP(j,1,(N - 1)/i){
            divisors[j * i].pb(i);
            ++total;
        }
    }
    calculate(1);

    FORD(i,N - 1,1){
        REP(j,2,(N - 1)/i){
            int k = j * i;
            res[i] -= res[k];
        }
    }

    REP(i,1,N){
        if(res[i] > 0){
            printf("%d %lli\n",i,res[i]);
        }
    }
}

int main(){
    #ifndef ONLINE_JUDGE
        freopen(taskname".INP","r",stdin);
        freopen(taskname".OUT","w",stdout);
    #else
        // online submission
    #endif

    //scanf("%d",&tcases);

    FOR(i,1,tcases) testcase();

    cerr << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";

    return 0;
}


#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stdlib.h>
#include <time.h>
#include <iomanip>
#include <math.h>
#include <bitset>
#include <string.h>

using namespace std;

#define taskname "A"
#define LL long long
#define uLL unsigned long long
#define FOR(i,l,r) for(int i = l; i <= r; ++i)
#define REP(i,l,r) for(int i = l; i < r; ++i)
#define FORD(i,r,l) for(int i = r; i >= l; --i)
#define REPD(i,r,l) for(int i = r; i > l; --i)
#define sz(x) (int)((x).size())
#define all(x) (x).begin(), (x).end()
#define debug(x) { cerr << #x << " = " << x << endl; }
#define sci(x) int x; scanf("%d", &x);
#define scii(x, y) int x, y; scanf("%d %d", &x, &y);
#define sciii(x, y, z) int x, y, z; scanf("%d %d %d", &x, &y, &z);
#define pi pair<int,int>
#define pii pair<int,pi>
#define mp make_pair
#define fi first
#define se second
#define pb push_back
#define _USE_MATH_DEFINES
/* M_PI */
#define SetLength2(a, n, t) a=((t*) calloc(n, sizeof(t))) + (n)/2

const int N = 2e5 + 1;
const LL oo = 1e17 + 11;

int tcases = 1;

int n,m,a[N],sz[N],val[N];
vector <int> e[N],divisors[N];
long long res[N];
bool cen[N];

int gcd(int x,int y){
    return y == 0 ? x : gcd(y,x % y);
}
void dfs(int u,int p = 0){
    sz[u] = 1;
    for(int v : e[u]){
        if(v == p || cen[v]) continue;
        dfs(v,u);
        sz[u] += sz[v];
    }
}
int find(int u,int p = 0,int total = 0){
    for(int v : e[u]){
        if(v == p || cen[v]) continue;
        if(sz[v] * 2 > total) return find(v,u,total);
    }
    return u;
}
void dfs0(int u,int root,int curGcd,int p = 0){
    val[u] = curGcd;
    for(int x : divisors[curGcd]){
        ++res[x];
    }
    for(int v : e[u]){
        if(v == p || cen[v]) continue;
        dfs0(v,root,gcd(curGcd,a[v]),u);
    }
}
int cnt[N];

void dfs1(int u,int p = 0,bool added = 0){
    for(int x : divisors[val[u]]){
        if(added) ++cnt[x];
        else{
            res[x] += cnt[x];
        }
    }
    for(int v : e[u]){
        if(v == p || cen[v]) continue;
        dfs1(v,u,added);
    }
}

void dfs2(int u,int p = 0){
    for(int x : divisors[val[u]]) cnt[x] = 0;
    for(int v : e[u]){
        if(v == p || cen[v]) continue;
        dfs2(v,u);
    }
}
void calculate(int u){
    dfs(u);
    int centroid = find(u,u,sz[u]);
    cen[centroid] = 1;
    dfs0(centroid,centroid,a[centroid]);

    for(int v : e[centroid]) if(!cen[v]){
        dfs1(v);
        dfs1(v,v,1);
    }

    dfs2(centroid); // delete

    for(int v : e[centroid]) if(!cen[v]){
        calculate(v);
    }
}
void testcase(){
    scanf("%d",&n);
    FOR(i,1,n) scanf("%d",&a[i]);
    REP(i,1,n){
        int u,v;
        scanf("%d%d",&u,&v);
        e[u].pb(v);
        e[v].pb(u);
    }

    int total = 0;
    REP(i,1,N){
        REP(j,1,(N - 1)/i){
            divisors[j * i].pb(i);
            ++total;
        }
    }
    calculate(1);

    FORD(i,N - 1,1){
        REP(j,2,(N - 1)/i){
            int k = j * i;
            res[i] -= res[k];
        }
    }

    FOR(i,1,n){
        --res[a[i]];
    }

    REP(i,1,N){
        if(res[i] > 0){
            printf("%d %lli\n",i,res[i]);
        }
    }
}

int main(){
    #ifndef ONLINE_JUDGE
        freopen(taskname".INP","r",stdin);
        freopen(taskname".OUT","w",stdout);
    #else
        // online submission
    #endif

    //scanf("%d",&tcases);

    FOR(i,1,tcases) testcase();

    cerr << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";

    return 0;
}


#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stdlib.h>
#include <time.h>
#include <iomanip>
#include <math.h>
#include <bitset>
#include <string.h>

using namespace std;

#define taskname "A"
#define LL long long
#define uLL unsigned long long
#define FOR(i,l,r) for(int i = l; i <= r; ++i)
#define REP(i,l,r) for(int i = l; i < r; ++i)
#define FORD(i,r,l) for(int i = r; i >= l; --i)
#define REPD(i,r,l) for(int i = r; i > l; --i)
#define sz(x) (int)((x).size())
#define all(x) (x).begin(), (x).end()
#define debug(x) { cerr << #x << " = " << x << endl; }
#define sci(x) int x; scanf("%d", &x);
#define scii(x, y) int x, y; scanf("%d %d", &x, &y);
#define sciii(x, y, z) int x, y, z; scanf("%d %d %d", &x, &y, &z);
#define pi pair<int,int>
#define pii pair<int,pi>
#define mp make_pair
#define fi first
#define se second
#define pb push_back
#define _USE_MATH_DEFINES
/* M_PI */
#define SetLength2(a, n, t) a=((t*) calloc(n, sizeof(t))) + (n)/2

const int N = 2e5 + 1;
const LL oo = 1e17 + 11;

int tcases = 1;

int n,m,a[N],sz[N],val[N],cnt[N];
vector <int> e[N],divisors[N];
long long res[N];
bool cen[N];

int gcd(int x,int y){
    return y == 0 ? x : gcd(y,x % y);
}
void dfs(int u,int p = 0){
    for(int x : divisors[val[u]]) cnt[x] = 0;
    sz[u] = 1;
    for(int v : e[u]){
        if(v == p || cen[v]) continue;
        dfs(v,u);
        sz[u] += sz[v];
    }
}
int find(int u,int p = 0,int total = 0){
    for(int v : e[u]){
        if(v == p || cen[v]) continue;
        if(sz[v] * 2 > total) return find(v,u,total);
    }
    return u;
}
void dfs0(int u,int root,int curGcd,int p = 0){
    val[u] = curGcd;
    for(int x : divisors[curGcd]){
        ++res[x];
    }
    for(int v : e[u]){
        if(v == p || cen[v]) continue;
        dfs0(v,root,gcd(curGcd,a[v]),u);
    }
}

void dfs1(int u,int p = 0,bool added = 0){
    for(int x : divisors[val[u]]){
        if(added) ++cnt[x];
        else{
            res[x] += cnt[x];
        }
    }
    for(int v : e[u]){
        if(v == p || cen[v]) continue;
        dfs1(v,u,added);
    }
}

void dfs2(int u,int p = 0){
    for(int x : divisors[val[u]]) cnt[x] = 0;
    for(int v : e[u]){
        if(v == p || cen[v]) continue;
        dfs2(v,u);
    }
}
void calculate(int u){
    dfs(u); // delete old values
    int centroid = find(u,u,sz[u]);
    cen[centroid] = 1;
    dfs0(centroid,centroid,a[centroid]);

    for(int v : e[centroid]) if(!cen[v]){
        dfs1(v);
        dfs1(v,v,1);
    }

    for(int v : e[centroid]) if(!cen[v]){
        calculate(v);
    }
}
void testcase(){
    scanf("%d",&n);
    FOR(i,1,n) scanf("%d",&a[i]);
    REP(i,1,n){
        int u,v;
        scanf("%d%d",&u,&v);
        e[u].pb(v);
        e[v].pb(u);
    }

    int total = 0;
    REP(i,1,N){
        FOR(j,1,(N - 1)/i){
            divisors[j * i].pb(i);
            ++total;
        }
    }

    calculate(1);

    FORD(i,N - 1,1){
        FOR(j,2,(N - 1)/i){
            int k = j * i;
            res[i] -= res[k];
        }
    }

    REP(i,1,N){
        if(res[i] > 0){
            printf("%d %lli\n",i,res[i]);
        }
    }
}

int main(){
    #ifndef ONLINE_JUDGE
        freopen(taskname".INP","r",stdin);
        freopen(taskname".OUT","w",stdout);
    #else
        // online submission
    #endif

    //scanf("%d",&tcases);

    FOR(i,1,tcases) testcase();

    cerr << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";

    return 0;
}


/// IN THE NAME OF GUITAR
#include <bits/stdc++.h>

using namespace std;

typedef int ll;
typedef pair<ll, ll> pll;

#define sz(x)                       (ll) x.size()
#define all(x)                      (x).begin(),(x).end()
#define F                           first
#define S                           second

ll Pow(ll a, ll b, ll md, ll ans = 1) {
    for (; b; b >>= 1, a = a * a % md)
        if (b & 1)
            ans = ans * a % md;
    return ans % md;
}
const ll MAXN = 2e5 + 10;
const ll INF  = 1e9 + 7;
const ll MOD  = 1e9 + 7;
ll mark[MAXN], A[MAXN], cnt[MAXN], mobius[MAXN], SZ = 0, n, timer = 1;
vector<ll> adj[MAXN], dv[MAXN], vec[MAXN];

void init() {
    for (ll i = 1; i < MAXN; i++) {
        for (ll j = i; j < MAXN; j += i) {
            dv[j].push_back(i);
        }
    }
    mobius[1] = 1;
    for (ll i = 1; i < MAXN; i++) {
        for (ll d : dv[i]) {
            if (i == d) continue;
            mobius[i] -= mobius[d];
        }
    }
}

void DFS(ll v, ll gcd) {
    SZ++;
    mark[v] = timer;
    for (ll u : adj[v]) {
        if (mark[u] != timer && A[u] % gcd == 0) {
            DFS(u, gcd);
        }
    }
}

int main() {
    init();
    scanf("%d", &n);
    for (ll i = 1; i <= n; i++) {
        scanf("%d", &A[i]);
    }
    for (ll i = 1; i <= n - 1; i++) {
        ll u, v;
        scanf("%d%d", &u, &v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    for (ll i = 1; i <= n; i++) {
        vec[A[i]].push_back(i);
    }
    for (ll i = 1; i < MAXN; i++) {
        for (ll j = i; j < MAXN; j += i) {
            for (ll k : vec[j]) {
                if (mark[k] == timer) continue;
                DFS(k, i);
                cnt[i] += SZ * (SZ + 1) / 2;
                SZ = 0;
            }
        }
        timer++;
    }
    //~ for (ll i = 1; i < MAXN; i++) if (cnt[i]) printf("%lld %lld\n", i, cnt[i]);
    for (ll i = 1; i < MAXN; i++) {
        ll res = 0;
        for (ll j = i; j < MAXN; j += i) {
            res += cnt[j] * mobius[j / i];
        }
        if (res == 0) continue;
        printf("%d %d\n", i, res);
    }
    return 0;
}


/// IN THE NAME OF GUITAR
#include <bits/stdc++.h>

using namespace std;

typedef long long int ll;
typedef pair<ll, ll> pll;

#define sz(x)                       (ll) x.size()
#define all(x)                      (x).begin(),(x).end()
#define F                           first
#define S                           second

ll Pow(ll a, ll b, ll md, ll ans = 1) {
    for (; b; b >>= 1, a = a * a % md)
        if (b & 1)
            ans = ans * a % md;
    return ans % md;
}
const ll MAXN = 2e5 + 10;
const ll INF  = 8e18;
const ll MOD  = 1e9 + 7;
ll mark[MAXN], A[MAXN], cnt[MAXN], mobius[MAXN], SZ = 0, n, timer = 1;
vector<ll> adj[MAXN], dv[MAXN], vec[MAXN];

void init() {
    for (ll i = 1; i < MAXN; i++) {
        for (ll j = i; j < MAXN; j += i) {
            dv[j].push_back(i);
        }
    }
    mobius[1] = 1;
    for (ll i = 1; i < MAXN; i++) {
        for (ll d : dv[i]) {
            if (i == d) continue;
            mobius[i] -= mobius[d];
        }
    }
}

void DFS(ll v, ll gcd) {
    SZ++;
    mark[v] = timer;
    for (ll u : adj[v]) {
        if (mark[u] != timer && A[u] % gcd == 0) {
            DFS(u, gcd);
        }
    }
}

int main() {
    init();
    scanf("%lld", &n);
    for (ll i = 1; i <= n; i++) {
        scanf("%lld", &A[i]);
    }
    for (ll i = 1; i <= n - 1; i++) {
        ll u, v;
        scanf("%lld%lld", &u, &v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    for (ll i = 1; i <= n; i++) {
        vec[A[i]].push_back(i);
    }
    for (ll i = 1; i < MAXN; i++) {
        for (ll j = i; j < MAXN; j += i) {
            for (ll k : vec[j]) {
                if (mark[k] == timer) continue;
                DFS(k, i);
                cnt[i] += SZ * (SZ + 1) / 2;
                SZ = 0;
            }
        }
        timer++;
    }
    //~ for (ll i = 1; i < MAXN; i++) if (cnt[i]) printf("%lld %lld\n", i, cnt[i]);
    for (ll i = 1; i < MAXN; i++) {
        ll res = 0;
        for (ll j = i; j < MAXN; j += i) {
            res += cnt[j] * mobius[j / i];
        }
        if (res == 0) continue;
        printf("%lld %lld\n", i, res);
    }
    return 0;
}


/// IN THE NAME OF GUITAR
#include <bits/stdc++.h>

using namespace std;

typedef long long int ll;
typedef pair<ll, ll> pll;

#define sz(x)                       (ll) x.size()
#define all(x)                      (x).begin(),(x).end()
#define F                           first
#define S                           second

ll Pow(ll a, ll b, ll md, ll ans = 1) {
    for (; b; b >>= 1, a = a * a % md)
        if (b & 1)
            ans = ans * a % md;
    return ans % md;
}
const ll MAXN = 2e5 + 10;
const ll INF  = 8e18;
const ll MOD  = 1e9 + 7;
int mark[MAXN], A[MAXN], mobius[MAXN], SZ = 0, n, timer = 1;
ll cnt[MAXN];
vector<int> adj[MAXN], dv[MAXN], vec[MAXN];

void init() {
    for (int i = 1; i < MAXN; i++) {
        for (int j = i; j < MAXN; j += i) {
            dv[j].push_back(i);
        }
    }
    mobius[1] = 1;
    for (int i = 1; i < MAXN; i++) {
        for (int d : dv[i]) {
            if (i == d) continue;
            mobius[i] -= mobius[d];
        }
    }
}

void DFS(int v, int gcd) {
    SZ++;
    mark[v] = timer;
    for (int u : adj[v]) {
        if (mark[u] != timer && A[u] % gcd == 0) {
            DFS(u, gcd);
        }
    }
}

int main() {
    init();
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &A[i]);
    }
    for (ll i = 1; i <= n - 1; i++) {
        int u, v;
        scanf("%d%d", &u, &v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    for (int i = 1; i <= n; i++) {
        vec[A[i]].push_back(i);
    }
    for (int i = 1; i < MAXN; i++) {
        for (int j = i; j < MAXN; j += i) {
            for (int k : vec[j]) {
                if (mark[k] == timer) continue;
                DFS(k, i);
                cnt[i] += 1LL * SZ * (SZ + 1) / 2;
                SZ = 0;
            }
        }
        timer++;
    }
    //~ for (ll i = 1; i < MAXN; i++) if (cnt[i]) printf("%lld %lld\n", i, cnt[i]);
    for (int i = 1; i < MAXN; i++) {
        ll res = 0;
        for (int j = i; j < MAXN; j += i) {
            res += cnt[j] * mobius[j / i];
        }
        if (res == 0) continue;
        printf("%d %lld\n", i, res);
    }
    return 0;
}


/// IN THE NAME OF GUITAR
#include <bits/stdc++.h>

using namespace std;

typedef int ll;
typedef pair<ll, ll> pll;

#define sz(x)                       (ll) x.size()
#define all(x)                      (x).begin(),(x).end()
#define F                           first
#define S                           second

ll Pow(ll a, ll b, ll md, ll ans = 1) {
    for (; b; b >>= 1, a = a * a % md)
        if (b & 1)
            ans = ans * a % md;
    return ans % md;
}
const ll MAXN = 2e5 + 10;
const ll INF  = 1e9 + 7;
const ll MOD  = 1e9 + 7;
ll mark[MAXN], A[MAXN], cnt[MAXN], mobius[MAXN], SZ = 0, n, timer = 1;
vector<ll> adj[MAXN], dv[MAXN], vec[MAXN];

void init() {
    for (ll i = 1; i < MAXN; i++) {
        for (ll j = i; j < MAXN; j += i) {
            dv[j].push_back(i);
        }
    }
    mobius[1] = 1;
    for (ll i = 1; i < MAXN; i++) {
        for (ll d : dv[i]) {
            if (i == d) continue;
            mobius[i] -= mobius[d];
        }
    }
}

void DFS(ll v, ll gcd) {
    SZ++;
    mark[v] = timer;
    for (ll u : adj[v]) {
        if (mark[u] != timer && A[u] % gcd == 0) {
            DFS(u, gcd);
        }
    }
}

int main() {
    init();
    scanf("%d", &n);
    for (ll i = 1; i <= n; i++) {
        scanf("%d", &A[i]);
    }
    for (ll i = 1; i <= n - 1; i++) {
        ll u, v;
        scanf("%d%d", &u, &v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    for (ll i = 1; i <= n; i++) {
        vec[A[i]].push_back(i);
    }
    for (ll i = 1; i < MAXN; i++) {
        for (ll j = i; j < MAXN; j += i) {
            for (ll k : vec[j]) {
                if (mark[k] == timer) continue;
                DFS(k, i);
                cnt[i] += SZ * (SZ + 1) / 2;
                SZ = 0;
            }
        }
        timer++;
    }
    //~ for (ll i = 1; i < MAXN; i++) if (cnt[i]) printf("%lld %lld\n", i, cnt[i]);
    for (ll i = 1; i < MAXN; i++) {
        long long int res = 0;
        for (ll j = i; j < MAXN; j += i) {
            res += 1LL * cnt[j] * mobius[j / i];
        }
        if (res == 0) continue;
        printf("%d %lld\n", i, res);
    }
    return 0;
}


/*     !ya khoda!     */
#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>

#define ll long long
#define ld long double

#define pp push
#define po pop()
#define pb push_back
#define pf push_front
#define pob pop_back()
#define pof pop_front()
#define I insert
#define E erase

#define F first
#define S second

#define mkp make_pair
#define pll pair<ll,ll>
#define smax(a,b) a=max(a,b)
#define smin(a,b) a=min(a,b)
#define all(a) a.begin(),a.end()

#define coutghat(x)      cout<<tolower(x);
#define coutashar(x,d)   cout<<fixed<<setprecision(x)<<(ld)d
#define IOS ios_base::sync_with_stdio(false) , cin.tie(0) , cout.tie(0);

#define LB(x) ((x) & -(x))
#define BIT(a , b) (((a)>>(b)) & 1)
//#define poow(a,b,M)   b?(poow((a*a)%M,b/2)%M * (b&1?a))%M:1 ;
/*==========================================================================*/
using namespace std;
using namespace __gnu_pbds;
template <typename T> using ordered_set =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename T> using ordered_multiset =  tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;
ll poow(ll x,ll n,ll Mod=1e9+7) { return (n==0?1:poow(x*x%Mod,n/2)*(n&1?x:1)%Mod); }
//#pragma optimize O3
// 107,109, 211,223, 307, 401,409, 503,509, 601,607, 701,709, 809, 907, 1009
/*==========================================================================*/
const int N=2e5+100 , M=1e3+100 , LG=23 , base=2;
const int MOD=1e9+7 , mod=1e9+9;
const ll  INF=1e9   , inf=1e18 , super_inf=~0ull/4;
ll n,a[N] , now,res,cnt , ans[N];
vector<ll>g[N],bank[N];
bool vis[N];
/*==========================================================================*/
void dfs(ll v)
{   vis[v]=1 , cnt++;
	for(auto u:g[v])
		if(a[u]%now==0 && vis[u]==0)
			dfs(u);
}
/*==========================================================================*/
int main()
{
	IOS;
	cin>>n;
	for(int i=0;i<n;i++)   cin>>a[i]  ,  bank[a[i]].pb(i);
	for(int i=0;i<n-1;i++)
	{   ll v,u;
		cin>>v>>u , v--,u--;
		g[v].pb(u) , g[u].pb(v);
	}

	for(int i=N-1;i>0;i--)
	{   res=0 , now=i;
		for(int j=i;j<N;j+=i)
		{
			for(auto x:bank[j])
				if(vis[x]==0)
				    cnt=0,dfs(x)  ,  res+=cnt*(cnt+1)/2;
			ans[i]-=ans[j];
		}
		ans[i]+=res;
		for(int j=i;j<N;j+=i)
			for(auto x:bank[j])
				vis[x]=0;
	}

	for(int i=1;i<N;i++)
		if(ans[i])
			cout<<i<<" "<<ans[i]<<"\n";
    return 0;
}


/*     !ya khoda!     */
#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>

#define ll long long
#define ld long double

#define pp push
#define po pop()
#define pb push_back
#define pf push_front
#define pob pop_back()
#define pof pop_front()
#define I insert
#define E erase

#define F first
#define S second

#define mkp make_pair
#define pll pair<ll,ll>
#define smax(a,b) a=max(a,b)
#define smin(a,b) a=min(a,b)
#define all(a) a.begin(),a.end()

#define coutghat(x)      cout<<tolower(x);
#define coutashar(x,d)   cout<<fixed<<setprecision(x)<<(ld)d
#define IOS ios_base::sync_with_stdio(false) , cin.tie(0) , cout.tie(0);

#define LB(x) ((x) & -(x))
#define BIT(a , b) (((a)>>(b)) & 1)
//#define poow(a,b,M)   b?(poow((a*a)%M,b/2)%M * (b&1?a))%M:1 ;
/*==========================================================================*/
using namespace std;
using namespace __gnu_pbds;
template <typename T> using ordered_set =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename T> using ordered_multiset =  tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;
ll poow(ll x,ll n,ll Mod=1e9+7) { return (n==0?1:poow(x*x%Mod,n/2)*(n&1?x:1)%Mod); }
//#pragma optimize O3
// 107,109, 211,223, 307, 401,409, 503,509, 601,607, 701,709, 809, 907, 1009
/*==========================================================================*/
const int N=2e5+10 , M=1e3+100 , LG=23 , base=2;
const int MOD=1e9+7 , mod=1e9+9;
const ll  INF=1e9   , inf=1e18 , super_inf=~0ull/4;
ll n,a[N] , now,res,cnt , ans[N];
vector<ll>g[N],bank[N];
bool vis[N];
/*==========================================================================*/
void dfs(ll v)
{   vis[v]=1 , cnt++;
	for(auto u:g[v])
		if(a[u]%now==0 && vis[u]==0)
			dfs(u);
}
/*==========================================================================*/
int main()
{
	IOS;
	cin>>n;
	for(int i=0;i<n;i++)   cin>>a[i]  ,  bank[a[i]].pb(i);
	for(int i=0;i<n-1;i++)
	{   ll v,u;
		cin>>v>>u , v--,u--;
		g[v].pb(u) , g[u].pb(v);
	}

	for(int i=N-1;i>0;i--)
	{   res=0 , now=i;
		for(int j=i;j<N;j+=i)
		{
			for(auto x:bank[j])
				if(vis[x]==0)
				    cnt=0,dfs(x)  ,  res+=cnt*(cnt+1)/2;
			ans[i]-=ans[j];
		}
		ans[i]+=res;
		for(int j=i;j<N;j+=i)
			for(auto x:bank[j])
				vis[x]=0;
	}

	for(int i=1;i<N;i++)
		if(ans[i])
			cout<<i<<" "<<ans[i]<<"\n";
    return 0;
}


#include <bits/stdc++.h>
#define fi first
#define se second
#define DBG(x) cerr << #x << " = " << x << endl

using namespace std;
typedef long long ll;

const int N = 2e5 + 5;
const int M = 4e5 + 5;
const int inf = 0x3f3f3f3f;

int n, a[N];
int tot, head[N];
int maxx[N], sz[N], rt, sum;
bool vis[N];
map<int, ll> mp1, mp2, ans;
struct Enode {
    int to, next;
} edge[M];

void addedge(int u, int v) {
    edge[tot].to = v;
    edge[tot].next = head[u];
    head[u] = tot++;
}

void dfs(int u, int fa, int G) {
    mp2[G]++;
    for(int i = head[u]; i != -1; i = edge[i].next) {
        int v = edge[i].to;
        if(v == fa) continue;
        dfs(v, u, __gcd(G, a[v]));
    }
}

void calc(int u, int fa) {
    mp1.clear();
    mp1[a[u]]++; ans[a[u]]++;
    for(int i = head[u]; i != -1; i = edge[i].next) {
        int v = edge[i].to;
        if(v == fa) continue;
        mp2.clear();
        dfs(v, u, __gcd(a[u], a[v]));
        for(auto t1 : mp1) {
            for(auto t2 : mp2) {
                int x = __gcd(t1.fi, t2.fi);
                ll y = t1.se * t2.se;
                ans[x] += y;
            }
        }
        for(auto t2 : mp2) {
            int x = t2.fi;
            ll y = t2.se;
            mp1[x] += y;
        }
    }
    for(int i = head[u]; i != -1; i = edge[i].next) {
        int v = edge[i].to;
        if(v == fa) continue;
        calc(v, u);
    }
}

int main() {
    memset(head, -1, sizeof head);
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    for(int i = 1, u, v; i < n; i++) {
        scanf("%d%d", &u, &v);
        addedge(u, v);
        addedge(v, u);
    }
    calc(1, -1);
    for(auto t : ans) printf("%d %lld\n", t.fi, t.se);
    return 0;
}


#include <bits/stdc++.h>
#define fi first
#define se second
#define DBG(x) cerr << #x << " = " << x << endl

using namespace std;
typedef long long ll;

const int N = 2e5 + 5;
const int M = 4e5 + 5;
const int inf = 0x3f3f3f3f;

int n, a[N];
int tot, head[N];
int maxx[N], sz[N], rt, sum;
bool vis[N];
map<int, ll> mp1, mp2, ans;
struct Enode {
    int to, next;
} edge[M];

void addedge(int u, int v) {
    edge[tot].to = v;
    edge[tot].next = head[u];
    head[u] = tot++;
}

void findrt(int u, int fa) {
    maxx[u] = 0;
    sz[u] = 1;
    for(int i = head[u]; i != -1; i = edge[i].next) {
        int v = edge[i].to;
        if(vis[v] || v == fa) continue;
        findrt(v, u);
        sz[u] += sz[v];
        maxx[u] = max(maxx[u], sz[v]);
    }
    maxx[u] = max(maxx[u], sum - sz[u]);
    if(maxx[u] < maxx[rt]) rt = u;
}

void dfs(int u, int fa, int g) {
    int G = __gcd(g, a[u]);
    mp2[G]++;
    for(int i = head[u]; i != -1; i = edge[i].next) {
        int v = edge[i].to;
        if(v == fa || vis[v]) continue;
        dfs(v, u, G);
    }
}

void calc(int u) {
    mp1[a[u]]++; ans[a[u]]++;
    for(int i = head[u]; i != -1; i = edge[i].next) {
        int v = edge[i].to;
        if(vis[v]) continue;
        mp2.clear();
        dfs(v, u, a[u]);
        for(auto t1 : mp1) {
            for(auto t2 : mp2) {
                int x = __gcd(t1.fi, t2.fi);
                ll y = t1.se * t2.se;
                ans[x] += y;
            }
        }
        for(auto t2 : mp2) {
            int x = t2.fi;
            ll y = t2.se;
            mp1[x] += y;
        }
    }
}

void gao(int u) {
    vis[u] = 1;
    mp1.clear();
    calc(u);
    for(int i = head[u]; i != -1; i = edge[i].next) {
        int v = edge[i].to;
        if(vis[v]) continue;
        sum = sz[v];
        rt = 0;
        findrt(v, -1);
        gao(rt);
    }
}

void init() {
    sum = n;//number of points
    rt = 0;
    maxx[rt] = inf;
    findrt(1, -1);
}

int main() {
    memset(head, -1, sizeof head);
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    for(int i = 1, u, v; i < n; i++) {
        scanf("%d%d", &u, &v);
        addedge(u, v);
        addedge(v, u);
    }
    init();
    gao(1);
    for(auto t : ans) printf("%d %lld\n", t.fi, t.se);
    return 0;
}
/*

*/


#include <bits/stdc++.h>
#define fi first
#define se second
#define DBG(x) cerr << #x << " = " << x << endl

using namespace std;
typedef long long ll;

const int N = 2e5 + 5;
const int M = 4e5 + 5;
const int inf = 0x3f3f3f3f;

int n, a[N];
int tot, head[N];
int maxx[N], sz[N], rt, sum;
bool vis[N];
map<int, ll> mp[N], ans;
struct Enode {
    int to, next;
} edge[M];

void addedge(int u, int v) {
    edge[tot].to = v;
    edge[tot].next = head[u];
    head[u] = tot++;
}

void calc(int u, int fa) {
    mp[u][a[u]]++, ans[a[u]]++;
    for(int i = head[u]; i != -1; i = edge[i].next) {
        int v = edge[i].to;
        if(v == fa) continue;
        calc(v, u);
        for(auto t1 : mp[u]) {
            for(auto t2 : mp[v]) {
                int x = __gcd(t1.fi, t2.fi);
                ll y = t1.se * t2.se;
                ans[x] += y;
            }
        }
        for(auto t2 : mp[v]) {
            int x = __gcd(t2.fi, a[u]);
            ll y = t2.se;
            mp[u][x] += y;
        }
        mp[v].clear();
    }
}

int main() {
    memset(head, -1, sizeof head);
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    for(int i = 1, u, v; i < n; i++) {
        scanf("%d%d", &u, &v);
        addedge(u, v);
        addedge(v, u);
    }
    calc(1, -1);
    for(auto t : ans) printf("%d %lld\n", t.fi, t.se);
    return 0;
}


// This code wrote by chtholly_micromaker(MicroMaker)
#include <bits/stdc++.h>
#define reg register
#define int long long
using namespace std;
const int MaxN=200050;
struct Edge
{
	int nxt,to;
}E[MaxN<<2];
template <class t> inline void read(t &s)
{
	s=0;
	reg int f=1;
	reg char c=getchar();
	while(!isdigit(c))
	{
		if(c=='-')
			f=-1;
		c=getchar();
	}
	while(isdigit(c))
		s=(s<<3)+(s<<1)+(c^48),c=getchar();
	s*=f;
	return;
}
int hd[MaxN],en;
int val[MaxN];
int ans[MaxN];
map<int,int> dr[MaxN];
inline void adde(int u,int v)
{
	++en;
	E[en]=(Edge){hd[u],v};
	hd[u]=en;
	return;
}
inline int gcd(int a,int b)
{
	return !b?a:gcd(b,a%b);
}
inline void dfs(int u,int fa)
{
	for(int i=hd[u];~i;i=E[i].nxt)
	{
		reg int v=E[i].to;
		if(v==fa)
			continue;
		dfs(v,u);
	for(reg map<int,int>::iterator iter=dr[u].begin();iter!=dr[u].end();++iter)
		for(reg map<int,int>::iterator Iter=dr[v].begin();Iter!=dr[v].end();++Iter)
			ans[gcd(iter->first,Iter->first)]+=iter->second*Iter->second;
		for(map<int,int>::iterator iter=dr[v].begin();iter!=dr[v].end();++iter)
			dr[u][gcd(iter->first,val[u])]+=iter->second;
	}
	dr[u][val[u]]+=1;
	for(map<int,int>::iterator iter=dr[u].begin();iter!=dr[u].end();++iter)
		ans[iter->first]+=iter->second;
	return;
}
signed main(void)
{
	memset(hd,-1,sizeof hd);
	int n;cin>>n;
	reg int u,v;
	for(int i=1;i<=n;++i)
		read(val[i]);
	for(int i=1;i<n;++i)
	{
		read(u);read(v);
		adde(u,v);
		adde(v,u);
	}
	dfs(1,0);
	for(int i=1;i<MaxN;++i)
		if(ans[i])
			printf("%lld %lld\n",i,ans[i]);
	return 0;
}


// This code wrote by chtholly_micromaker(MicroMaker)
#include <bits/stdc++.h>
#define reg register
#define int long long
using namespace std;
const int MaxN=200050;
struct Edge
{
	int nxt,to;
}E[MaxN<<2];
template <class t> inline void read(t &s)
{
	s=0;
	reg int f=1;
	reg char c=getchar();
	while(!isdigit(c))
	{
		if(c=='-')
			f=-1;
		c=getchar();
	}
	while(isdigit(c))
		s=(s<<3)+(s<<1)+(c^48),c=getchar();
	s*=f;
	return;
}
int hd[MaxN],en;
int val[MaxN];
map<int,int> dr[MaxN];
int ans[MaxN];
inline void adde(int u,int v)
{
	++en;
	E[en]=(Edge){hd[u],v};
	hd[u]=en;
	return;
}
inline int gcd(int a,int b)
{
	return !b?a:gcd(b,a%b);
}
inline void dfs(int u,int fa)
{
	dr[u][val[u]]=1;
	vector<int> sons;
	for(int i=hd[u];~i;i=E[i].nxt)
	{
		reg int v=E[i].to;
		if(v==fa)
			continue;
		dfs(v,u);
		sons.push_back(v);
		if((int)dr[u].size()>(int)dr[v].size())
			dr[u].swap(dr[v]);
		for(map<int,int>::iterator iter=dr[v].begin();iter!=dr[v].end();++iter)
			dr[u][gcd(iter->first,val[u])]+=iter->second;
	}
	for(int i=0;i<(int)sons.size();++i)
		for(int j=i+1;j<(int)sons.size();++j)
		{
			reg int x=sons[i],y=sons[j];
		for(reg map<int,int>::iterator iter=dr[x].begin();iter!=dr[x].end();++iter)
			for(reg map<int,int>::iterator Iter=dr[y].begin();Iter!=dr[y].end();++Iter)
				ans[gcd(iter->first,Iter->first)]+=iter->second*Iter->second;
		}
	for(map<int,int>::iterator iter=dr[u].begin();iter!=dr[u].end();++iter)
		ans[iter->first]+=iter->second;
	return;
}
signed main(void)
{
	memset(hd,-1,sizeof hd);
	int n;cin>>n;
	reg int u,v;
	for(int i=1;i<=n;++i)
		read(val[i]);
	for(int i=1;i<n;++i)
	{
		read(u);read(v);
		adde(u,v);
		adde(v,u);
	}
	dfs(1,0);

	for(int i=1;i<MaxN;++i)
		if(ans[i])
			printf("%lld %lld\n",i,ans[i]);
	return 0;
}


// This code wrote by chtholly_micromaker(MicroMaker)
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#define reg register
// #define int long long
using namespace std;
const int MaxN=200050;
struct Edge
{
	int nxt,to;
}E[MaxN<<2];
template <class t> inline void read(t &s)
{
	s=0;
	reg int f=1;
	reg char c=getchar();
	while(!isdigit(c))
	{
		if(c=='-')
			f=-1;
		c=getchar();
	}
	while(isdigit(c))
		s=(s<<3)+(s<<1)+(c^48),c=getchar();
	s*=f;
	return;
}
int hd[MaxN],en;
int val[MaxN];
long long ans[MaxN];
inline void adde(int u,int v)
{
	++en;
	E[en]=(Edge){hd[u],v};
	hd[u]=en;
	return;
}
inline int gcd(int a,int b)
{
	return !b?a:gcd(b,a%b);
}
inline void dfs(int u,int fa,map<int,long long> &dru)
{
	for(int i=hd[u];~i;i=E[i].nxt)
	{
		reg int v=E[i].to;
		map<int,long long> drv;
		if(v==fa)
			continue;
		dfs(v,u,drv);
	for(reg map<int,int>::iterator iter=dru.begin();iter!=dru.end();++iter)
		for(reg map<int,int>::iterator Iter=drv.begin();Iter!=drv.end();++Iter)
			ans[gcd(iter->first,Iter->first)]+=iter->second*Iter->second;
		for(map<int,int>::iterator iter=drv.begin();iter!=drv.end();++iter)
			dru[gcd(iter->first,val[u])]+=iter->second;
	}
	dru[val[u]]+=1;
	for(map<int,int>::iterator iter=dru.begin();iter!=dru.end();++iter)
		ans[iter->first]+=iter->second;
	return;
}
signed main(void)
{
	memset(hd,-1,sizeof hd);
	int n;cin>>n;
	reg int u,v;
	for(int i=1;i<=n;++i)
		read(val[i]);
	for(int i=1;i<n;++i)
	{
		read(u);read(v);
		adde(u,v);
		adde(v,u);
	}
	map<int,long long> baolichuqiji;
	dfs(1,0,baolichuqiji);
	for(int i=1;i<MaxN;++i)
		if(ans[i])
			printf("%d %lld\n",i,ans[i]);
	return 0;
}


// This code wrote by chtholly_micromaker(MicroMaker)
#include <bits/stdc++.h>
#define reg register
#define int long long
using namespace std;
const int MaxN=200050;
struct Edge
{
	int nxt,to;
}E[MaxN<<2];
template <class t> inline void read(t &s)
{
	s=0;
	reg int f=1;
	reg char c=getchar();
	while(!isdigit(c))
	{
		if(c=='-')
			f=-1;
		c=getchar();
	}
	while(isdigit(c))
		s=(s<<3)+(s<<1)+(c^48),c=getchar();
	s*=f;
	return;
}
int hd[MaxN],en;
int val[MaxN];
int ans[MaxN];
inline void adde(int u,int v)
{
	++en;
	E[en]=(Edge){hd[u],v};
	hd[u]=en;
	return;
}
inline int gcd(int a,int b)
{
	return !b?a:gcd(b,a%b);
}
inline void dfs(int u,int fa,map<int,int> &dru)
{
	for(int i=hd[u];~i;i=E[i].nxt)
	{
		reg int v=E[i].to;
		map<int,int> drv;
		if(v==fa)
			continue;
		dfs(v,u,drv);
	for(reg map<int,int>::iterator iter=dru.begin();iter!=dru.end();++iter)
		for(reg map<int,int>::iterator Iter=drv.begin();Iter!=drv.end();++Iter)
			ans[gcd(iter->first,Iter->first)]+=iter->second*Iter->second;
		for(map<int,int>::iterator iter=drv.begin();iter!=drv.end();++iter)
			dru[gcd(iter->first,val[u])]+=iter->second;
	}
	dru[val[u]]+=1;
	for(map<int,int>::iterator iter=dru.begin();iter!=dru.end();++iter)
		ans[iter->first]+=iter->second;
	return;
}
signed main(void)
{
	memset(hd,-1,sizeof hd);
	int n;cin>>n;
	reg int u,v;
	for(int i=1;i<=n;++i)
		read(val[i]);
	for(int i=1;i<n;++i)
	{
		read(u);read(v);
		adde(u,v);
		adde(v,u);
	}
	map<int,int> baolichuqiji;
	dfs(1,0,baolichuqiji);
	for(int i=1;i<MaxN;++i)
		if(ans[i])
			printf("%lld %lld\n",i,ans[i]);
	return 0;
}


// This code wrote by chtholly_micromaker(MicroMaker)
#include <bits/stdc++.h>
#define reg register
#define int long long
using namespace std;
const int MaxN=200050;
struct Edge
{
	int nxt,to;
}E[MaxN<<2];
template <class t> inline void read(t &s)
{
	s=0;
	reg int f=1;
	reg char c=getchar();
	while(!isdigit(c))
	{
		if(c=='-')
			f=-1;
		c=getchar();
	}
	while(isdigit(c))
		s=(s<<3)+(s<<1)+(c^48),c=getchar();
	s*=f;
	return;
}
int hd[MaxN],en;
int val[MaxN];
map<int,int> dr[MaxN];
int ans[MaxN];
inline void adde(int u,int v)
{
	++en;
	E[en]=(Edge){hd[u],v};
	hd[u]=en;
	return;
}
inline int gcd(int a,int b)
{
	return !b?a:gcd(b,a%b);
}
inline void dfs(int u,int fa)
{
	dr[u][val[u]]=1;
	vector<int> sons;
	for(int i=hd[u];~i;i=E[i].nxt)
	{
		reg int v=E[i].to;
		if(v==fa)
			continue;
		dfs(v,u);
		sons.push_back(v);
		// if((int)dr[u].size()>(int)dr[v].size())
			// dr[u].swap(dr[v]);
		for(map<int,int>::iterator iter=dr[v].begin();iter!=dr[v].end();++iter)
			dr[u][gcd(iter->first,val[u])]+=iter->second;
	}
	for(int i=0;i<(int)sons.size();++i)
		for(int j=i+1;j<(int)sons.size();++j)
		{
			reg int x=sons[i],y=sons[j];

	for(reg map<int,int>::iterator iter=dr[x].begin();iter!=dr[x].end();++iter)
		for(reg map<int,int>::iterator Iter=dr[y].begin();Iter!=dr[y].end();++Iter)
			ans[gcd(gcd(iter->first,Iter->first),val[u])]+=iter->second*Iter->second;

		}
	for(map<int,int>::iterator iter=dr[u].begin();iter!=dr[u].end();++iter)
		ans[iter->first]+=iter->second;
	return;
}
signed main(void)
{
	memset(hd,-1,sizeof hd);
	int n;cin>>n;
	reg int u,v;
	for(int i=1;i<=n;++i)
		read(val[i]);
	for(int i=1;i<n;++i)
	{
		read(u);read(v);
		adde(u,v);
		adde(v,u);
	}
	dfs(1,0);
	for(int i=1;i<MaxN;++i)
		if(ans[i])
			printf("%lld %lld\n",i,ans[i]);
	return 0;
}


// This code wrote by chtholly_micromaker(MicroMaker)
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#define reg register
// #define int long long
using namespace std;
const int MaxN=200050;
struct Edge
{
	int nxt,to;
}E[MaxN<<2];
template <class t> inline void read(t &s)
{
	s=0;
	reg int f=1;
	reg char c=getchar();
	while(!isdigit(c))
	{
		if(c=='-')
			f=-1;
		c=getchar();
	}
	while(isdigit(c))
		s=(s<<3)+(s<<1)+(c^48),c=getchar();
	s*=f;
	return;
}
int hd[MaxN],en;
int val[MaxN];
long long ans[MaxN];
inline void adde(int u,int v)
{
	++en;
	E[en]=(Edge){hd[u],v};
	hd[u]=en;
	return;
}
inline int gcd(int a,int b)
{
	return !b?a:gcd(b,a%b);
}
inline void dfs(int u,int fa,map<int,long long> &dru)
{
	for(int i=hd[u];~i;i=E[i].nxt)
	{
		reg int v=E[i].to;
		map<int,long long> drv;
		if(v==fa)
			continue;
		dfs(v,u,drv);
	for(reg map<int,long long>::iterator iter=dru.begin();iter!=dru.end();++iter)
		for(reg map<int,long long>::iterator Iter=drv.begin();Iter!=drv.end();++Iter)
			ans[gcd(iter->first,Iter->first)]+=iter->second*Iter->second;
		for(map<int,long long>::iterator iter=drv.begin();iter!=drv.end();++iter)
			dru[gcd(iter->first,val[u])]+=iter->second;
	}
	dru[val[u]]+=1;
	for(map<int,long long>::iterator iter=dru.begin();iter!=dru.end();++iter)
		ans[iter->first]+=iter->second;
	return;
}
signed main(void)
{
	memset(hd,-1,sizeof hd);
	int n;cin>>n;
	reg int u,v;
	for(int i=1;i<=n;++i)
		read(val[i]);
	for(int i=1;i<n;++i)
	{
		read(u);read(v);
		adde(u,v);
		adde(v,u);
	}
	map<int,long long> baolichuqiji;
	dfs(1,0,baolichuqiji);
	for(int i=1;i<MaxN;++i)
		if(ans[i])
			printf("%d %lld\n",i,ans[i]);
	return 0;
}


// This code wrote by chtholly_micromaker(MicroMaker)
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#define reg register
#define int long long
using namespace std;
const int MaxN=200050;
struct Edge
{
	int nxt,to;
}E[MaxN<<2];
template <class t> inline void read(t &s)
{
	s=0;
	reg int f=1;
	reg char c=getchar();
	while(!isdigit(c))
	{
		if(c=='-')
			f=-1;
		c=getchar();
	}
	while(isdigit(c))
		s=(s<<3)+(s<<1)+(c^48),c=getchar();
	s*=f;
	return;
}
int hd[MaxN],en;
int val[MaxN];
int ans[MaxN];
inline void adde(int u,int v)
{
	++en;
	E[en]=(Edge){hd[u],v};
	hd[u]=en;
	return;
}
inline int gcd(int a,int b)
{
	return !b?a:gcd(b,a%b);
}
inline void dfs(int u,int fa,map<int,int> &dru)
{
	for(int i=hd[u];~i;i=E[i].nxt)
	{
		reg int v=E[i].to;
		map<int,int> drv;
		if(v==fa)
			continue;
		dfs(v,u,drv);
	for(reg map<int,int>::iterator iter=dru.begin();iter!=dru.end();++iter)
		for(reg map<int,int>::iterator Iter=drv.begin();Iter!=drv.end();++Iter)
			ans[gcd(iter->first,Iter->first)]+=iter->second*Iter->second;
		for(map<int,int>::iterator iter=drv.begin();iter!=drv.end();++iter)
			dru[gcd(iter->first,val[u])]+=iter->second;
	}
	dru[val[u]]+=1;
	for(map<int,int>::iterator iter=dru.begin();iter!=dru.end();++iter)
		ans[iter->first]+=iter->second;
	return;
}
signed main(void)
{
	memset(hd,-1,sizeof hd);
	int n;cin>>n;
	reg int u,v;
	for(int i=1;i<=n;++i)
		read(val[i]);
	for(int i=1;i<n;++i)
	{
		read(u);read(v);
		adde(u,v);
		adde(v,u);
	}
	map<int,int> baolichuqiji;
	dfs(1,0,baolichuqiji);
	for(int i=1;i<MaxN;++i)
		if(ans[i])
			printf("%lld %lld\n",i,ans[i]);
	return 0;
}


#include <iostream>
#include <vector>
#include <unordered_map>

using namespace std;
typedef unordered_map <int, int> mint;
typedef pair <int, int> pii;
typedef unordered_map <int, vector<int> > mvint;
const int N = 2e5 + 1;
const int M = 2e5 + 10;
int n, x, y, num[M]; long long ans[M];
vector <int> g[M], c[M];
mint epm;
mvint lower[M];
vector <mint> child[M];

void input();
mint dfs(int, int);
int gcd(int, int);

int main() {
	input();
	dfs(0, 0);
	cerr << "*****" << endl;
	for (int i = 0; i < N; i++)
		if (ans[i])
			cout << i << ' ' << ans[i] << endl;
}

int gcd(int a, int b) {
	return !b? a : gcd(b, a % b);
}

void input() {
	cin >> n;
	for (int i = 0; i < n; i++)
		cin >> num[i];
	for (int i = 0; i < n - 1; i++) {
		cin >> x >> y;
		x--; y--;
		g[x].push_back(y);
		g[y].push_back(x);
	}
}

mint dfs(int v, int pv) {
	mint res;
	unordered_map <int, long long> changes;
	for (int u : g[v])
		if (u != pv) {
			mint h, l;
			l = dfs(u, v);
			for (pii i : l)
				h[gcd(i.first, num[v])] += i.second;
			child[v].push_back(h);
		}
	epm.clear();
	epm[num[v]] = 1;
	child[v].push_back(epm);
	for (int i = 0; i < child[v].size(); i++)
		for (pii j : child[v][i])
			res[gcd(j.first, num[v])] += j.second;
	for (int i = 0; i < child[v].size(); i++)
		for (pii j : child[v][i])
			for (pii tmp : res) {
				changes[gcd(j.first, tmp.first)] += 1LL * j.second * tmp.second;
				changes[gcd(j.first, tmp.first)] -= 1LL * j.second * child[v][i][tmp.first];

			}
	for (pair <int, long long> tmp : changes)
		ans[tmp.first] += tmp.second / 2;
	ans[num[v]]++;
	// child[v].clear();
	// changes.clear();
	return res;
}

//
// SamMHD


#include <iostream>
#include <vector>
#include <unordered_map>

using namespace std;
const int N = 2e5 + 10;
int n, a[N], v, u;
long long int ans[N];
vector <int> g[N];
unordered_map <int, int> num[N];

void input();
void dfs(int, int);
int gcd(int, int);

int32_t main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    input();
    dfs(0, 0);

    for (int i = 1; i < N; i++)
        if(ans[i])
            cout << i << ' ' << ans[i] << endl;
}

void input() {
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> a[i];
    for (int i = 0; i < n - 1; i++) {
        cin >> u >> v;
        --v; --u;
        g[u].push_back(v);
        g[v].push_back(u);
    }
}

int gcd(int x, int y) {
    return !y? x : gcd(y, x % y);
}

void dfs (int v, int pv) {
    num[v][a[v]]++;
    ans[a[v]]++;
    for (int u : g[v])
        if(u != pv) {
            dfs(u, v);
            for (auto i : num[u])
                for (auto j : num[v])
                    ans[gcd(i.first, j.first)] += 1LL * num[u][i.first] * num[v][j.first];
            for (auto i: num[u])
                num[v][gcd(i.first, a[v])] += num[u][i.first];
            num[u].clear();
        }
}


#include <iostream>
#include <vector>
#include <unordered_map>

using namespace std;
typedef unordered_map <int, int> mint;
typedef pair <int, int> pii;
typedef unordered_map <int, vector<int> > mvint;
const int N = 2e5 + 1;
const int M = 2e5 + 10;
int n, x, y, num[M]; long long ans[M];
vector <int> g[M], c[M];
mint epm;
mvint lower[M];
vector <mint> child[M];

void input();
mint dfs(int, int);
int gcd(int, int);

int main() {
	input();
	dfs(0, 0);
	cerr << "*****" << endl;
	for (int i = 0; i < N; i++)
		if (ans[i])
			cout << i << ' ' << ans[i] << endl;
}

int gcd(int a, int b) {
	return !b? a : gcd(b, a % b);
}

void input() {
	cin >> n;
	for (int i = 0; i < n; i++)
		cin >> num[i];
	for (int i = 0; i < n - 1; i++) {
		cin >> x >> y;
		x--; y--;
		g[x].push_back(y);
		g[y].push_back(x);
	}
}

mint dfs(int v, int pv) {
	mint res;
	unordered_map <int, long long> changes;
	for (int u : g[v])
		if (u != pv) {
			mint h, l;
			l = dfs(u, v);
			for (pii i : l)
				h[gcd(i.first, num[v])] += i.second;
			child[v].push_back(h);
		}
	epm.clear();
	epm[num[v]] = 1;
	child[v].push_back(epm);
	for (int i = 0; i < child[v].size(); i++)
		for (pii j : child[v][i])
			res[gcd(j.first, num[v])] += j.second;
	for (int i = 0; i < child[v].size(); i++)
		for (pii j : child[v][i])
			for (pii tmp : res) {
				changes[gcd(j.first, tmp.first)] += 1LL * j.second * tmp.second;
				changes[gcd(j.first, tmp.first)] -= 1LL * j.second * child[v][i][tmp.first];

			}
	for (pair <int, long long> tmp : changes)
		ans[tmp.first] += tmp.second / 2;
	ans[num[v]]++;
	// child[v].clear();
	// changes.clear();
	return res;
}

// SamMHD


#include <iostream>
#include <vector>
#include <map>
#include <cstdio>
#include <unordered_map>

#define tmap unordered_map

using namespace std;

typedef tmap <int, int> mint;
typedef pair <int, int> pii;
const int N = 2e5 + 1;
const int M = 2e5 + 10;

int n, x, y, num[M];
long long ans[M], ans2[M];
vector <int> g[M];
mint res[M];

void input();
long long val(int);
void dfs(int, int);
int fetch(mint&, int);
int gcd(int a, int b) {
	return !b? a : gcd(b, a % b);
}
int gcd (int a, int b, int c) {
	return gcd(a, gcd(b, c));
}

int main() {
	input();
	dfs(0, 0);
	cerr << "*****" << endl;
	for (int i = 0; i < N; i++)
		if ((ans[i] / 2) + ans2[i])
			cout << i << ' ' << (ans[i] / 2) + ans2[i] << endl;
}

void input() {
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		scanf("%d", &num[i]);
		ans2[num[i]]++;
	}
	for (int i = 0; i < n - 1; i++) {
		scanf("%d %d", &x, &y);
		x--; y--;
		g[x].push_back(y);
		g[y].push_back(x);
	}
}

void dfs(int v, int pv) {
	for (int u : g[v])
		if (u != pv)
			dfs(u, v);

	g[v].push_back(n + 1);
	res[n + 1].clear();
	res[n + 1][num[v]] = 1;

	for (int u : g[v])
		if (u != pv)
			for (pii j : res[u])
				res[v][gcd(j.first, num[v])] += j.second;

	for (int u : g[v])
		if (u != pv)
			for (pii i : res[u])
				for (pii tmp : res[v])
					ans[gcd(gcd(i.first,num[v]), tmp.first)] += 1LL * i.second * tmp.second;

	// for (int u : g[v])
	// 	if (u != pv)
	// 		for (auto it = res[u].begin(); it != res[u].end(); it++)
	// 			for (auto jt = res[u].begin(); jt != res[u].end(); jt++)
	// 				ans[gcd(it->first, jt->first, num[v])] -= 1LL * (it->second) * (jt->second);

	// for (int u : g[v])
	// 	if (u != pv)
	// 		for (auto it = res[u].begin(); it != res[u].end(); it++)
	// 			for (auto jt = (++it)--; jt != res[u].end(); jt++)
	// 				if (gcd(it->first, num[v]) != gcd(it->second, num[v]))
	// 					ans[gcd(it->first, it->second, num[v])] += 1LL * it->second *

	vector <pii> h;
	for (int u : g[v])
		if (u != pv && u != n + 1) {
			h.clear();
			for (pii t : res[u]) {
				int g = gcd(num[v], t.first);
				int i = 0;
				while (i != h.size()) {
					if (h[i].first == g)
						break;
					i++;
				}
				if (i == h.size())
					h.push_back(pii(g, t.second));
				else
					h[i].second += t.second;
			}
			for (int i = 0; i < h.size(); i++)
				for (int j = 0; j < h.size(); j++)
					ans[gcd(h[i].first, h[j].first)] -= 1LL * h[i].second * h[j].second;
		}
}

int fetch(mint &m, int ind) {
	auto f = m.find(ind);
	if (f != m.end())
		return f -> second;
	return 0;
}

long long val (int i) {
	return (ans[i] / 2) + ans2[i];
}
// SamMHD


#include <iostream>
#include <vector>
#include <map>
#include <cstdio>
#include <unordered_map>

#define tmap unordered_map

using namespace std;
typedef tmap <int, int> mint;
typedef pair <int, int> pii;
typedef tmap <int, vector<int> > mvint;
const int N = 2e5 + 1;
const int M = 2e5 + 10;
int n, x, y, num[M];
long long ans[M], ans2[M];
vector <int> g[M];
mint epm, res[M];
mvint lower[M];
vector <mint> child[M];
void input();
void data_normalize();
void dfs(int, int);
int fetch(mint&, int);
int gcd(int a, int b) {
	return !b? a : gcd(b, a % b);
}

int main() {
	// ios::sync_with_stdio(false);
	// cin.tie(0);
	// cout.tie(0);
	input();
	dfs(0, 0);
	data_normalize();
	cerr << "*****" << endl;
	for (int i = 0; i < N; i++)
		if ((ans[i] / 2) + ans2[i])
			cout << i << ' ' << (ans[i] / 2) + ans2[i] << endl;
}

void input() {
	// cin >> n;
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		// cin >> num[i];
		scanf("%d", &num[i]);
		ans2[num[i]]++;
	}
	for (int i = 0; i < n - 1; i++) {
		// cin >> x >> y;
		scanf("%d %d", &x, &y);
		x--; y--;
		g[x].push_back(y);
		g[y].push_back(x);
	}
}

void dfs(int v, int pv) {
	// tmap <int, long long> changes;
	for (int u : g[v])
		if (u != pv) {
			mint h;
			h.clear();
			dfs(u, v);
			for (pii i : res[u])
				h[gcd(i.first, num[v])] += i.second;
			res[u] = h;
		}
	// mint epm;
	// epm[num[v]] = 1;
	// child[v].push_back(epm);
	g[v].push_back(n + 1);
	res[n + 1].clear();
	res[n + 1][num[v]] = 1;
	for (int u : g[v])
		if (u != pv)
			for (pii j : res[u])
				res[v][gcd(j.first, num[v])] += j.second;
	for (int u : g[v])
		if (u != pv)
			for (pii j : res[u])
				for (pii tmp : res[v]) {
					ans[gcd(gcd(j.first,num[v]), tmp.first)] += 1LL * j.second * tmp.second;
					ans[gcd(gcd(j.first,num[v]), tmp.first)] -= 1LL * j.second *
												fetch(res[u],tmp.first);
				}
	// for (pair <int, long long> tmp : changes)
		// ans[tmp.first] += tmp.second / 2;
	// ans[num[v]]++;
}

int fetch(mint &m, int ind) {
	if (m.find(ind) != m.end())
		return m[ind];
	return 0;
}

void data_normalize() {
	// for (int i = 0; i < n; i++)
	// 	ans2[num[i]]++;
}

// SamMHD


#include <iostream>
#include <vector>
#include <map>
#include <unordered_map>

#define tmap unordered_map

using namespace std;
typedef tmap <int, int> mint;
typedef pair <int, int> pii;
typedef tmap <int, vector<int> > mvint;
const int N = 2e5 + 1;
const int M = 2e5 + 10;
int n, x, y, num[M]; long long ans[M];
vector <int> g[M], c[M];
mint epm, res[M];
mvint lower[M];
vector <mint> child[M];

void input();
mint *dfs(int, int);
int fetch(mint&, int);
int gcd(int a, int b) {
	return !b? a : gcd(b, a % b);
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	input();
	dfs(0, 0);
	cerr << "*****" << endl;
	for (int i = 0; i < N; i++)
		if (ans[i])
			cout << i << ' ' << ans[i] << endl;
}

void input() {
	cin >> n;
	for (int i = 0; i < n; i++)
		cin >> num[i];
	for (int i = 0; i < n - 1; i++) {
		cin >> x >> y;
		x--; y--;
		g[x].push_back(y);
		g[y].push_back(x);
	}
}

mint *dfs(int v, int pv) {
	tmap <int, long long> changes;
	for (int u : g[v])
		if (u != pv) {
			mint h, *l;
			l = dfs(u, v);
			for (pii i : *l)
				h[gcd(i.first, num[v])] += i.second;
			child[v].push_back(h);
		}
	epm.clear();
	epm[num[v]] = 1;
	child[v].push_back(epm);
	for (int i = 0; i < child[v].size(); i++)
		for (pii j : child[v][i])
			res[v][gcd(j.first, num[v])] += j.second;
	for (int i = 0; i < child[v].size(); i++)
		for (pii j : child[v][i])
			for (pii tmp : res[v]) {
				changes[gcd(j.first, tmp.first)] += 1LL * j.second * tmp.second;
				changes[gcd(j.first, tmp.first)] -= 1LL * j.second *
													fetch(child[v][i],tmp.first);

			}
	for (pair <int, long long> tmp : changes)
		ans[tmp.first] += tmp.second / 2;
	ans[num[v]]++;
	return &res[v];
}

int fetch(mint &m, int ind) {
	if (m.find(ind) != m.end())
		return m[ind];
	return 0;
}

// SamMHD


#include <iostream>
#include <vector>
#include <map>
#include <unordered_map>

#define tmap unordered_map

using namespace std;
typedef tmap <int, int> mint;
typedef pair <int, int> pii;
typedef tmap <int, vector<int> > mvint;
const int N = 2e5 + 1;
const int M = 2e5 + 10;
int n, x, y, num[M]; long long ans[M];
vector <int> g[M], c[M];
mint epm;
mvint lower[M];
vector <mint> child[M];

void input();
mint dfs(int, int);
int fetch(mint&, int);
int gcd(int a, int b) {
	return !b? a : gcd(b, a % b);
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	input();
	dfs(0, 0);
	cerr << "*****" << endl;
	for (int i = 0; i < N; i++)
		if (ans[i])
			cout << i << ' ' << ans[i] << endl;
}

void input() {
	cin >> n;
	for (int i = 0; i < n; i++)
		cin >> num[i];
	for (int i = 0; i < n - 1; i++) {
		cin >> x >> y;
		x--; y--;
		g[x].push_back(y);
		g[y].push_back(x);
	}
}

mint dfs(int v, int pv) {
	mint res;
	tmap <int, long long> changes;
	for (int u : g[v])
		if (u != pv) {
			mint h, l;\
			l = dfs(u, v);
			for (pii i : l)
				h[gcd(i.first, num[v])] += i.second;
			child[v].push_back(h);
		}
	epm.clear();
	epm[num[v]] = 1;
	child[v].push_back(epm);
	for (int i = 0; i < child[v].size(); i++)
		for (pii j : child[v][i])
			res[gcd(j.first, num[v])] += j.second;
	for (int i = 0; i < child[v].size(); i++)
		for (pii j : child[v][i])
			for (pii tmp : res) {
				changes[gcd(j.first, tmp.first)] += 1LL * j.second * tmp.second;
				changes[gcd(j.first, tmp.first)] -= 1LL * j.second *
													fetch(child[v][i],tmp.first);

			}
	for (pair <int, long long> tmp : changes)
		ans[tmp.first] += tmp.second / 2;
	ans[num[v]]++;
	return res;
}

int fetch(mint &m, int ind) {
	if (m.find(ind) != m.end())
		return m[ind];
	return 0;
}

// SamMHD


#include <iostream>
#include <vector>
#include <map>
#include <cstdio>
#include <unordered_map>

#define tmap unordered_map

using namespace std;
typedef tmap <int, int> mint;
typedef pair <int, int> pii;
typedef tmap <int, vector<int> > mvint;
const int N = 2e5 + 1;
const int M = 2e5 + 10;
int n, x, y, num[M]; long long ans[M];
vector <int> g[M], c[M];
mint epm, res[M];
mvint lower[M];
vector <mint> child[M];

void input();
mint *dfs(int, int);
int fetch(mint&, int);
int gcd(int a, int b) {
	return !b? a : gcd(b, a % b);
}

int main() {
	// ios::sync_with_stdio(false);
	// cin.tie(0);
	// cout.tie(0);
	input();
	dfs(0, 0);
	cerr << "*****" << endl;
	for (int i = 0; i < N; i++)
		if (ans[i])
			cout << i << ' ' << ans[i] << endl;
}

void input() {
	// cin >> n;
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
		// cin >> num[i];
		scanf("%d", &num[i]);
	for (int i = 0; i < n - 1; i++) {
		// cin >> x >> y;
		scanf("%d %d", &x, &y);
		x--; y--;
		g[x].push_back(y);
		g[y].push_back(x);
	}
}

mint *dfs(int v, int pv) {
	tmap <int, long long> changes;
	for (int u : g[v])
		if (u != pv) {
			mint h, *l;
			l = dfs(u, v);
			for (pii i : *l)
				h[gcd(i.first, num[v])] += i.second;
			child[v].push_back(h);
		}
	epm.clear();
	epm[num[v]] = 1;
	child[v].push_back(epm);
	for (int i = 0; i < child[v].size(); i++)
		for (pii j : child[v][i])
			res[v][gcd(j.first, num[v])] += j.second;
	for (int i = 0; i < child[v].size(); i++)
		for (pii j : child[v][i])
			for (pii tmp : res[v]) {
				changes[gcd(j.first, tmp.first)] += 1LL * j.second * tmp.second;
				changes[gcd(j.first, tmp.first)] -= 1LL * j.second *
													fetch(child[v][i],tmp.first);

			}
	for (pair <int, long long> tmp : changes)
		ans[tmp.first] += tmp.second / 2;
	ans[num[v]]++;
	return &res[v];
}

int fetch(mint &m, int ind) {
	if (m.find(ind) != m.end())
		return m[ind];
	return 0;
}

// SamMHD


#include <iostream>
#include <vector>
#include <map>
#include <unordered_map>

#define tmap unordered_map

using namespace std;
typedef tmap <int, int> mint;
typedef pair <int, int> pii;
typedef tmap <int, vector<int> > mvint;
const int N = 2e5 + 1;
const int M = 2e5 + 10;
int n, x, y, num[M]; long long ans[M];
vector <int> g[M], c[M];
mint epm;
mvint lower[M];
vector <mint> child[M];

void input();
mint dfs(int, int);
int fetch(mint&, int);
int gcd(int a, int b) {
	return !b? a : gcd(b, a % b);
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	input();
	dfs(0, 0);
	cerr << "*****" << endl;
	for (int i = 0; i < N; i++)
		if (ans[i])
			cout << i << ' ' << ans[i] << endl;
}

void input() {
	cin >> n;
	for (int i = 0; i < n; i++)
		cin >> num[i];
	for (int i = 0; i < n - 1; i++) {
		cin >> x >> y;
		x--; y--;
		g[x].push_back(y);
		g[y].push_back(x);
	}
}

mint dfs(int v, int pv) {
	mint res;
	tmap <int, long long> changes;
	res.clear();
	changes.clear();
	for (int u : g[v])
		if (u != pv) {
			mint h, l;
			h.clear();
			l.clear();
			l = dfs(u, v);
			for (pii i : l)
				h[gcd(i.first, num[v])] += i.second;
			child[v].push_back(h);
		}
	epm.clear();
	epm[num[v]] = 1;
	child[v].push_back(epm);
	for (int i = 0; i < child[v].size(); i++)
		for (pii j : child[v][i])
			res[gcd(j.first, num[v])] += j.second;
	for (int i = 0; i < child[v].size(); i++)
		for (pii j : child[v][i])
			for (pii tmp : res) {
				changes[gcd(j.first, tmp.first)] += 1LL * j.second * tmp.second;
				changes[gcd(j.first, tmp.first)] -= 1LL * j.second *
													fetch(child[v][i],tmp.first);

			}
	for (pair <int, long long> tmp : changes)
		ans[tmp.first] += tmp.second / 2;
	ans[num[v]]++;
	child[v].clear();
	changes.clear();
	return res;
}

int fetch(mint &m, int ind) {
	if (m.find(ind) != m.end())
		return m[ind];
	return 0;
}

// SamMHD


#include <iostream>
#include <vector>
#include <map>
#include <cstdio>
#include <unordered_map>

#define tmap unordered_map

using namespace std;

typedef tmap <int, int> mint;
typedef pair <int, int> pii;
const int N = 2e5 + 1;
const int M = 2e5 + 10;

int n, x, y, num[M];
long long ans[M], ans2[M];
vector <int> g[M];
mint res[M];

void input();
long long val(int);
void dfs(int, int);
int fetch(mint&, int);
int gcd(int a, int b) {
	return !b? a : gcd(b, a % b);
}
int gcd (int a, int b, int c) {
	return gcd(a, gcd(b, c));
}

int main() {
	input();
	dfs(0, 0);
	cerr << "*****" << endl;
	for (int i = 0; i < N; i++)
		if ((ans[i] / 2) + ans2[i])
			cout << i << ' ' << (ans[i] / 2) + ans2[i] << endl;
}

void input() {
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		scanf("%d", &num[i]);
		ans2[num[i]]++;
	}
	for (int i = 0; i < n - 1; i++) {
		scanf("%d %d", &x, &y);
		x--; y--;
		g[x].push_back(y);
		g[y].push_back(x);
	}
}

void dfs(int v, int pv) {
	for (int u : g[v])
		if (u != pv)
			dfs(u, v);

	g[v].push_back(n + 1);
	res[n + 1].clear();
	res[n + 1][num[v]] = 1;

	for (int u : g[v])
		if (u != pv)
			for (pii j : res[u])
				res[v][gcd(j.first, num[v])] += j.second;

	for (int u : g[v])
		if (u != pv)
			for (pii i : res[u])
				for (pii tmp : res[v])
					ans[gcd(gcd(i.first,num[v]), tmp.first)] += 1LL * i.second * tmp.second;

	// for (int u : g[v])
	// 	if (u != pv)
	// 		for (auto it = res[u].begin(); it != res[u].end(); it++)
	// 			for (auto jt = res[u].begin(); jt != res[u].end(); jt++)
	// 				;//ans[gcd(gcd(it->first, jt->first), num[v])] -= 1LL * (it->second) * (jt->second);

	for (int u : g[v])
		if (u != pv) {
			mint h;
			for (pii i : res[u])
				h[gcd(i.first, num[v])] += i.second;
			for (auto it = h.begin(); it != h.end(); it++)
				for (auto jt = h.begin(); jt != h.end(); jt++)
					ans[gcd(it->first, jt->first)] -= 1LL * it->second * jt->second;
		}

	// return
	// vector <pii> h;
	// for (int u : g[v])
	// 	if (u != pv && u != n + 1) {
	// 		h.clear();
	// 		for (pii t : res[u]) {
	// 			int g = gcd(num[v], t.first);
	// 			int i = 0;
	// 			while (i != h.size()) {
	// 				if (h[i].first == g)
	// 					break;
	// 				i++;
	// 			}
	// 			if (i == h.size())
	// 				h.push_back(pii(g, t.second));
	// 			else
	// 				h[i].second += t.second;
	// 		}
	// 		for (int i = 0; i < h.size(); i++)
	// 			for (int j = 0; j < h.size(); j++)
	// 				ans[gcd(h[i].first, h[j].first)] -= 1LL * h[i].second * h[j].second;
	// 	}
}

int fetch(mint &m, int ind) {
	auto f = m.find(ind);
	if (f != m.end())
		return f -> second;
	return 0;
}

long long val (int i) {
	return (ans[i] / 2) + ans2[i];
}
// SamMHD


#include <iostream>
#include <vector>
#include <unordered_map>

using namespace std;
typedef unordered_map <int, int> mint;
typedef pair <int, int> pii;
typedef unordered_map <int, vector<int> > mvint;
const int N = 2e5 + 1;
const int M = 2e5 + 10;
int n, x, y, num[M]; long long ans[M];
vector <int> g[M], c[M];
mint epm;
mvint lower[M];
vector <mint> child[M];

void input();
mint dfs(int, int);
int gcd(int, int);

int main() {
	input();
	dfs(0, 0);
	cerr << "*****" << endl;
	for (int i = 0; i < N; i++)
		if (ans[i])
			cout << i << ' ' << ans[i] << endl;
}

int gcd(int a, int b) {
	return !b? a : gcd(b, a % b);
}

void input() {
	cin >> n;
	for (int i = 0; i < n; i++)
		cin >> num[i];
	for (int i = 0; i < n - 1; i++) {
		cin >> x >> y;
		x--; y--;
		g[x].push_back(y);
		g[y].push_back(x);
	}
}

mint dfs(int v, int pv) {
	mint res;
	unordered_map <int, long long> changes;
	res.clear();
	changes.clear();
	for (int u : g[v])
		if (u != pv) {
			mint h, l;
			l = dfs(u, v);
			for (pii i : l)
				h[gcd(i.first, num[v])] += i.second;
			child[v].push_back(h);
		}
	epm.clear();
	epm[num[v]] = 1;
	child[v].push_back(epm);
	for (int i = 0; i < child[v].size(); i++)
		for (pii j : child[v][i])
			res[gcd(j.first, num[v])] += j.second;
	for (int i = 0; i < child[v].size(); i++)
		for (pii j : child[v][i])
			for (pii tmp : res) {
				changes[gcd(j.first, tmp.first)] += 1LL * j.second * tmp.second;
				changes[gcd(j.first, tmp.first)] -= 1LL * j.second * child[v][i][tmp.first];

			}
	for (pair <int, long long> tmp : changes)
		ans[tmp.first] += tmp.second / 2;
	ans[num[v]]++;
	child[v].clear();
	changes.clear();
	return res;
}

//
// SamMHD


#include <iostream>
#include <vector>
#include <map>
#include <cstdio>
#include <unordered_map>

#define tmap unordered_map

using namespace std;

typedef tmap <int, int> mint;
typedef pair <int, int> pii;
const int N = 2e5 + 1;
const int M = 2e5 + 10;

int n, x, y, num[M];
long long ans[M], ans2[M];
vector <int> g[M];
mint res[M];

void input();
long long val(int);
void dfs(int, int);
int fetch(mint&, int);
int gcd(int a, int b) {
	return !b? a : gcd(b, a % b);
}

int main() {
	input();
	dfs(0, 0);
	cerr << "*****" << endl;
	for (int i = 0; i < N; i++)
		if ((ans[i] / 2) + ans2[i])
			cout << i << ' ' << (ans[i] / 2) + ans2[i] << endl;
}

void input() {
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		scanf("%d", &num[i]);
		ans2[num[i]]++;
	}
	for (int i = 0; i < n - 1; i++) {
		scanf("%d %d", &x, &y);
		x--; y--;
		g[x].push_back(y);
		g[y].push_back(x);
	}
}

void dfs(int v, int pv) {
	for (int u : g[v])
		if (u != pv)
			dfs(u, v);

	g[v].push_back(n + 1);
	res[n + 1].clear();
	res[n + 1][num[v]] = 1;

	for (int u : g[v])
		if (u != pv)
			for (pii j : res[u])
				res[v][gcd(j.first, num[v])] += j.second;

	for (int u : g[v])
		if (u != pv)
			for (pii i : res[u])
				for (pii tmp : res[v])
					ans[gcd(gcd(i.first,num[v]), tmp.first)] += 1LL * i.second * tmp.second;

	for (int u : g[v])
		if (u != pv)
			for (auto it = res[u].begin(); it != res[u].end(); it++)
				for (auto jt = res[u].begin(); jt != res[u].end(); jt++)
					;//ans[gcd(gcd(it->first, jt->first), num[v])] -= 1LL * (it->second) * (jt->second);

	for (int u : g[v])
		if (u != pv) {
			mint h;
			for (pii i : res[u])
				h[gcd(i.first, num[v])] += i.second;
			for (auto it = h.begin(); it != h.end(); it++)
				for (auto jt = h.begin(); jt != h.end(); jt++)
					ans[gcd(it->first, jt->first)] -= 1LL * it->second * jt->second;
		}
}

int fetch(mint &m, int ind) {
	auto f = m.find(ind);
	if (f != m.end())
		return f -> second;
	return 0;
}

long long val (int i) {
	return (ans[i] / 2) + ans2[i];
}
// SamMHD


#include <iostream>
#include <vector>
#include <map>

using namespace std;
typedef map <int, int> mint;
typedef pair <int, int> pii;
typedef map <int, vector<int> > mvint;
const int N = 2e5 + 1;
const int M = 2e5 + 10;
int n, x, y, num[M]; long long ans[M];
vector <int> g[M], c[M];
map <int, int> epm;
mvint lower[M];
vector <mint> child[M];

void input();
mint dfs(int, int);
int gcd(int, int);

int main() {
	input();
	dfs(0, 0);
	cerr << "*****" << endl;
	for (int i = 0; i < N; i++)
		if (ans[i])
			cout << i << ' ' << ans[i] << endl;
}

int gcd(int a, int b) {
	return !b? a : gcd(b, a % b);
}

void input() {
	cin >> n;
	for (int i = 0; i < n; i++)
		cin >> num[i];
	for (int i = 0; i < n - 1; i++) {
		cin >> x >> y;
		x--; y--;
		g[x].push_back(y);
		g[y].push_back(x);
	}
}

mint dfs(int v, int pv) {
	mint res;
	map <int, long long> changes;
	for (int u : g[v])
		if (u != pv) {
			mint h, l;
			l = dfs(u, v);
			for (pii i : l)
				h[gcd(i.first, num[v])] += i.second;
			child[v].push_back(h);
		}
	epm.clear();
	epm[num[v]] = 1;
	child[v].push_back(epm);
	for (int i = 0; i < child[v].size(); i++)
		for (pii j : child[v][i])
			res[gcd(j.first, num[v])] += j.second;
	for (int i = 0; i < child[v].size(); i++)
		for (pii j : child[v][i])
			for (pii tmp : res) {
				changes[gcd(j.first, tmp.first)] += 1LL * j.second * tmp.second;
				changes[gcd(j.first, tmp.first)] -= 1LL * j.second * child[v][i][tmp.first];

			}
	for (pair <int, long long> tmp : changes)
		ans[tmp.first] += tmp.second / 2;
	ans[num[v]]++;
	// child[v].clear();
	// changes.clear();
	return res;
}

// SamMHD


#include <iostream>
#include <vector>
#include <map>
#include <cstdio>
#include <unordered_map>

#define tmap unordered_map

using namespace std;
typedef tmap <int, int> mint;
typedef pair <int, int> pii;
typedef tmap <int, vector<int> > mvint;
const int N = 2e5 + 1;
const int M = 2e5 + 10;
int n, x, y, num[M];
long long ans[M], ans2[M];
vector <int> g[M];
mint epm, res[M];
mvint lower[M];
vector <mint> child[M];
void input();
void data_normalize();
void dfs(int, int);
int fetch(mint&, int);
int gcd(int a, int b) {
	return !b? a : gcd(b, a % b);
}

int main() {
	// ios::sync_with_stdio(false);
	// cin.tie(0);
	// cout.tie(0);
	input();
	dfs(0, 0);
	data_normalize();
	cerr << "*****" << endl;
	for (int i = 0; i < N; i++)
		if ((ans[i] / 2) + ans2[i])
			cout << i << ' ' << (ans[i] / 2) + ans2[i] << endl;
}

void input() {
	// cin >> n;
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		// cin >> num[i];
		scanf("%d", &num[i]);
		ans2[num[i]]++;
	}
	for (int i = 0; i < n - 1; i++) {
		// cin >> x >> y;
		scanf("%d %d", &x, &y);
		x--; y--;
		g[x].push_back(y);
		g[y].push_back(x);
	}
}

void dfs(int v, int pv) {
	// tmap <int, long long> changes;
	for (int u : g[v])
		if (u != pv) {
			// mint h;
			// h.clear();
			dfs(u, v);
			// for (pii i : res[u])
			// 	h[gcd(i.first, num[v])] += i.second;
			// res[u] = h;
		}
	// mint epm;
	// epm[num[v]] = 1;
	// child[v].push_back(epm);
	g[v].push_back(n + 1);
	res[n + 1].clear();
	res[n + 1][num[v]] = 1;
	for (int u : g[v])
		if (u != pv)
			for (pii j : res[u])
				res[v][gcd(j.first, num[v])] += j.second;
	for (int u : g[v])
		if (u != pv)
			for (pii i : res[u])
				for (pii tmp : res[v]) {
					ans[gcd(gcd(i.first,num[v]), tmp.first)] += 1LL * i.second * tmp.second;
					// ans[gcd(gcd(i.first,num[v]), tmp.first)] -= 1LL * i.second *
												// fetch(res[u],tmp.first);
				}
	for (int u : g[v])
		if (u != pv)
			for (auto it = res[u].begin(); it != res[u].end(); it++)
				for (auto jt = res[u].begin(); jt != res[u].end(); jt++)
					ans[gcd(gcd(it->first, jt->first), num[v])] -= 1LL * (it->second) * (jt->second);
	// for (pair <int, long long> tmp : changes)
		// ans[tmp.first] += tmp.second / 2;
	// ans[num[v]]++;
}

int fetch(mint &m, int ind) {
	auto f = m.find(ind);
	if (f != m.end())
		return f -> second;
	return 0;
}

void data_normalize() {
	// for (int i = 0; i < n; i++)
	// 	ans2[num[i]]++;
}

// SamMHD


#include <iostream>
#include <vector>
#include <map>
#include <cstdio>
#include <unordered_map>

#define tmap unordered_map

using namespace std;

typedef tmap <int, int> mint;
typedef pair <int, int> pii;
const int N = 2e5 + 1;
const int M = 2e5 + 10;

int n, x, y, num[M];
long long ans[M], ans2[M];
vector <int> g[M];
mint res[M];

void input();
long long val(int);
void dfs(int, int);
int fetch(mint&, int);
int gcd(int a, int b) {
	return !b? a : gcd(b, a % b);
}
int gcd (int a, int b, int c) {
	return gcd(a, gcd(b, c));
}

int main() {
	input();
	dfs(0, 0);
	cerr << "*****" << endl;
	for (int i = 0; i < N; i++)
		if ((ans[i] / 2) + ans2[i])
			cout << i << ' ' << (ans[i] / 2) + ans2[i] << endl;
}

void input() {
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		scanf("%d", &num[i]);
		ans2[num[i]]++;
	}
	for (int i = 0; i < n - 1; i++) {
		scanf("%d %d", &x, &y);
		x--; y--;
		g[x].push_back(y);
		g[y].push_back(x);
	}
}

void dfs(int v, int pv) {
	for (int u : g[v])
		if (u != pv)
			dfs(u, v);

	g[v].push_back(n + 1);
	res[n + 1].clear();
	res[n + 1][num[v]] = 1;

	for (int u : g[v])
		if (u != pv)
			for (pii j : res[u])
				res[v][gcd(j.first, num[v])] += j.second;

	for (int u : g[v])
		if (u != pv)
			for (pii i : res[u])
				for (pii tmp : res[v])
					ans[gcd(gcd(i.first,num[v]), tmp.first)] += 1LL * i.second * tmp.second;

	// for (int u : g[v])
	// 	if (u != pv)
	// 		for (auto it = res[u].begin(); it != res[u].end(); it++)
	// 			for (auto jt = res[u].begin(); jt != res[u].end(); jt++)
	// 				;//ans[gcd(gcd(it->first, jt->first), num[v])] -= 1LL * (it->second) * (jt->second);

	for (int u : g[v])
		if (u != pv) {
			mint h;
			for (pii i : res[u])
				h[gcd(i.first, num[v])] += i.second;
			for (auto it = h.begin(); it != h.end(); it++)
				for (auto jt = h.begin(); jt != h.end(); jt++)
					ans[gcd(it->first, jt->first)] -= 1LL * it->second * jt->second;
		}

	return
	vector <pii> h;
	for (int u : g[v])
		if (u != pv && u != n + 1) {
			h.clear();
			for (pii t : res[u]) {
				int g = gcd(num[v], t.first);
				int i = 0;
				while (i != h.size()) {
					if (h[i].first == g)
						break;
					i++;
				}
				if (i == h.size())
					h.push_back(pii(g, t.second));
				else
					h[i].second += t.second;
			}
			for (int i = 0; i < h.size(); i++)
				for (int j = 0; j < h.size(); j++)
					ans[gcd(h[i].first, h[j].first)] -= 1LL * h[i].second * h[j].second;
		}
}

int fetch(mint &m, int ind) {
	auto f = m.find(ind);
	if (f != m.end())
		return f -> second;
	return 0;
}

long long val (int i) {
	return (ans[i] / 2) + ans2[i];
}
// SamMHD


#include<bits/stdc++.h>
using namespace std;

typedef int ll;
typedef long double ld;
typedef pair<int,int> pi;
typedef pair<ll,ll> pll;

#define endl '\n'
#define ff first
#define ss second

#define pb push_back
#define f(i,l,r) for(ll i=l;i<=r;i++)
#define rf(i,r,l) for(ll i=r;i>=l;i--)
#define Max 5000001
#define inf 2147483647
#define llinf 9223372036854775807
#define all(v) v.begin(),v.end()
#define bp(n) __builtin_popcountll(n)
#define fast ios_base::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL)

#define d0(a) cout<<a<<' ';
#define d1(a) cout<<a<<endl;
#define d2(a,b) cout<<a<<' '<<b<<endl;
#define d3(a,b,c) cout<<a<<' '<<b<<' '<<c<<endl;
#define d4(a,b,c,d) cout<<a<<' '<<b<<' '<<c<<' '<<d<<endl;
#define d5(a,b,c,d,e) cout<<a<<' '<<b<<' '<<c<<' '<<d<<' '<<e<<endl;
#define d6(a,b,c,d,e,f) cout<<a<<' '<<b<<' '<<c<<' '<<d<<' '<<e<<' '<<f<<endl;

const ll N=2e5+1,mod=1e9+7,bit=61;

ll a[N],n;
long long dp[N];
vector<pll> edges[N];
ll val[N];

template<typename T>
class dsu
{
	public:
		vector<T> par,sz;
		ll n;
		dsu(ll n_)
		{
			n=n_;
			par.resize(n+1);
			sz.resize(n+1);
			for(int i=0;i<=n;i++)
			{
				par[i]=i;
				sz[i]=1;
			}
		}
		T getp(T x)
		{
			while(par[x]!=x)
			{
				par[x]=par[par[x]];
				x=par[x];
			}
			return x;
		}
		void merge(T a,T b,long long  &res)
		{
			T p1=getp(a),p2=getp(b);
			if(p1==p2)
			{
				return;
			}
			if(sz[p2]>sz[p1])
			{
				swap(p1,p2);
			}
			res-=((long long)sz[p1]*((long long)sz[p1]+1LL))/2;
			res-=((long long)sz[p2]*((long long)sz[p2]+1LL))/2;
			par[p2]=p1;
			sz[p1]+=sz[p2];
			res+=((long long)sz[p1]*((long long)sz[p1]+1LL))/2;
			sz[p2]=0;
		}
};

signed main()
{
    fast;

    ll t=1;
    //cin>>t;
    while(t--)
    {
        cin>>n;
        f(i,1,n)
        {
            cin>>a[i];
            val[a[i]]++;
        }
        f(i,1,n-1)
        {
            ll u,v;
            cin>>u>>v;
            edges[__gcd(a[u],a[v])].pb({u,v});
        }
        rf(i,N-1,1)
        {
            dp[i]=0;
            unordered_map<int,int> mp;
            for(int j=i;j<N;j+=i)
            {
                dp[i]+=val[j];
                for(auto v:edges[j])
                {
                    mp[v.ff]=1;
                    mp[v.ss]=1;
                }
            }
            int x=dp[i];
            ll id=0;
            for(auto &it:mp)
            {
                it.ss=++id;
            }
            dsu<int> obj(x);
            for(int j=i;j<N;j+=i)
            {
                for(auto v:edges[j])
                {
                    obj.merge(mp[v.ff],mp[v.ss],dp[i]);
                }
            }
            for(int j=2*i;j<N;j+=i)
            {
                dp[i]-=dp[j];
            }
        }
        f(i,1,N-1)
        {
            if(dp[i])
            {
                cout<<i<<' '<<dp[i]<<endl;
            }
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef int ll;
typedef long double ld;
typedef pair<int,int> pi;
typedef pair<ll,ll> pll;

#define endl '\n'
#define ff first
#define ss second

#define pb push_back
#define f(i,l,r) for(ll i=l;i<=r;i++)
#define rf(i,r,l) for(ll i=r;i>=l;i--)
#define Max 5000001
#define inf 2147483647
#define llinf 9223372036854775807
#define all(v) v.begin(),v.end()
#define bp(n) __builtin_popcountll(n)
#define fast ios_base::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL)

#define d0(a) cout<<a<<' ';
#define d1(a) cout<<a<<endl;
#define d2(a,b) cout<<a<<' '<<b<<endl;
#define d3(a,b,c) cout<<a<<' '<<b<<' '<<c<<endl;
#define d4(a,b,c,d) cout<<a<<' '<<b<<' '<<c<<' '<<d<<endl;
#define d5(a,b,c,d,e) cout<<a<<' '<<b<<' '<<c<<' '<<d<<' '<<e<<endl;
#define d6(a,b,c,d,e,f) cout<<a<<' '<<b<<' '<<c<<' '<<d<<' '<<e<<' '<<f<<endl;

const ll N=2e5+1,mod=1e9+7,bit=61;

ll a[N],n;
long long dp[N];
vector<pll> edges[N];
ll val[N];

template<typename T>
class dsu
{
	public:
		vector<T> par,sz;
		ll n;
		dsu(ll n_)
		{
			n=n_;
			par.resize(n+1);
			sz.resize(n+1);
			for(int i=0;i<=n;i++)
			{
				par[i]=i;
				sz[i]=1;
			}
		}
		T getp(T x)
		{
			while(par[x]!=x)
			{
				par[x]=par[par[x]];
				x=par[x];
			}
			return x;
		}
		void merge(T a,T b,long long  &res)
		{
			T p1=getp(a),p2=getp(b);
			if(p1==p2)
			{
				return;
			}
			if(sz[p2]>sz[p1])
			{
				swap(p1,p2);
			}
			res-=((long long)sz[p1]*((long long)sz[p1]+1LL))/2;
			res-=((long long)sz[p2]*((long long)sz[p2]+1LL))/2;
			par[p2]=p1;
			sz[p1]+=sz[p2];
			res+=((long long)sz[p1]*((long long)sz[p1]+1LL))/2;
			sz[p2]=0;
		}
};

signed main()
{
    fast;

    ll t=1;
    //cin>>t;
    while(t--)
    {
        cin>>n;
        f(i,1,n)
        {
            cin>>a[i];
            val[a[i]]++;
        }
        f(i,1,n-1)
        {
            ll u,v;
            cin>>u>>v;
            edges[__gcd(a[u],a[v])].pb({u,v});
        }
        rf(i,N-1,1)
        {
            dp[i]=0;
            map<int,int> mp;
            for(int j=i;j<N;j+=i)
            {
                dp[i]+=val[j];
                for(auto v:edges[j])
                {
                    mp[v.ff]=1;
                    mp[v.ss]=1;
                }
            }
            int x=dp[i];
            ll id=0;
            for(auto &it:mp)
            {
                it.ss=++id;
            }
            dsu<int> obj(x);
            for(int j=i;j<N;j+=i)
            {
                for(auto v:edges[j])
                {
                    obj.merge(mp[v.ff],mp[v.ss],dp[i]);
                }
            }
            for(int j=2*i;j<N;j+=i)
            {
                dp[i]-=dp[j];
            }
        }
        f(i,1,N-1)
        {
            if(dp[i])
            {
                cout<<i<<' '<<dp[i]<<endl;
            }
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef int ll;
typedef long double ld;
typedef pair<int,int> pi;
typedef pair<ll,ll> pll;

#define endl '\n'
#define ff first
#define ss second

#define pb push_back
#define f(i,l,r) for(ll i=l;i<=r;i++)
#define rf(i,r,l) for(ll i=r;i>=l;i--)
#define Max 5000001
#define inf 2147483647
#define llinf 9223372036854775807
#define all(v) v.begin(),v.end()
#define bp(n) __builtin_popcountll(n)
#define fast ios_base::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL)

#define d0(a) cout<<a<<' ';
#define d1(a) cout<<a<<endl;
#define d2(a,b) cout<<a<<' '<<b<<endl;
#define d3(a,b,c) cout<<a<<' '<<b<<' '<<c<<endl;
#define d4(a,b,c,d) cout<<a<<' '<<b<<' '<<c<<' '<<d<<endl;
#define d5(a,b,c,d,e) cout<<a<<' '<<b<<' '<<c<<' '<<d<<' '<<e<<endl;
#define d6(a,b,c,d,e,f) cout<<a<<' '<<b<<' '<<c<<' '<<d<<' '<<e<<' '<<f<<endl;

const ll N=2e5+1,mod=1e9+7,bit=61;

ll a[N],n;
long long dp[N];
vector<pll> edges[N];
ll val[N];

template<typename T>
class dsu
{
	public:
		vector<T> par,sz;
		ll n;
		dsu(ll n_)
		{
			n=n_;
			par.resize(n+1);
			sz.resize(n+1);
			for(int i=0;i<=n;i++)
			{
				par[i]=i;
				sz[i]=1;
			}
		}
		T getp(T x)
		{
			while(par[x]!=x)
			{
				par[x]=par[par[x]];
				x=par[x];
			}
			return x;
		}
		void merge(T a,T b,long long  &res)
		{
			T p1=getp(a),p2=getp(b);
			if(p1==p2)
			{
				return;
			}
			if(sz[p2]>sz[p1])
			{
				swap(p1,p2);
			}
			res-=((long long)sz[p1]*((long long)sz[p1]+1LL))/2;
			res-=((long long)sz[p2]*((long long)sz[p2]+1LL))/2;
			par[p2]=p1;
			sz[p1]+=sz[p2];
			res+=((long long)sz[p1]*((long long)sz[p1]+1LL))/2;
			sz[p2]=0;
		}
};

signed main()
{
    fast;

    ll t=1;
    //cin>>t;
    while(t--)
    {
        cin>>n;
        f(i,1,n)
        {
            cin>>a[i];
            val[a[i]]++;
        }
        f(i,1,n-1)
        {
            ll u,v;
            cin>>u>>v;
            edges[__gcd(a[u],a[v])].pb({u,v});
        }
        rf(i,N-1,1)
        {
            dp[i]=0;
            dsu<int> obj(n);
            for(int j=i;j<N;j+=i)
            {
                dp[i]+=val[j];
                for(auto u:edges[j])
                {
                    obj.merge(u.ff,u.ss,dp[i]);
                }
            }
            for(int j=2*i;j<N;j+=i)
            {
                dp[i]-=dp[j];
            }
        }
        f(i,1,N-1)
        {
            if(dp[i])
            {
                cout<<i<<' '<<dp[i]<<endl;
            }
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef int ll;
typedef long double ld;
typedef pair<int,int> pi;
typedef pair<ll,ll> pll;

#define endl '\n'
#define ff first
#define ss second

#define pb push_back
#define f(i,l,r) for(ll i=l;i<=r;i++)
#define rf(i,r,l) for(ll i=r;i>=l;i--)
#define Max 5000001
#define inf 2147483647
#define llinf 9223372036854775807
#define all(v) v.begin(),v.end()
#define bp(n) __builtin_popcountll(n)
#define fast ios_base::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL)

#define d0(a) cout<<a<<' ';
#define d1(a) cout<<a<<endl;
#define d2(a,b) cout<<a<<' '<<b<<endl;
#define d3(a,b,c) cout<<a<<' '<<b<<' '<<c<<endl;
#define d4(a,b,c,d) cout<<a<<' '<<b<<' '<<c<<' '<<d<<endl;
#define d5(a,b,c,d,e) cout<<a<<' '<<b<<' '<<c<<' '<<d<<' '<<e<<endl;
#define d6(a,b,c,d,e,f) cout<<a<<' '<<b<<' '<<c<<' '<<d<<' '<<e<<' '<<f<<endl;

const ll N=2e5+1,mod=1e9+7,bit=61;

ll a[N],ver,from[N],n;
long long dp[N];
vector<ll> adj[N],val[N];

void dfs(ll u,ll target)
{
    from[u]=target;
    ver++;
    for(auto v:adj[u])
    {
        if(from[v]!=target and a[v]%target==0)
        {
            dfs(v,target);
        }
    }
}

signed main()
{
    fast;

    ll t=1;
    //cin>>t;
    while(t--)
    {
        cin>>n;
        f(i,1,n)
        {
            cin>>a[i];
            val[a[i]].pb(i);
        }
        f(i,1,n-1)
        {
            ll u,v;
            cin>>u>>v;
            adj[u].pb(v);
            adj[v].pb(u);
        }
        rf(i,N-1,1)
        {
            dp[i]=0;
            for(int j=i;j<N;j+=i)
            {
                for(auto v:val[j])
                {
                    if(from[v]==i)
                    {
                        continue;
                    }
                    ver=0;
                    dfs(v,i);
                    dp[i]+=((long long)ver*((long long)ver+1LL))/2;
                }
            }
            for(int j=2*i;j<N;j+=i)
            {
                dp[i]-=dp[j];
            }
        }
        f(i,1,N-1)
        {
            if(dp[i])
            {
                cout<<i<<' '<<dp[i]<<endl;
            }
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long int ll;
typedef long double ld;
typedef pair<int,int> pi;
typedef pair<ll,ll> pll;

#define endl '\n'
#define ff first
#define ss second
#define int long long
#define pb push_back
#define f(i,l,r) for(ll i=l;i<=r;i++)
#define rf(i,r,l) for(ll i=r;i>=l;i--)
#define Max 5000001
#define inf 2147483647
#define llinf 9223372036854775807
#define all(v) v.begin(),v.end()
#define bp(n) __builtin_popcountll(n)
#define fast ios_base::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL)

#define d0(a) cout<<a<<' ';
#define d1(a) cout<<a<<endl;
#define d2(a,b) cout<<a<<' '<<b<<endl;
#define d3(a,b,c) cout<<a<<' '<<b<<' '<<c<<endl;
#define d4(a,b,c,d) cout<<a<<' '<<b<<' '<<c<<' '<<d<<endl;
#define d5(a,b,c,d,e) cout<<a<<' '<<b<<' '<<c<<' '<<d<<' '<<e<<endl;
#define d6(a,b,c,d,e,f) cout<<a<<' '<<b<<' '<<c<<' '<<d<<' '<<e<<' '<<f<<endl;

const ll N=2e5+1,mod=1e9+7,bit=61;

ll a[N],ver,from[N],n,dp[N];
vector<ll> adj[N],val[N];

void dfs(ll u,ll target)
{
    from[u]=target;
    ver++;
    for(auto v:adj[u])
    {
        if(from[v]!=target and a[v]%target==0)
        {
            dfs(v,target);
        }
    }
}

signed main()
{
    fast;

    ll t=1;
    //cin>>t;
    while(t--)
    {
        cin>>n;
        f(i,1,n)
        {
            cin>>a[i];
            val[a[i]].pb(i);
        }
        f(i,1,n-1)
        {
            ll u,v;
            cin>>u>>v;
            adj[u].pb(v);
            adj[v].pb(u);
        }
        rf(i,N-1,1)
        {
            dp[i]=0;
            for(int j=i;j<N;j+=i)
            {
                for(auto v:val[j])
                {
                    if(from[v]==i)
                    {
                        continue;
                    }
                    ver=0;
                    dfs(v,i);
                    dp[i]+=(ver*(ver+1))/2;
                }
            }
            for(int j=2*i;j<N;j+=i)
            {
                dp[i]-=dp[j];
            }
        }
        f(i,1,N-1)
        {
            if(dp[i])
            {
                cout<<i<<' '<<dp[i]<<endl;
            }
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef int ll;
typedef long double ld;
typedef pair<int,int> pi;
typedef pair<ll,ll> pll;

#define endl '\n'
#define ff first
#define ss second

#define pb push_back
#define f(i,l,r) for(ll i=l;i<=r;i++)
#define rf(i,r,l) for(ll i=r;i>=l;i--)
#define Max 5000001
#define inf 2147483647
#define llinf 9223372036854775807
#define all(v) v.begin(),v.end()
#define bp(n) __builtin_popcountll(n)
#define fast ios_base::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL)

#define d0(a) cout<<a<<' ';
#define d1(a) cout<<a<<endl;
#define d2(a,b) cout<<a<<' '<<b<<endl;
#define d3(a,b,c) cout<<a<<' '<<b<<' '<<c<<endl;
#define d4(a,b,c,d) cout<<a<<' '<<b<<' '<<c<<' '<<d<<endl;
#define d5(a,b,c,d,e) cout<<a<<' '<<b<<' '<<c<<' '<<d<<' '<<e<<endl;
#define d6(a,b,c,d,e,f) cout<<a<<' '<<b<<' '<<c<<' '<<d<<' '<<e<<' '<<f<<endl;

const ll N=2e5+1,mod=1e9+7,bit=61;

ll a[N],ver,from[N],n;
long long dp[N];
vector<pll> edges[N];
vector<ll> adj[N],val[N];

template<typename T>
class dsu
{
	public:
		vector<T> par,sz;
		ll n;
		dsu(ll n_)
		{
			n=n_;
			par.resize(n+1);
			sz.resize(n+1);
			for(int i=0;i<=n;i++)
			{
				par[i]=i;
				sz[i]=1;
			}
		}
		T getp(T x)
		{
			while(par[x]!=x)
			{
				par[x]=par[par[x]];
				x=par[x];
			}
			return x;
		}
		void merge(T a,T b,long long  &res)
		{
			T p1=getp(a),p2=getp(b);
			if(p1==p2)
			{
				return;
			}
			if(sz[p2]>sz[p1])
			{
				swap(p1,p2);
			}
			res-=((long long)sz[p1]*((long long)sz[p1]+1LL))/2;
			res-=((long long)sz[p2]*((long long)sz[p2]+1LL))/2;
			par[p2]=p1;
			sz[p1]+=sz[p2];
			res+=((long long)sz[p1]*((long long)sz[p1]+1LL))/2;
			sz[p2]=0;
		}
};

signed main()
{
    fast;

    ll t=1;
    //cin>>t;
    while(t--)
    {
        cin>>n;
        f(i,1,n)
        {
            cin>>a[i];
            val[a[i]].pb(i);
        }
        f(i,1,n-1)
        {
            ll u,v;
            cin>>u>>v;
            adj[u].pb(v);
            adj[v].pb(u);
            edges[__gcd(a[u],a[v])].pb({u,v});
        }
        rf(i,N-1,1)
        {
            dp[i]=0;
            dsu<int> obj(n);
            for(int j=i;j<N;j+=i)
            {
                dp[i]+=(int)val[j].size();
                for(auto u:edges[j])
                {
                    obj.merge(u.ff,u.ss,dp[i]);
                }
            }
            for(int j=2*i;j<N;j+=i)
            {
                dp[i]-=dp[j];
            }
        }
        f(i,1,N-1)
        {
            if(dp[i])
            {
                cout<<i<<' '<<dp[i]<<endl;
            }
        }
    }
    return 0;
}