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

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef map<int, int> mii;
typedef vector<mii> vmii;

const int MAXN = 2e5;

vvi pf;

void sieve()
{
    pf.resize(MAXN+1);

    for (int i = 2; i*i <= MAXN; ++i)
    {
        if (pf[i].empty())
        {
            for (int j = i; j <= MAXN; j += i)
            {
                pf[j].push_back(i);
            }
        }
    }
}

int n;
vi a;
vvi g;

void input()
{
    cin >> n;

    a.resize(n+1);
    for (int i = 1; i <= n; ++i)
    {
        cin >> a[i];
    }

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

vmii pft;

void tmplt()
{
    pft.resize(n+1);
    for (int i = 1; i <= n; ++i)
    {
        for (auto x: pf[a[i]])
        {
            pft[i].insert(pft[i].end(), {x, 0});
        }
    }
}

int gmax = 0;

int root;
vi pr;
void dfs(int z)
{
    if (g[z].size() == 1 && z != root)
    {
        for_each (pft[z].begin(), pft[z].end(), [](auto &x){x.second = 1;});
        // for (auto &p: pft[z])
        // {
        //     p.second = 1;
        // }

        if (a[z] != 1) gmax = max(gmax, 1);

        return;
    }

    for (auto y: g[z])
    {
        if (y == pr[z]) continue;

        pr[y] = z;
        dfs(y);
    }

    for (auto &fp: pft[z])
    {
        int mx1 = 0, mx2 = 0;
        for (auto y: g[z])
        {
            if (y == pr[z]) continue;

            // auto it = lower_bound(pft[y].begin(), pft[y].end(), fp, [](pii l, pii r){return l.first < r.first;});
            // if (it == pft[y].end()) break;
            // if (it->first != fp.first) continue;

            auto it = pft[y].find(fp.first);
            if (it == pft[y].end()) continue;

            int ct = it->second;
            if (ct > mx1)
            {
                mx2 = mx1;
                mx1 = ct;
            }
            else if (ct > mx2)
            {
                mx2 = ct;
            }
        }

        gmax = max(gmax, mx1 + mx2 + 1);
        fp.second = max(fp.second, mx1 + 1);
    }

}

void dfs_st()
{
    pr.resize(n+1);
    gmax = 0;

    for (int i = 1; i <= n; ++i)
    {
        if (g[i].size() <= 1)
        {
            root = i;
            break;
        }
    }

    dfs(root);
}

int main()
{
    sieve();
    input();
    tmplt();
    dfs_st();
    cout << gmax << endl;
}


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

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef map<int, int> mii;
typedef vector<mii> vmii;

const int MAXN = 2e5;

vvi pf;

void sieve()
{
    pf.resize(MAXN+1);

    for (int i = 2; i*i <= MAXN; ++i)
    {
        if (pf[i].empty())
        {
            for (int j = i; j <= MAXN; j += i)
            {
                pf[j].push_back(i);
            }
        }
    }
}

int n;
vi a;
vvi g;

void input()
{
    cin >> n;

    a.resize(n+1);
    for (int i = 1; i <= n; ++i)
    {
        cin >> a[i];
    }

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

vmii pft;

void tmplt()
{
    pft.resize(n+1);
    for (int i = 1; i <= n; ++i)
    {
        for (auto x: pf[a[i]])
        {
            pft[i].insert(pft[i].end(), {x, 0});
        }
    }
}

int gmax = 0;

int root;
vi pr;
void dfs(int z)
{
    if (g[z].size() == 1 && z != root)
    {
        // for_each (pft[z].begin(), pft[z].end(), [](auto &x){x.second = 1;});
        for (auto &p: pft[z])
        {
            p.second = 1;
        }

        if (a[z] != 1) gmax = max(gmax, 1);

        return;
    }

    for (auto y: g[z])
    {
        if (y == pr[z]) continue;

        pr[y] = z;
        dfs(y);
    }

    for (auto &fp: pft[z])
    {
        int mx1 = 0, mx2 = 0;
        for (auto y: g[z])
        {
            if (y == pr[z]) continue;

            // auto it = lower_bound(pft[y].begin(), pft[y].end(), fp, [](pii l, pii r){return l.first < r.first;});
            // if (it == pft[y].end()) break;
            // if (it->first != fp.first) continue;

            auto it = pft[y].find(fp.first);
            if (it == pft[y].end()) continue;

            int ct = it->second;
            if (ct > mx1)
            {
                mx2 = mx1;
                mx1 = ct;
            }
            else if (ct > mx2)
            {
                mx2 = ct;
            }
        }

        gmax = max(gmax, mx1 + mx2 + 1);
        fp.second = max(fp.second, mx1 + 1);
    }

}

void dfs_st()
{
    pr.resize(n+1);
    gmax = 0;

    for (int i = 1; i <= n; ++i)
    {
        if (g[i].size() <= 1)
        {
            root = i;
            break;
        }
    }

    dfs(root);
}

int main()
{
    sieve();
    input();
    tmplt();
    dfs_st();
    cout << gmax << endl;
}


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

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef map<int, int> mii;
typedef vector<mii> vmii;

const int MAXN = 2e5+5;

vvi pf;

void sieve()
{
    pf.resize(MAXN+1);

    for (int i = 2; i*i <= MAXN; ++i)
    {
        if (pf[i].empty())
        {
            for (int j = i; j <= MAXN; j += i)
            {
                pf[j].push_back(i);
            }
        }
    }
}

int n;
vi a;
vvi g;

void input()
{
    cin >> n;

    a.resize(n+1);
    for (int i = 1; i <= n; ++i)
    {
        cin >> a[i];
    }

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

vmii pft;

void tmplt()
{
    pft.resize(n+1);
    for (int i = 1; i <= n; ++i)
    {
        for (auto x: pf[a[i]])
        {
            pft[i].insert(pft[i].end(), {x, 0});
        }
    }
}

int gmax = 0;

int root;
vi pr;
void dfs(int z)
{
    if (g[z].size() == 1 && z != root)
    {
        // for_each (pft[z].begin(), pft[z].end(), [](auto &x){x.second = 1;});
        for (auto &p: pft[z])
        {
            p.second = 1;
        }

        if (a[z] != 1) gmax = max(gmax, 1);

        return;
    }

    for (auto y: g[z])
    {
        if (y == pr[z]) continue;

        pr[y] = z;
        dfs(y);
    }

    for (auto &fp: pft[z])
    {
        int mx1 = 0, mx2 = 0;
        for (auto y: g[z])
        {
            if (y == pr[z]) continue;

            // auto it = lower_bound(pft[y].begin(), pft[y].end(), fp, [](pii l, pii r){return l.first < r.first;});
            // if (it == pft[y].end()) break;
            // if (it->first != fp.first) continue;

            auto it = pft[y].find(fp.first);
            if (it == pft[y].end()) continue;

            int ct = it->second;
            if (ct > mx1)
            {
                mx2 = mx1;
                mx1 = ct;
            }
            else if (ct > mx2)
            {
                mx2 = ct;
            }
        }

        gmax = max(gmax, mx1 + mx2 + 1);
        fp.second = max(fp.second, mx1 + 1);
    }

}

void dfs_st()
{
    pr.resize(n+1);
    gmax = 0;

    for (int i = 1; i <= n; ++i)
    {
        if (g[i].size() <= 1)
        {
            root = i;
            break;
        }
    }

    dfs(root);
}

int main()
{
    sieve();
    input();
    tmplt();
    dfs_st();
    cout << gmax << endl;
}


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

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;
typedef vector<pii> vp;
typedef vector<vp> vvp;

const int MAXN = 2e5;

vvi pf;

void sieve()
{
    pf.resize(MAXN+1);

    for (int i = 2; i <= MAXN; ++i)
    {
        if (pf[i].empty())
        {
            for (int j = i; j <= MAXN; j += i)
            {
                pf[j].push_back(i);
            }
        }
    }
}

int n;
vi a;
vvi g;

void input()
{
    cin >> n;

    a.resize(n+1);
    for (int i = 1; i <= n; ++i)
    {
        cin >> a[i];
    }

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

vvp pft;

void tmplt()
{
    pft.resize(n+1);
    for (int i = 1; i <= n; ++i)
    {
        vp &p = pft[i];
        for (auto x: pf[a[i]])
        {
            p.push_back({x, 0});
        }
    }
}

int gmax = 0;

int root;
vi pr;
void dfs(int z)
{
    if (g[z].size() == 1 && z != root)
    {
        for (auto &p: pft[z])
        {
            p.second = 1;
        }

        if (a[z] != 1) gmax = max(gmax, 1);

        return;
    }

    for (auto y: g[z])
    {
        if (y == pr[z]) continue;

        pr[y] = z;
        dfs(y);
    }

    for (auto &fp: pft[z])
    {
        int mx1 = 0, mx2 = 0;
        bool f = false;
        for (auto y: g[z])
        {
            if (y == pr[z]) continue;

            auto it = lower_bound(pft[y].begin(), pft[y].end(), fp, [](pii l, pii r){return l.first < r.first;});
            if (it == pft[y].end()) continue;
            if (it->first != fp.first) continue;

            int ct = it->second;
            if (ct > mx1)
            {
                mx2 = mx1;
                mx1 = ct;
            }
            else if (ct > mx2)
            {
                mx2 = ct;
            }
        }

        int k = a[z] == 1 ? 0 : 1;
        gmax = max(gmax, mx1 + mx2 + k);
        fp.second = max(fp.second, mx1 + k);
    }

}

void dfs_st()
{
    pr.resize(n+1);
    gmax = 0;

    for (int i = 1; i <= n; ++i)
    {
        if (g[i].size() == 1)
        {
            root = i;
            break;
        }
    }

    dfs(root);
}

int main()
{
    sieve();
    input();
    tmplt();
    dfs_st();
    cout << gmax << endl;
}


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

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef map<int, int> mii;
typedef vector<mii> vmii;

const int MAXN = 2e5;

vvi pf;

void sieve()
{
    pf.resize(MAXN+1);

    for (int i = 2; i <= MAXN; ++i)
    {
        if (pf[i].empty())
        {
            for (int j = i; j <= MAXN; j += i)
            {
                pf[j].push_back(i);
            }
        }
    }
}

int n;
vi a;
vvi g;

void input()
{
    cin >> n;

    a.resize(n+1);
    for (int i = 1; i <= n; ++i)
    {
        cin >> a[i];
    }

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

vmii pft;

void tmplt()
{
    pft.resize(n+1);
    for (int i = 1; i <= n; ++i)
    {
        for (auto x: pf[a[i]])
        {
            pft[i].insert(pft[i].end(), {x, 0});
        }
    }
}

int gmax = 0;

vi pr;
void dfs(int z)
{
    if (g[z].size() == 1)
    {
        for_each (pft[z].begin(), pft[z].end(), [](auto &x){x.second = 1;});
        // for (auto &p: pft[z])
        // {
        //     p.second = 1;
        // }

        if (a[z] != 1) gmax = max(gmax, 1);

        return;
    }

    for (auto y: g[z])
    {
        if (y == pr[z]) continue;

        pr[y] = z;
        dfs(y);
    }

    for (auto &fp: pft[z])
    {
        int mx1 = 0, mx2 = 0;
        for (auto y: g[z])
        {
            if (y == pr[z]) continue;

            // auto it = lower_bound(pft[y].begin(), pft[y].end(), fp, [](pii l, pii r){return l.first < r.first;});
            // if (it == pft[y].end()) break;
            // if (it->first != fp.first) continue;

            auto it = pft[y].find(fp.first);
            if (it == pft[y].end()) continue;

            int ct = it->second;
            if (ct > mx1)
            {
                mx2 = mx1;
                mx1 = ct;
            }
            else if (ct > mx2)
            {
                mx2 = ct;
            }
        }

        gmax = max(gmax, mx1 + mx2 + 1);
        fp.second = max(fp.second, mx1 + 1);
    }

}

void dfs_st()
{
    pr.resize(n+1);
    g[1].push_back(0);
    pr[1] = 0;
    gmax = 0;
    dfs(1);
}

int main()
{
    sieve();
    input();
    tmplt();
    dfs_st();
    cout << gmax << endl;
}


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

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;
typedef vector<pii> vp;
typedef vector<vp> vvp;

const int MAXN = 2e5+5;

vvi pf;

void sieve()
{
    pf.resize(MAXN+1);

    for (int i = 2; i <= MAXN; ++i)
    {
        if (pf[i].empty())
        {
            for (int j = i; j <= MAXN; j += i)
            {
                pf[j].push_back(i);
            }
        }
    }
}

int n;
vi a;
vvi g;

void input()
{
    cin >> n;

    a.resize(n+1);
    for (int i = 1; i <= n; ++i)
    {
        cin >> a[i];
    }

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

vvp pft;

void tmplt()
{
    pft.resize(n+1);
    for (int i = 1; i <= n; ++i)
    {
        vp &p = pft[i];
        for (auto x: pf[a[i]])
        {
            p.push_back({x, 0});
        }
    }
}

int gmax;

int root;
vi pr;
void dfs(int z)
{
    // cout << "d " << z << " entered" << endl;
    if (g[z].size() == 1 && z != root)
    {
        for (auto &p: pft[z])
        {
            p.second = 1;
        }

        // cout << "d " << z << " completed with pft[z] = ";
        // for (auto p: pft[z])
        // {
        //     cout << p.first << ": " << p.second << ", ";
        // }
        // cout << endl;

        return;
    }

    for (auto y: g[z])
    {
        if (y == pr[z]) continue;

        pr[y] = z;
        dfs(y);
    }

    for (auto &fp: pft[z])
    {
        int mx1 = 0, mx2 = 0;
        for (auto y: g[z])
        {
            if (y == pr[z]) continue;

            auto it = lower_bound(pft[y].begin(), pft[y].end(), fp, [](pii l, pii r){return l.first < r.first;});
            if (it->first != fp.first) continue;

            int ct = it->second;
            // cout << ct << " at it->first = " << it->first << " fp.first = " << fp.first << endl;
            if (ct > mx1)
            {
                mx2 = mx1;
                mx1 = ct;
            }
            else if (ct > mx2)
            {
                mx2 = ct;
            }
        }

        gmax = max(gmax, mx1 + mx2 + 1);
        // cout << "mx1 = " << mx1 << endl;
        fp.second = max(fp.second, mx1 + 1);
    }

    // cout << "d " << z << " completed with pft[z] = ";
    // for (auto p: pft[z])
    // {
    //     cout << p.first << ": " << p.second << ", ";
    // }
    // cout << endl;
}

void dfs_st()
{
    pr.resize(n+1);
    gmax = 0;

    for (int i = 1; i <= n; ++i)
    {
        if (g[i].size() == 1)
        {
            root = i;
            break;
        }
    }

    dfs(root);
}

int main()
{
    sieve();
    // cout << "s" << endl;
    input();
    // cout << "i" << endl;
    tmplt();
    // cout << "t" << endl;
    dfs_st();
    // cout << "d" << endl;
    cout << gmax << endl;
}


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

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;
typedef vector<pii> vp;
typedef vector<vp> vvp;

const int MAXN = 2e5+5;

vvi pf;

void sieve()
{
    pf.resize(MAXN+1);

    for (int i = 2; i <= MAXN; ++i)
    {
        if (pf[i].empty())
        {
            for (int j = i; j <= MAXN; j += i)
            {
                pf[j].push_back(i);
            }
        }
    }
}

int n;
vi a;
vvi g;

void input()
{
    cin >> n;

    a.resize(MAXN+1);
    for (int i = 1; i <= n; ++i)
    {
        cin >> a[i];
    }

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

vvp pft;

void tmplt()
{
    pft.resize(MAXN+1);
    for (int i = 1; i <= n; ++i)
    {
        vp &p = pft[i];
        for (auto x: pf[a[i]])
        {
            p.push_back({x, 0});
        }
    }
}

int gmax;

int root;
vi pr;
void dfs(int z)
{
    // cout << "d " << z << " entered" << endl;
    if (g[z].size() == 1 && z != root)
    {
        for (auto &p: pft[z])
        {
            p.second = 1;
        }

        // cout << "d " << z << " completed with pft[z] = ";
        // for (auto p: pft[z])
        // {
        //     cout << p.first << ": " << p.second << ", ";
        // }
        // cout << endl;

        return;
    }

    for (auto y: g[z])
    {
        if (y == pr[z]) continue;

        pr[y] = z;
        dfs(y);
    }

    for (auto &fp: pft[z])
    {
        int mx1 = 0, mx2 = 0;
        for (auto y: g[z])
        {
            if (y == pr[z]) continue;

            auto it = lower_bound(pft[y].begin(), pft[y].end(), fp, [](pii l, pii r){return l.first < r.first;});
            if (it->first != fp.first) continue;

            int ct = it->second;
            // cout << ct << " at it->first = " << it->first << " fp.first = " << fp.first << endl;
            if (ct > mx1)
            {
                mx2 = mx1;
                mx1 = ct;
            }
            else if (ct > mx2)
            {
                mx2 = ct;
            }
        }

        gmax = max(gmax, mx1 + mx2 + 1);
        // cout << "mx1 = " << mx1 << endl;
        fp.second = max(fp.second, mx1 + 1);
    }

    // cout << "d " << z << " completed with pft[z] = ";
    // for (auto p: pft[z])
    // {
    //     cout << p.first << ": " << p.second << ", ";
    // }
    // cout << endl;
}

void dfs_st()
{
    pr.resize(MAXN+1);
    gmax = 0;

    for (int i = 1; i <= n; ++i)
    {
        if (g[i].size() == 1)
        {
            root = i;
            break;
        }
    }

    dfs(root);
}

int main()
{
    sieve();
    // cout << "s" << endl;
    input();
    // cout << "i" << endl;
    tmplt();
    // cout << "t" << endl;
    dfs_st();
    // cout << "d" << endl;
    cout << gmax << endl;
}


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

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;
typedef vector<pii> vp;
typedef vector<vp> vvp;

const int MAXN = 2e5;

vvi pf;

void sieve()
{
    pf.resize(MAXN+1);

    for (int i = 2; i <= MAXN; ++i)
    {
        if (pf[i].empty())
        {
            for (int j = i; j <= MAXN; j += i)
            {
                pf[j].push_back(i);
            }
        }
    }
}

int n;
vi a;
vvi g;

void input()
{
    cin >> n;

    a.resize(n+1);
    for (int i = 1; i <= n; ++i)
    {
        cin >> a[i];
    }

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

vvp pft;

void tmplt()
{
    pft.resize(n+1);
    for (int i = 1; i <= n; ++i)
    {
        vp &p = pft[i];
        for (auto x: pf[a[i]])
        {
            p.push_back({x, 0});
        }
    }
}

int gmax = 0;

int root;
vi pr;
void dfs(int z)
{
    if (g[z].size() == 1 && z != root)
    {
        for (auto &p: pft[z])
        {
            p.second = 1;
        }

        if (a[z] != 1) gmax = max(gmax, 1);

        return;
    }

    for (auto y: g[z])
    {
        if (y == pr[z]) continue;

        pr[y] = z;
        dfs(y);
    }

    for (auto &fp: pft[z])
    {
        int mx1 = 0, mx2 = 0;
        for (auto y: g[z])
        {
            if (y == pr[z]) continue;

            // auto it = lower_bound(pft[y].begin(), pft[y].end(), fp, [](pii l, pii r){return l.first < r.first;});
            // if (it == pft[y].end()) break;
            // if (it->first != fp.first) continue;

            auto it = find_if(pft[y].begin(), pft[y].end(), [&fp](pii x){return x.first == fp.first;});
            if (it == pft[y].end()) continue;

            int ct = it->second;
            if (ct > mx1)
            {
                mx2 = mx1;
                mx1 = ct;
            }
            else if (ct > mx2)
            {
                mx2 = ct;
            }
        }

        gmax = max(gmax, mx1 + mx2 + 1);
        fp.second = max(fp.second, mx1 + 1);
    }

}

void dfs_st()
{
    pr.resize(n+1);
    gmax = 0;

    for (int i = 1; i <= n; ++i)
    {
        if (g[i].size() <= 1)
        {
            root = i;
            break;
        }
    }

    dfs(root);
}

int main()
{
    sieve();
    input();
    tmplt();
    dfs_st();
    cout << gmax << endl;
}


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

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef map<int, int> mii;
typedef vector<mii> vmii;

const int MAXN = 2e5;

vvi pf;

void sieve()
{
    pf.resize(MAXN+1);

    for (int i = 2; i*i <= MAXN; ++i)
    {
        if (pf[i].empty())
        {
            for (int j = i; j <= MAXN; j += i)
            {
                pf[j].push_back(i);
            }
        }
    }
}

int n;
vi a;
vvi g;

void input()
{
    cin >> n;

    a.resize(n+1);
    for (int i = 1; i <= n; ++i)
    {
        cin >> a[i];
    }

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

vmii pft;

void tmplt()
{
    pft.resize(n+1);
    for (int i = 1; i <= n; ++i)
    {
        for (auto x: pf[a[i]])
        {
            pft[i].insert(pft[i].end(), {x, 0});
        }
    }
}

int gmax = 0;

int root;
vi pr;
void dfs(int z)
{
    if (g[z].size() == 1 && z != root)
    {
        for_each (pft[z].begin(), pft[z].begin(), [](auto &x){x.second = 1;});
        // for (auto &p: pft[z])
        // {
        //     p.second = 1;
        // }

        if (a[z] != 1) gmax = max(gmax, 1);

        return;
    }

    for (auto y: g[z])
    {
        if (y == pr[z]) continue;

        pr[y] = z;
        dfs(y);
    }

    for (auto &fp: pft[z])
    {
        int mx1 = 0, mx2 = 0;
        for (auto y: g[z])
        {
            if (y == pr[z]) continue;

            // auto it = lower_bound(pft[y].begin(), pft[y].end(), fp, [](pii l, pii r){return l.first < r.first;});
            // if (it == pft[y].end()) break;
            // if (it->first != fp.first) continue;

            auto it = pft[y].find(fp.first);
            if (it == pft[y].end()) continue;

            int ct = it->second;
            if (ct > mx1)
            {
                mx2 = mx1;
                mx1 = ct;
            }
            else if (ct > mx2)
            {
                mx2 = ct;
            }
        }

        gmax = max(gmax, mx1 + mx2 + 1);
        fp.second = max(fp.second, mx1 + 1);
    }

}

void dfs_st()
{
    pr.resize(n+1);
    gmax = 0;

    for (int i = 1; i <= n; ++i)
    {
        if (g[i].size() <= 1)
        {
            root = i;
            break;
        }
    }

    dfs(root);
}

int main()
{
    sieve();
    input();
    tmplt();
    dfs_st();
    cout << gmax << endl;
}


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

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;
typedef vector<pii> vp;
typedef vector<vp> vvp;

const int MAXN = 2e5;

vvi pf;

void sieve()
{
    pf.resize(MAXN+1);

    for (int i = 2; i <= MAXN; ++i)
    {
        if (pf[i].empty())
        {
            for (int j = i; j <= MAXN; j += i)
            {
                pf[j].push_back(i);
            }
        }
    }
}

int n;
vi a;
vvi g;

void input()
{
    cin >> n;

    a.resize(n+1);
    for (int i = 1; i <= n; ++i)
    {
        cin >> a[i];
    }

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

vvp pft;

void tmplt()
{
    pft.resize(n+1);
    for (int i = 1; i <= n; ++i)
    {
        vp &p = pft[i];
        for (auto x: pf[a[i]])
        {
            p.push_back({x, 0});
        }
    }
}

int gmax;

int root;
vi pr;
void dfs(int z)
{
    if (a[z] == 1)
    {
        for (auto y: g[z])
        {
            if (y == pr[z]) continue;
            pr[y] = z;
            dfs(y);
        }
        return;
    }
    // cout << "d " << z << " entered" << endl;
    if (g[z].size() == 1 && z != root)
    {
        for (auto &p: pft[z])
        {
            p.second = 1;
        }

        // cout << "d " << z << " completed with pft[z] = ";
        // for (auto p: pft[z])
        // {
        //     cout << p.first << ": " << p.second << ", ";
        // }
        // cout << endl;

        return;
    }

    for (auto y: g[z])
    {
        if (y == pr[z]) continue;

        pr[y] = z;
        dfs(y);
    }

    for (auto &fp: pft[z])
    {
        int mx1 = 0, mx2 = 0;
        for (auto y: g[z])
        {
            if (y == pr[z]) continue;

            auto it = lower_bound(pft[y].begin(), pft[y].end(), fp, [](pii l, pii r){return l.first < r.first;});
            if (it->first != fp.first) continue;

            int ct = it->second;
            // cout << ct << " at it->first = " << it->first << " fp.first = " << fp.first << endl;
            if (ct > mx1)
            {
                mx2 = mx1;
                mx1 = ct;
            }
            else if (ct > mx2)
            {
                mx2 = ct;
            }
        }

        gmax = max(gmax, mx1 + mx2 + 1);
        // cout << "mx1 = " << mx1 << endl;
        fp.second = max(fp.second, mx1 + 1);
    }

    // cout << "d " << z << " completed with pft[z] = ";
    // for (auto p: pft[z])
    // {
    //     cout << p.first << ": " << p.second << ", ";
    // }
    // cout << endl;
}

void dfs_st()
{
    pr.resize(n+1);
    gmax = 0;

    for (int i = 1; i <= n; ++i)
    {
        if (g[i].size() == 1)
        {
            root = i;
            break;
        }
    }

    dfs(root);
}

int main()
{
    sieve();
    // cout << "s" << endl;
    input();
    // cout << "i" << endl;
    tmplt();
    // cout << "t" << endl;
    dfs_st();
    // cout << "d" << endl;
    cout << gmax << endl;
}


#include<bits/stdc++.h>
using namespace std;
# define ll long long
const int maxn = 4e5+100;
int a[maxn],num,head[maxn],maxx;
map<int,int>dis[maxn];
struct node
{
    int nex;
    int to;
} edge[maxn];
void init()
{
    maxx=0;
    num=0;
    memset(head,-1,sizeof(head));
}
int gcd(int n,int m)
{
    if(n<m)
        swap(n,m);
    return n%m==0?m:gcd(m,n%m);
}
void addedge(int fr,int to)
{
    edge[num].nex=head[fr];
    edge[num].to=to;
    head[fr]=num++;
}
void dfs(int fr,int rt)
{
    if(a[fr]>1)
        dis[fr][a[fr]]=1;
    for(int i=head[fr]; i!=-1; i=edge[i].nex)
    {
        int to=edge[i].to;
        if(to==rt)
            continue;
        dfs(to,fr);
        for(auto t1:dis[fr])
        {
            for(auto t2:dis[to])
            {
                if(gcd(t1.first,t2.first)!=1)
                    maxx=max(maxx,t1.second+t2.second);
            }
        }
        for(auto t1:dis[to])
        {
            int tmp=gcd(t1.first,a[fr]);
            if(tmp==1)
                continue;
            dis[fr][tmp]=max(dis[fr][tmp],t1.second+1);
        }
    }
}
int main()
{
    init();
    int n;
    scanf("%d",&n);
    int t1,t2;
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        if(a[i]!=1)
            maxx=1;
    }
    for(int i=1; i<=n-1; i++)
    {
        scanf("%d %d",&t1,&t2);
        addedge(t1,t2);
        addedge(t2,t1);
    }
    dfs(1,1);
    printf("%d\n",maxx);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
# define ll long long
const int maxn = 2e5+100;
int a[maxn],num,head[maxn],maxx;
map<int,int>dis[maxn];
int con[maxn];
struct node
{
    int nex;
    int to;
} edge[maxn];
void init()
{
    maxx=0;
    num=0;
    memset(head,-1,sizeof(head));
}
int gcd(int n,int m)
{
    if(n<m)
        swap(n,m);
    return n%m==0?m:gcd(m,n%m);
}
void addedge(int fr,int to)
{
    edge[num].nex=head[fr];
    edge[num].to=to;
    head[fr]=num++;
}
void dfs(int fr,int rt)
{
    if(a[fr]>1)
        dis[fr][a[fr]]=1;
    for(int i=head[fr]; i!=-1; i=edge[i].nex)
    {
        int to=edge[i].to;
        if(to==rt)
            continue;
        dfs(to,fr);
        for(auto t1:dis[fr])
        {
            for(auto t2:dis[to])
            {
                if(gcd(t1.first,t2.first)!=1)
                    maxx=max(maxx,t1.second+t2.second);
            }
        }
                for(auto t1:dis[to])
        {
            int tmp=gcd(t1.first,a[fr]);
            if(tmp==1)
                continue;
            dis[fr][tmp]=max(dis[fr][tmp],t1.second+1);
        }
    }
}
int main()
{
    init();
    int n;
    scanf("%d",&n);
    int t1,t2;
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        if(a[i]!=1)
            maxx=1;
    }
    for(int i=1; i<=n-1; i++)
    {
        scanf("%d %d",&t1,&t2);
        addedge(t1,t2);
        addedge(t2,t1);
    }
    dfs(1,1);
    printf("%d\n",maxx);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
# define ll long long
const int maxn = 4e5+100;
int a[maxn],num,head[maxn],maxx;
map<int,int>dis[maxn];
struct node
{
    int nex;
    int to;
} edge[maxn];
void init()
{
    maxx=0;
    num=0;
    memset(head,-1,sizeof(head));
}
int gcd(int n,int m)
{
    if(n<m)
        swap(n,m);
    return n%m==0?m:gcd(m,n%m);
}
void addedge(int fr,int to)
{
    edge[num].nex=head[fr];
    edge[num].to=to;
    head[fr]=num++;
}
void dfs(int fr,int rt)
{
    if(a[fr]>1)
        dis[fr][a[fr]]=1;
    for(int i=head[fr]; i!=-1; i=edge[i].nex)
    {
        int to=edge[i].to;
        if(to==rt)
            continue;
        dfs(to,fr);
//        for(auto t1:dis[fr])
//        {
//            for(auto t2:dis[to])
//            {
//                if(gcd(t1.first,t2.first)!=1)
//                    maxx=max(maxx,t1.second+t2.second);
//            }
//        }
        for(auto t1:dis[to])
        {
            int tmp=gcd(t1.first,a[fr]);
            if(tmp==1)
                continue;
            dis[fr][tmp]=max(dis[fr][tmp],t1.second+1);
            maxx=max(maxx,dis[fr][tmp]);
        }
    }
}
int main()
{
    init();
    int n;
    scanf("%d",&n);
    int t1,t2;
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        if(a[i]!=1)
            maxx=1;
    }
    for(int i=1; i<=n-1; i++)
    {
        scanf("%d %d",&t1,&t2);
        addedge(t1,t2);
        addedge(t2,t1);
    }
    dfs(1,1);
    printf("%d\n",maxx);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
# define ll long long
const int maxn = 4e5+100;
int a[maxn],num,head[maxn],maxx;
map<int,int>dis[maxn];
struct node
{
    int nex;
    int to;
} edge[maxn];
void init()
{
    maxx=0;
    num=0;
    memset(head,-1,sizeof(head));
}
int gcd(int n,int m)
{
    if(n<m)
        swap(n,m);
    return n%m==0?m:gcd(m,n%m);
}
void addedge(int fr,int to)
{
    edge[num].nex=head[fr];
    edge[num].to=to;
    head[fr]=num++;
}
void dfs(int fr,int rt)
{
    if(a[fr]>1)
    {
        dis[fr][a[fr]]=1;
    }
    for(int i=head[fr]; i!=-1; i=edge[i].nex)
    {
        int to=edge[i].to;
        if(to==rt)
            continue;
            dfs(to,fr);
        for(auto t1:dis[fr])
        {
            for(auto t2:dis[to])
            {
                if(gcd(t1.first,t2.first)!=1)
                {
                    maxx=max(maxx,t1.second+t2.second);
                }
            }
        }
        for(auto t1:dis[to])
        {
            int tmp=gcd(a[fr],t1.first);
            if(tmp==1)
                continue;
            dis[fr][tmp]=max(dis[fr][tmp],t1.second+1);
        }
    }
}
int main()
{
    init();
    int n;
    scanf("%d",&n);
    int t1,t2;
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        if(a[i]!=1)
            maxx=1;
    }
    for(int i=1; i<=n-1; i++)
    {
        scanf("%d %d",&t1,&t2);
        addedge(t1,t2);
        addedge(t2,t1);
    }
    dfs(1,1);
    printf("%d\n",maxx);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
# define ll long long
const int maxn = 2e5+100;
int a[maxn],num,head[maxn],maxx;
map<int,int>dis[3*maxn];
struct node
{
    int nex;
    int to;
} edge[maxn];
void init()
{
    maxx=0;
    num=0;
    memset(head,-1,sizeof(head));
}
int gcd(int n,int m)
{
    if(n<m)
        swap(n,m);
    return n%m==0?m:gcd(m,n%m);
}
void addedge(int fr,int to)
{
    edge[num].nex=head[fr];
    edge[num].to=to;
    head[fr]=num++;
}
void dfs(int fr,int rt)
{
    if(a[fr]>1)
        dis[fr][a[fr]]=1;
    for(int i=head[fr]; i!=-1; i=edge[i].nex)
    {
        int to=edge[i].to;
        if(to==rt)
            continue;
        dfs(to,fr);
        for(auto t1:dis[fr])
        {
            for(auto t2:dis[to])
            {
                if(gcd(t1.first,t2.first)!=1)
                    maxx=max(maxx,t1.second+t2.second);
            }
        }
        for(auto t1:dis[to])
        {
            int tmp=gcd(t1.first,a[fr]);
            if(tmp==1)
                continue;
            dis[fr][tmp]=max(dis[fr][tmp],t1.second+1);
        }
    }
}
int main()
{
    init();
    int n;
    scanf("%d",&n);
    int t1,t2;
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        if(a[i]!=1)
            maxx=1;
    }
    for(int i=1; i<=n-1; i++)
    {
        scanf("%d %d",&t1,&t2);
        addedge(t1,t2);
        addedge(t2,t1);
    }
    dfs(1,1);
    printf("%d\n",maxx);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
# define ll long long
const int maxn = 2e5+100;
int a[maxn],num,head[maxn],maxx;
struct node
{
    int nex;
    int to;
} edge[maxn];
void init()
{
    maxx=0;
    num=0;
    memset(head,-1,sizeof(head));
}
int gcd(int n,int m)
{
    if(n<m)
        swap(n,m);
    return n%m==0?m:gcd(m,n%m);
}
void addedge(int fr,int to)
{
    edge[num].nex=head[fr];
    edge[num].to=to;
    head[fr]=num++;
}
void dfs(int num,int tmp,int fr,int rt)
{
    if(num>1)
    maxx=max(maxx,num);
    for(int i=head[fr]; i!=-1; i=edge[i].nex)
    {
        int to=edge[i].to;
        if(to==rt)
            continue;
            int t=gcd(tmp,a[to]);
            if(t!=1){
            dfs(num+1,t,to,fr);
            dfs(num+1,a[to],to,fr);
            }
    }
}
int main()
{
    init();
    int n;
    scanf("%d",&n);
    int t1,t2;
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        if(a[i]!=1)
            maxx=1;
    }
    for(int i=1; i<=n-1; i++)
    {
        scanf("%d %d",&t1,&t2);
        addedge(t1,t2);
        addedge(t2,t1);
    }
    dfs(1,a[1],1,-1);
    printf("%d\n",maxx);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
# define ll long long
const int maxn = 2e5+100;
int a[maxn],num,head[maxn],maxx;
struct node
{
    int nex;
    int to;
} edge[maxn];
void init()
{
    maxx=0;
    num=0;
    memset(head,-1,sizeof(head));
}
int gcd(int n,int m)
{
    if(n<m)
        swap(n,m);
    return n%m==0?m:gcd(m,n%m);
}
void addedge(int fr,int to)
{
    edge[num].nex=head[fr];
    edge[num].to=to;
    head[fr]=num++;
}
void dfs(int num,int tmp,int fr,int rt)
{
    if(num>1&&tmp>1)
        maxx=max(maxx,num);
    for(int i=head[fr]; i!=-1; i=edge[i].nex)
    {
        int to=edge[i].to;
        if(to==rt)
            continue;
        int t=gcd(tmp,a[to]);
        if(t!=1)
        {
            dfs(num+1,t,to,fr);
            dfs(num+1,a[to],to,fr);
        }
        else dfs(1,a[to],to,fr);
    }
}
int main(){
    init();
    int n;
    scanf("%d",&n);
    int t1,t2;
    for(int i=1; i<=n; i++){
        scanf("%d",&a[i]);
        if(a[i]!=1)
            maxx=1;
    }
    for(int i=1; i<=n-1; i++){
        scanf("%d %d",&t1,&t2);
        addedge(t1,t2);
        addedge(t2,t1);
    }
    dfs(1,a[1],1,-1);
    printf("%d\n",maxx);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
# define ll long long
const int maxn = 2e5+100;
int a[maxn],num,head[maxn],maxx;
struct node
{
    int nex;
    int to;
} edge[maxn];
void init()
{
    maxx=0;
    num=0;
    memset(head,-1,sizeof(head));
}
int gcd(int n,int m)
{
    if(n<m)
        swap(n,m);
    return n%m==0?m:gcd(m,n%m);
}
void addedge(int fr,int to)
{
    edge[num].nex=head[fr];
    edge[num].to=to;
    head[fr]=num++;
}
void dfs(int num,int tmp,int fr,int rt)
{
    if(num>1)
        maxx=max(maxx,num);
    for(int i=head[fr]; i!=-1; i=edge[i].nex)
    {
        int to=edge[i].to;
        if(to==rt)
            continue;
        int t=gcd(tmp,a[to]);
        if(t!=1)
        {
            dfs(num+1,t,to,fr);
            dfs(num+1,a[to],to,fr);
        }
        else dfs(1,a[to],to,fr);
    }
}
int main(){
    init();
    int n;
    scanf("%d",&n);
    int t1,t2;
    for(int i=1; i<=n; i++){
        scanf("%d",&a[i]);
        if(a[i]!=1)
            maxx=1;
    }
    for(int i=1; i<=n-1; i++){
        scanf("%d %d",&t1,&t2);
        addedge(t1,t2);
        addedge(t2,t1);
    }
    dfs(1,a[1],1,-1);
    printf("%d\n",maxx);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
# define ll long long
const int maxn = 2e5+100;
int a[maxn],num,head[maxn],maxx;
struct node
{
    int nex;
    int to;
} edge[maxn];
void init()
{
    maxx=0;
    num=0;
    memset(head,-1,sizeof(head));
}
int gcd(int n,int m)
{
    if(n<m)
        swap(n,m);
    return n%m==0?m:gcd(m,n%m);
}
void addedge(int fr,int to)
{
    edge[num].nex=head[fr];
    edge[num].to=to;
    head[fr]=num++;
}
void dfs(int num,int tmp,int fr,int rt)
{
    if(num>1&&tmp>1)
        maxx=max(maxx,num);
    for(int i=head[fr]; i!=-1; i=edge[i].nex)
    {
        int to=edge[i].to;
        if(to==rt)
            continue;
        int t=gcd(tmp,a[to]);
        if(t!=1)
        {
            dfs(num+1,t,to,fr);
        //    dfs(1,a[to],to,fr);
        }
            dfs(1,a[to],to,fr);
    }
}
int main()
{
    init();
    int n;
    scanf("%d",&n);
    int t1,t2;
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        if(a[i]!=1)
            maxx=1;
    }
    for(int i=1; i<=n-1; i++)
    {
        scanf("%d %d",&t1,&t2);
        addedge(t1,t2);
        addedge(t2,t1);
    }
    dfs(1,a[1],1,-1);
    printf("%d\n",maxx);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
using namespace __gnu_cxx;

typedef double db;
typedef long long ll;
typedef pair<db, db> pdd;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef unsigned long long ull;

#define F          first
#define S          second
#define pnl        printf("\n")
#define sz(x)      (int)x.size()
#define sf(x)      scanf("%d",&x)
#define pf(x)      printf("%d\n",x)
#define all(x)     x.begin(),x.end()
#define rall(x)    x.rbegin(),x.rend()
#define rep(i, n)  for(int i = 0; i < n; ++i)

const db eps = 1e-9;
const db pi = acos(-1);
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1000 * 1000 * 1000 + 7;

int n, a[200005];
vector<int> adj[200200];
vector<int> divs[200055];

void init() {
    for (int i = 1; i < 200005; ++i) {
        for (int j = 1; j * j <= i; ++j) {
            if (i / j * j != i) continue;
            int k = i / j;
            if (j > 1) divs[i].push_back(j);
            if (k != j && k > 1) divs[i].push_back(k);
        }
        sort(all(divs[i]));
    }
}

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

int ans;

map<int, int> dfs(int u, int p) {
    map<int, int> me;
    if (a[u] > 1) me[a[u]] = 1;
    for (auto v : adj[u]) {
        if (v == p) continue;
        map<int, int> tmp = dfs(v, u);
        for (auto it : me) {
            int g = gcd(it.F, a[v]);
            if (g == 1) continue;
            ans = max(ans, me[g] + tmp[g]);
            me[g] = max(me[g], tmp[g] + 1);
        }
    }
    for (int i = 0; i < sz(divs[a[u]]); ++i) {
        int d = divs[a[u]][i];
        for (int j = d + d; j <= a[u]; ++j)
            if (me.count(j) != 0)
                me[d] = max(me[d], me[j]);
    }
    for (auto it : me)
        ans = max(ans, it.S);
    return me;
}

int main() {
    init();
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    for (int i = 1; i < n; ++i) {
        int u, v;
        scanf("%d%d", &u, &v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    dfs(1, 0);
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
using namespace __gnu_cxx;

typedef double db;
typedef long long ll;
typedef pair<db, db> pdd;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef unsigned long long ull;

#define F          first
#define S          second
#define pnl        printf("\n")
#define sz(x)      (int)x.size()
#define sf(x)      scanf("%d",&x)
#define pf(x)      printf("%d\n",x)
#define all(x)     x.begin(),x.end()
#define rall(x)    x.rbegin(),x.rend()
#define rep(i, n)  for(int i = 0; i < n; ++i)

const db eps = 1e-9;
const db pi = acos(-1);
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1000 * 1000 * 1000 + 7;

int n, a[200005];
vector<int> adj[200200];
vector<int> divs[200055];

void init() {
    for (int i = 1; i < 200005; ++i) {
        for (int j = 1; j * j <= i; ++j) {
            if (i / j * j != i) continue;
            int k = i / j;
            if (j > 1) divs[i].push_back(j);
            if (k != j && k > 1) divs[i].push_back(k);
        }
        sort(all(divs[i]));
    }
}

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

int ans;

map<int, int> dfs(int u, int p) {
    map<int, int> me;
    map<int, int> bla;
    for (auto d : divs[a[u]]) me[d] = 1, bla[d] = 1;
    for (auto v : adj[u]) {
        if (v == p) continue;
        map<int, int> tmp = dfs(v, u);
        int g = gcd(a[u], a[v]);
        if (g == 1) continue;
        for (auto it : tmp) {
            // cout << u << " " << it.F << endl;
            g = gcd(it.F, a[u]);
            if (g == 1) continue;
            ans = max(ans, me[g] + tmp[it.F]);
            bla[g] = max(me[g], tmp[it.F] + 1);
        }
    }
    for (auto it : bla) {
        ans = max(ans, it.S);
        //cout << "pp  " << u << " " << it.F <<" " << it.S << endl;
        // me[a[u]] = max(me[a[u]], it.S);
    }
    return me;
}

int main() {
    init();
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    for (int i = 1; i < n; ++i) {
        int u, v;
        scanf("%d%d", &u, &v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    dfs(1, 0);
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
using namespace __gnu_cxx;

typedef double db;
typedef long long ll;
typedef pair<db, db> pdd;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef unsigned long long ull;

#define F          first
#define S          second
#define pnl        printf("\n")
#define sz(x)      (int)x.size()
#define sf(x)      scanf("%d",&x)
#define pf(x)      printf("%d\n",x)
#define all(x)     x.begin(),x.end()
#define rall(x)    x.rbegin(),x.rend()
#define rep(i, n)  for(int i = 0; i < n; ++i)

const db eps = 1e-9;
const db pi = acos(-1);
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1000 * 1000 * 1000 + 7;

int n, a[200005];
vector<int> adj[200200];
vector<int> divs[200055];

void init() {
    for (int i = 1; i < 200005; ++i) {
        for (int j = 1; j * j <= i; ++j) {
            if (i / j * j != i) continue;
            int k = i / j;
            if (j > 1) divs[i].push_back(j);
            if (k != j && k > 1) divs[i].push_back(k);
        }
        sort(all(divs[i]));
    }
}

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

int ans;

map<int, int> dfs(int u, int p) {
    map<int, int> me;
    for (auto d : divs[a[u]]) me[d] = 1;
    for (auto v : adj[u]) {
        if (v == p) continue;
        map<int, int> tmp = dfs(v, u);
        int g = gcd(a[u], a[v]);
        if (g == 1) continue;
        for (auto it : me) {
            if (gcd(it.F, a[v]) == 1) continue;
            ans = max(ans, me[it.F] + tmp[a[v]]);
            me[it.F] = max(me[it.F], tmp[a[v]] + 1);
        }
    }
    for (auto it : me) {
        ans = max(ans, it.S);
        me[a[u]] = max(me[a[u]], it.S);
    }
    return me;
}

int main() {
    init();
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    for (int i = 1; i < n; ++i) {
        int u, v;
        scanf("%d%d", &u, &v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    dfs(1, 0);
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
using namespace __gnu_cxx;

typedef double db;
typedef long long ll;
typedef pair<db, db> pdd;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef unsigned long long ull;

#define F          first
#define S          second
#define pnl        printf("\n")
#define sz(x)      (int)x.size()
#define sf(x)      scanf("%d",&x)
#define pf(x)      printf("%d\n",x)
#define all(x)     x.begin(),x.end()
#define rall(x)    x.rbegin(),x.rend()
#define rep(i, n)  for(int i = 0; i < n; ++i)

const db eps = 1e-9;
const db pi = acos(-1);
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1000 * 1000 * 1000 + 7;

int n, a[200005];
vector<int> adj[200200];
vector<int> divs[200055];

void init() {
    for (int i = 1; i < 200005; ++i) {
        for (int j = 1; j * j <= i; ++j) {
            if (i / j * j != i) continue;
            int k = i / j;
            if (j > 1) divs[i].push_back(j);
            if (k != j && k > 1) divs[i].push_back(k);
        }
        sort(all(divs[i]));
    }
}

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

int ans;

map<int, int> dfs(int u, int p) {
    map<int, int> me;
    for (auto d : divs[a[u]]) me[d] = 1;
    for (auto v : adj[u]) {
        if (v == p) continue;
        map<int, int> tmp = dfs(v, u);
        for (auto it : me) {
            int g = gcd(it.F, a[v]);
            if (g == 1) continue;
            ans = max(ans, me[g] + tmp[g]);
            me[g] = max(me[g], tmp[g] + 1);
        }
    }
    for (auto it : me)
        ans = max(ans, it.S);
    return me;
}

int main() {
    init();
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    for (int i = 1; i < n; ++i) {
        int u, v;
        scanf("%d%d", &u, &v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    dfs(1, 0);
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
using namespace __gnu_cxx;

typedef double db;
typedef long long ll;
typedef pair<db, db> pdd;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef unsigned long long ull;

#define F          first
#define S          second
#define pnl        printf("\n")
#define sz(x)      (int)x.size()
#define sf(x)      scanf("%d",&x)
#define pf(x)      printf("%d\n",x)
#define all(x)     x.begin(),x.end()
#define rall(x)    x.rbegin(),x.rend()
#define rep(i, n)  for(int i = 0; i < n; ++i)

const db eps = 1e-9;
const db pi = acos(-1);
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1000 * 1000 * 1000 + 7;

int n, a[200005];
vector<int> adj[200200];
vector<int> divs[200055];

void init() {
    for (int i = 1; i < 200005; ++i) {
        for (int j = 1; j * j <= i; ++j) {
            if (i / j * j != i) continue;
            int k = i / j;
            if (j > 1) divs[i].push_back(j);
            if (k != j && k > 1) divs[i].push_back(k);
        }
        sort(all(divs[i]));
    }
}

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

int ans;

map<int, int> dfs(int u, int p) {
    map<int, int> me;
    for (auto d : divs[a[u]]) me[d] = 1;
    for (auto v : adj[u]) {
        if (v == p) continue;
        map<int, int> tmp = dfs(v, u);
        for (auto it : me) {
            int g = gcd(it.F, a[v]);
            if (g == 1) continue;
            for (int j = g; j <= a[v]; j += g) {
                ans = max(ans, me[g] + tmp[j]);
                me[g] = max(me[g], tmp[j] + 1);
            }
        }
    }
    for (auto it : me)
        ans = max(ans, it.S);
    return me;
}

int main() {
    init();
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    for (int i = 1; i < n; ++i) {
        int u, v;
        scanf("%d%d", &u, &v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    dfs(1, 0);
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
using namespace __gnu_cxx;

typedef double db;
typedef long long ll;
typedef pair<db, db> pdd;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef unsigned long long ull;

#define F          first
#define S          second
#define pnl        printf("\n")
#define sz(x)      (int)x.size()
#define sf(x)      scanf("%d",&x)
#define pf(x)      printf("%d\n",x)
#define all(x)     x.begin(),x.end()
#define rall(x)    x.rbegin(),x.rend()
#define rep(i, n)  for(int i = 0; i < n; ++i)

const db eps = 1e-9;
const db pi = acos(-1);
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1000 * 1000 * 1000 + 7;

int n, a[200005];
vector<int> adj[200200];
vector<int> divs[200055];

void init() {
    for (int i = 1; i < 200005; ++i) {
        for (int j = 1; j * j <= i; ++j) {
            if (i / j * j != i) continue;
            int k = i / j;
            if (j > 1) divs[i].push_back(j);
            if (k != j && k > 1) divs[i].push_back(k);
        }
        sort(all(divs[i]));
    }
}

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

int ans;

map<int, int> dfs(int u, int p) {
    map<int, int> me;
    for (auto d : divs[a[u]]) me[d] = 1;
    for (auto v : adj[u]) {
        if (v == p) continue;
        map<int, int> tmp = dfs(v, u);
        int g = gcd(a[u], a[v]);
        if (g == 1) continue;
        for (auto it : me) {
            ans = max(ans, me[it.F] + tmp[a[v]]);
            me[it.F] = max(me[it.F], tmp[a[v]] + 1);
        }
    }
    for (auto it : me)
        ans = max(ans, it.S);
    return me;
}

int main() {
    init();
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    for (int i = 1; i < n; ++i) {
        int u, v;
        scanf("%d%d", &u, &v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    dfs(1, 0);
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
using namespace __gnu_cxx;

typedef double db;
typedef long long ll;
typedef pair<db, db> pdd;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef unsigned long long ull;

#define F          first
#define S          second
#define pnl        printf("\n")
#define sz(x)      (int)x.size()
#define sf(x)      scanf("%d",&x)
#define pf(x)      printf("%d\n",x)
#define all(x)     x.begin(),x.end()
#define rall(x)    x.rbegin(),x.rend()
#define rep(i, n)  for(int i = 0; i < n; ++i)

const db eps = 1e-9;
const db pi = acos(-1);
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1000 * 1000 * 1000 + 7;

int n, a[200005];
vector<int> adj[200200];
vector<int> divs[200055];

void init() {
    for (int i = 1; i < 200005; ++i) {
        for (int j = 1; j * j <= i; ++j) {
            if (i / j * j != i) continue;
            int k = i / j;
            if (j > 1) divs[i].push_back(j);
            if (k != j && k > 1) divs[i].push_back(k);
        }
        sort(all(divs[i]));
    }
}

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

int ans;

map<int, int> dfs(int u, int p) {
    map<int, int> me;
    for (auto d : divs[a[u]]) me[d] = 1;
    for (auto v : adj[u]) {
        if (v == p) continue;
        map<int, int> tmp = dfs(v, u);
        int g = gcd(a[u], a[v]);
        if (g == 1) continue;
        for (auto it : me) {
            if (gcd(it.S, a[v]) == 1) continue;
            ans = max(ans, me[it.F] + tmp[a[v]]);
            me[it.F] = max(me[it.F], tmp[a[v]] + 1);
        }
    }
    for (auto it : me) {
        ans = max(ans, it.S);
        me[a[u]] = max(me[a[u]], it.S);
    }
    return me;
}

int main() {
    init();
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    for (int i = 1; i < n; ++i) {
        int u, v;
        scanf("%d%d", &u, &v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    dfs(1, 0);
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
using namespace __gnu_cxx;

typedef double db;
typedef long long ll;
typedef pair<db, db> pdd;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef unsigned long long ull;

#define F          first
#define S          second
#define pnl        printf("\n")
#define sz(x)      (int)x.size()
#define sf(x)      scanf("%d",&x)
#define pf(x)      printf("%d\n",x)
#define all(x)     x.begin(),x.end()
#define rall(x)    x.rbegin(),x.rend()
#define rep(i, n)  for(int i = 0; i < n; ++i)

const db eps = 1e-9;
const db pi = acos(-1);
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1000 * 1000 * 1000 + 7;

int n, a[200005];
vector<int> adj[200200];
vector<int> divs[200055];

void init() {
    for (int i = 1; i < 200005; ++i) {
        for (int j = 1; j * j <= i; ++j) {
            if (i / j * j != i) continue;
            int k = i / j;
            if (j > 1) divs[i].push_back(j);
            if (k != j && k > 1) divs[i].push_back(k);
        }
        sort(all(divs[i]));
    }
}

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

int ans;

map<int, int> dfs(int u, int p) {
    map<int, int> me;
    for (auto d : divs[a[u]]) me[d] = 1;
    for (auto v : adj[u]) {
        if (v == p) continue;
        map<int, int> tmp = dfs(v, u);
        int g = gcd(a[u], a[v]);
        if (g == 1) continue;
        for (auto it : me) {
            g = gcd(it.F, a[v]);
            if (g == 1) continue;
            ans = max(ans, me[g] + tmp[a[v]]);
            me[g] = max(me[g], tmp[a[v]] + 1);
        }
    }
    for (auto it : me) {
        ans = max(ans, it.S);
        // me[a[u]] = max(me[a[u]], it.S);
    }
    return me;
}

int main() {
    init();
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    for (int i = 1; i < n; ++i) {
        int u, v;
        scanf("%d%d", &u, &v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    dfs(1, 0);
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
using namespace __gnu_cxx;

typedef double db;
typedef long long ll;
typedef pair<db, db> pdd;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef unsigned long long ull;

#define F          first
#define S          second
#define pnl        printf("\n")
#define sz(x)      (int)x.size()
#define sf(x)      scanf("%d",&x)
#define pf(x)      printf("%d\n",x)
#define all(x)     x.begin(),x.end()
#define rall(x)    x.rbegin(),x.rend()
#define rep(i, n)  for(int i = 0; i < n; ++i)

const db eps = 1e-9;
const db pi = acos(-1);
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1000 * 1000 * 1000 + 7;

int n, a[200005];
vector<int> adj[200200];
vector<int> divs[200055];

void init() {
    for (int i = 1; i < 200005; ++i) {
        for (int j = 1; j * j <= i; ++j) {
            if (i / j * j != i) continue;
            int k = i / j;
            if (j > 1) divs[i].push_back(j);
            if (k != j && k > 1) divs[i].push_back(k);
        }
        sort(all(divs[i]));
    }
}

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

int ans;

map<int, int> dfs(int u, int p) {
    map<int, int> me;
    for (auto d : divs[a[u]]) me[d] = 1;
    for (auto v : adj[u]) {
        if (v == p) continue;
        map<int, int> tmp = dfs(v, u);
        int g = gcd(a[u], a[v]);
        if (g == 1) continue;
        for (auto it : me) {
            ans = max(ans, me[it.F] + tmp[a[v]]);
            me[it.F] = max(me[it.F], tmp[a[v]] + 1);
        }
    }
    for (auto it : me) {
        ans = max(ans, it.S);
        me[a[u]] = max(me[a[u]], it.S);
    }
    return me;
}

int main() {
    init();
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    for (int i = 1; i < n; ++i) {
        int u, v;
        scanf("%d%d", &u, &v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    dfs(1, 0);
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
using namespace __gnu_cxx;

typedef double db;
typedef long long ll;
typedef pair<db, db> pdd;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef unsigned long long ull;

#define F          first
#define S          second
#define pnl        printf("\n")
#define sz(x)      (int)x.size()
#define sf(x)      scanf("%d",&x)
#define pf(x)      printf("%d\n",x)
#define all(x)     x.begin(),x.end()
#define rall(x)    x.rbegin(),x.rend()
#define rep(i, n)  for(int i = 0; i < n; ++i)

const db eps = 1e-9;
const db pi = acos(-1);
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1000 * 1000 * 1000 + 7;

int n, a[200005];
vector<int> adj[200200];
vector<int> divs[200055];

void init() {
    for (int i = 1; i < 200005; ++i) {
        for (int j = 1; j * j <= i; ++j) {
            if (i / j * j != i) continue;
            int k = i / j;
            if (j > 1) divs[i].push_back(j);
            if (k != j && k > 1) divs[i].push_back(k);
        }
        sort(all(divs[i]));
    }
}

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

int ans;

map<int, int> dfs(int u, int p) {
    map<int, int> me;
    map<int, int> bla;
    for (auto d : divs[a[u]]) me[d] = 1, bla[d] = 1;
    for (auto v : adj[u]) {
        if (v == p) continue;
        map<int, int> tmp = dfs(v, u);
        int g = gcd(a[u], a[v]);
        if (g == 1) continue;
        for (auto it : tmp) {
            // cout << u << " " << it.F << endl;
            g = gcd(it.F, a[u]);
            if (g == 1) continue;
            ans = max(ans, me[g] + tmp[it.F]);
            bla[g] = max(me[g], tmp[it.F] + 1);
        }
    }
    for (auto it : bla) {
        ans = max(ans, it.S);
        //cout << "pp  " << u << " " << it.F <<" " << it.S << endl;
        // me[a[u]] = max(me[a[u]], it.S);
    }
    return bla;
}

int main() {
    init();
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    for (int i = 1; i < n; ++i) {
        int u, v;
        scanf("%d%d", &u, &v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    dfs(1, 0);
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
using namespace __gnu_cxx;

typedef double db;
typedef long long ll;
typedef pair<db, db> pdd;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef unsigned long long ull;

#define F          first
#define S          second
#define pnl        printf("\n")
#define sz(x)      (int)x.size()
#define sf(x)      scanf("%d",&x)
#define pf(x)      printf("%d\n",x)
#define all(x)     x.begin(),x.end()
#define rall(x)    x.rbegin(),x.rend()
#define rep(i, n)  for(int i = 0; i < n; ++i)

const db eps = 1e-9;
const db pi = acos(-1);
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1000 * 1000 * 1000 + 7;

int n, a[200005];
vector<int> adj[200200];
vector<int> divs[200055];

void init() {
    for (int i = 1; i < 200005; ++i) {
        for (int j = 1; j * j <= i; ++j) {
            if (i / j * j != i) continue;
            int k = i / j;
            if (j > 1) divs[i].push_back(j);
            if (k != j && k > 1) divs[i].push_back(k);
        }
        sort(all(divs[i]));
    }
}

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

int ans;

map<int, int> dfs(int u, int p) {
    map<int, int> me;
    if (a[u] > 1) me[a[u]] = 1;
    for (auto v : adj[u]) {
        if (v == p) continue;
        map<int, int> tmp = dfs(v, u);
        for (auto it : me) {
            int g = gcd(it.F, a[v]);
            if (g == 1) continue;
            ans = max(ans, me[g] + tmp[g]);
            me[g] = max(me[g], tmp[g] + 1);
        }
    }
    for (int i = 0; i < sz(divs[a[u]]); ++i) {
        int d = divs[a[u]][i];
        for (int j = d + d; j <= a[u]; j += d)
            if (me.count(j) != 0)
                me[d] = max(me[d], me[j]);
    }
    for (auto it : me)
        ans = max(ans, it.S);
    return me;
}

int main() {
    init();
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    for (int i = 1; i < n; ++i) {
        int u, v;
        scanf("%d%d", &u, &v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    dfs(1, 0);
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
using namespace __gnu_cxx;

typedef double db;
typedef long long ll;
typedef pair<db, db> pdd;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef unsigned long long ull;

#define F          first
#define S          second
#define pnl        printf("\n")
#define sz(x)      (int)x.size()
#define sf(x)      scanf("%d",&x)
#define pf(x)      printf("%d\n",x)
#define all(x)     x.begin(),x.end()
#define rall(x)    x.rbegin(),x.rend()
#define rep(i, n)  for(int i = 0; i < n; ++i)

const db eps = 1e-9;
const db pi = acos(-1);
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1000 * 1000 * 1000 + 7;

int n, a[200005];
vector<int> adj[200200];

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

map<pii, int> dp[200200];

int solve(int u, int d, int p) {
    if (d == 1) return -INF;
    if (dp[u].count({p, d}) != 0) return dp[u][{p, d}];
    int &ret = dp[u][{p, d}];
    ret = 0;
    for (auto v : adj[u])
        if (v != p) ret = max(ret, solve(v, gcd(d, a[v]), u) + 1);
    return ret;
}

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    for (int i = 1; i < n; ++i) {
        int u, v;
        scanf("%d%d", &u, &v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    int ans = 0;
    for (int i = 1; i <= n; ++i) {
        ans = max(ans, solve(i, a[i], 0) + 1);
    }
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
using namespace __gnu_cxx;

typedef double db;
typedef long long ll;
typedef pair<db, db> pdd;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef unsigned long long ull;

#define F          first
#define S          second
#define pnl        printf("\n")
#define sz(x)      (int)x.size()
#define sf(x)      scanf("%d",&x)
#define pf(x)      printf("%d\n",x)
#define all(x)     x.begin(),x.end()
#define rall(x)    x.rbegin(),x.rend()
#define rep(i, n)  for(int i = 0; i < n; ++i)

const db eps = 1e-9;
const db pi = acos(-1);
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1000 * 1000 * 1000 + 7;

int n, a[200005];
vector<int> adj[200200];

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

map<pii, int> dp[200200];
map<pii, int> vis[200200];

int solve(int u, int d, int p) {
    if (d == 1) return -INF;
    if (vis[d][{p, u}]) return dp[d][{p, u}];
    vis[d][{p, u}] = 1;
    int &ret = dp[d][{p, u}];
    ret = 0;
    for (auto v : adj[u])
        if (v != p) ret = max(ret, solve(v, gcd(d, a[v]), u) + 1);
    return ret;
}

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    for (int i = 1; i < n; ++i) {
        int u, v;
        scanf("%d%d", &u, &v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    int ans = 0;
    for (int i = 1; i <= n; ++i) {
        ans = max(ans, solve(i, a[i], 0) + 1);
    }
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
using namespace __gnu_cxx;

typedef double db;
typedef long long ll;
typedef pair<db, db> pdd;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef unsigned long long ull;

#define F          first
#define S          second
#define pnl        printf("\n")
#define sz(x)      (int)x.size()
#define sf(x)      scanf("%d",&x)
#define pf(x)      printf("%d\n",x)
#define all(x)     x.begin(),x.end()
#define rall(x)    x.rbegin(),x.rend()
#define rep(i, n)  for(int i = 0; i < n; ++i)

const db eps = 1e-9;
const db pi = acos(-1);
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1000 * 1000 * 1000 + 7;

int n, a[200005];
vector<int> adj[200200];

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

map<pii, int> dp[200200];

int solve(int u, int d, int p) {
    if (d == 1) return 0;
    if (dp[d].count({p, u}) != 0) return dp[d][{p, u}];
    int &ret = dp[d][{p, u}];
    ret = -INF;
    for (auto v : adj[u])
        if (v != p) ret = max(ret, solve(v, gcd(d, a[v]), u) + 1);
    return ret;
}

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    for (int i = 1; i < n; ++i) {
        int u, v;
        scanf("%d%d", &u, &v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    int ans = 0;
    for (int i = 1; i <= n; ++i) {
        ans = max(ans, solve(i, a[i], 0));
    }
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
using namespace __gnu_cxx;

typedef double db;
typedef long long ll;
typedef pair<db, db> pdd;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef unsigned long long ull;

#define F          first
#define S          second
#define pnl        printf("\n")
#define sz(x)      (int)x.size()
#define sf(x)      scanf("%d",&x)
#define pf(x)      printf("%d\n",x)
#define all(x)     x.begin(),x.end()
#define rall(x)    x.rbegin(),x.rend()
#define rep(i, n)  for(int i = 0; i < n; ++i)

const db eps = 1e-9;
const db pi = acos(-1);
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1000 * 1000 * 1000 + 7;

int n, a[200005];
vector<int> adj[200200];
vector<int> divs[200055];

void init() {
    for (int i = 1; i < 200005; ++i) {
        for (int j = 1; j * j <= i; ++j) {
            if (i / j * j != i) continue;
            int k = i / j;
            if (j > 1) divs[i].push_back(j);
            if (k != j && k > 1) divs[i].push_back(k);
        }
        sort(all(divs[i]));
    }
}

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

int ans;

map<int, int> dfs(int u, int p) {
    map<int, int> me;
    map<int, int> bla;
    for (auto d : divs[a[u]]) me[d] = 1, bla[d] = 1;
    for (auto v : adj[u]) {
        if (v == p) continue;
        map<int, int> tmp = dfs(v, u);
        int g = gcd(a[u], a[v]);
        if (g == 1) continue;
        for (auto it : tmp) {
            // cout << u << " " << it.F << endl;
            g = gcd(it.F, a[u]);
            if (g == 1) continue;
            ans = max(ans, bla[g] + tmp[it.F]);
            bla[g] = max(me[g], tmp[it.F] + 1);
        }
    }
    for (auto it : bla) {
        ans = max(ans, it.S);
        //cout << "pp  " << u << " " << it.F <<" " << it.S << endl;
        // me[a[u]] = max(me[a[u]], it.S);
    }
    return bla;
}

int main() {
    init();
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    for (int i = 1; i < n; ++i) {
        int u, v;
        scanf("%d%d", &u, &v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    dfs(1, 0);
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
using namespace __gnu_cxx;

typedef double db;
typedef long long ll;
typedef pair<db, db> pdd;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef unsigned long long ull;

#define F          first
#define S          second
#define pnl        printf("\n")
#define sz(x)      (int)x.size()
#define sf(x)      scanf("%d",&x)
#define pf(x)      printf("%d\n",x)
#define all(x)     x.begin(),x.end()
#define rall(x)    x.rbegin(),x.rend()
#define rep(i, n)  for(int i = 0; i < n; ++i)

const db eps = 1e-9;
const db pi = acos(-1);
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1000 * 1000 * 1000 + 7;

int n, a[200005];
vector<int> adj[200200];

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

map<pii, int> dp[200200];

int solve(int u, int d, int p) {
    if (d == 1) return -INF;
    if (dp[d].count({p, u}) != 0) return dp[d][{p, u}];
    int &ret = dp[d][{p, u}];
    ret = 0;
    for (auto v : adj[u])
        if (v != p) ret = max(ret, solve(v, gcd(d, a[v]), u) + 1);
    return ret;
}

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    for (int i = 1; i < n; ++i) {
        int u, v;
        scanf("%d%d", &u, &v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    int ans = 0;
    for (int i = 1; i <= n; ++i) {
        ans = max(ans, solve(i, a[i], 0) + 1);
    }
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
using namespace __gnu_cxx;

typedef double db;
typedef long long ll;
typedef pair<db, db> pdd;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef unsigned long long ull;

#define F          first
#define S          second
#define pnl        printf("\n")
#define sz(x)      (int)x.size()
#define sf(x)      scanf("%d",&x)
#define pf(x)      printf("%d\n",x)
#define all(x)     x.begin(),x.end()
#define rall(x)    x.rbegin(),x.rend()
#define rep(i, n)  for(int i = 0; i < n; ++i)

const db eps = 1e-9;
const db pi = acos(-1);
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1000 * 1000 * 1000 + 7;

int n, a[200005];
vector<int> adj[200200];
vector<int> divs[200055];

void init() {
    for (int i = 1; i < 200005; ++i) {
        for (int j = 1; j * j <= i; ++j) {
            if (i / j * j != i) continue;
            int k = i / j;
            if (j > 1) divs[i].push_back(j);
            if (k != j && k > 1) divs[i].push_back(k);
        }
        sort(all(divs[i]));
    }
}

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

int ans;

map<int, int> dfs(int u, int p) {
    map<int, int> me;
    if (a[u] > 1) me[a[u]] = 1;
    for (auto v : adj[u]) {
        if (v == p) continue;
        map<int, int> tmp = dfs(v, u);
        for (auto it : me) {
            int g = gcd(it.F, a[v]);
            if (g == 1) continue;
            ans = max(ans, me[g] + tmp[g]);
            me[g] = max(me[g], tmp[g] + 1);
        }
    }
    for (int i = 0; i < sz(divs[a[u]]); ++i) {
        me[divs[a[u]][i]] = max(me[divs[a[u]][i]], me[a[u]]);
    }
    for (auto it : me)
        ans = max(ans, it.S);
    return me;
}

int main() {
    init();
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    for (int i = 1; i < n; ++i) {
        int u, v;
        scanf("%d%d", &u, &v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    dfs(1, 0);
    cout << ans << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;

const int N = 2e5 + 8 , P = 10;
int n , a[N] , mxt , dis[N] , ind , mx , t , aa , b , par[N];
bool mark[N] , mrk[N] , maark[N];
vector <int> p , x[N] , nei[N];

void dfs(int v , int p = -1)
{
	mark[v] = 1;
	if(dis[ind] < dis[v])
		ind = v;
	for(auto u : nei[v])
	{
		if(u != p && !mark[u])
		{
			dis[u] = dis[v] + 1;
			dfs(u , v);
		}
	}
}

int dfs_all(int q)
{
	for(auto yy : x[q])
		nei[yy].clear();
	mxt = -1;
	memset(mark , 0 , sizeof mark);
	memset(maark , 0 , sizeof maark);
	for(auto yy : x[q])
		maark[yy] = 1;
	for(auto yy : x[q])
	{
		if(par[yy] != -1 && maark[par[yy]] && par[yy] != yy)
		{
			nei[yy].push_back(par[yy]);
			nei[par[yy]].push_back(yy);
		}
	}
	for(auto yy : x[q])

		if(!mark[yy])
		{
			ind = N - 1;
			memset(dis , 0 , sizeof dis);
			dis[yy] = 1;
			dfs(yy);
			memset(dis , 0 , sizeof dis);
			dis[ind] = 1;
			dfs(ind);
			mxt = max(mxt , dis[ind]);
		}
	return mxt;
}

void dfsp(int v , int pr = -1)
{
	for(int u : nei[v])
		if(u != pr)
		{
			par[u] = v;
			dfsp(u , v);
		}
}

int main()
{
	ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);
	cin >> n;
	for(int i = 2 ; i < N ; i++)
		if(!mrk[i])
		{
			p.push_back(i);
			for(int j = i + i ; j < N ; j += i)
				mrk[j] = 1;
		}
//	cout << p.size() << endl;
	for(int i = 0 ; i < n ; i++)
	{
		cin >> a[i];
		for(int j = 2 ; j * j <= a[i] ; j++)
			if(a[i] % j == 0)
			{
				if(a[i] / j != j)
					x[a[i]/j].push_back(i);
				x[j].push_back(i);
			}
		if(!mrk[a[i]])
			x[a[i]].push_back(i);
	}
	for(int i = 0 ; i < n - 1 ; i++)
	{
		cin >> aa >> b;
		aa-- , b--;
		nei[aa].push_back(b);
		nei[b].push_back(aa);
	}
	dfsp(0);
	for(int i = 0 ; i < p.size() ; i++)
	{
		if(!x[p[i]].size())
			continue;
		t = dfs_all(p[i]);
		mx = max(mx , t);
	}
	cout << mx;
}


#include<bits/stdc++.h>

using namespace std;

const int N = 2e5 + 8 , P = 10;
int n , a[N] , mxt , dis[N] , ind , mx , t , aa , b , par[N] , r , mrk[N];
bool mark[N] , maark[N];
vector <int> p , x[N] , nei[N];

void dfs(int v , int p , int e)
{
	mark[v] = !e;
	if(dis[ind] < dis[v])
		ind = v;
	for(auto u : nei[v])
	{
		if(u != p && mark[u] == e)
		{
			dis[u] = dis[v] + 1;
			dfs(u , v , e);
		}
	}
}

int dfs_all(int q)
{
	for(auto yy : x[q])
		nei[yy].clear();
	mxt = 1;
	for(auto yy : x[q])
		maark[yy] = 1;
	for(auto yy : x[q])
	{
		if(par[yy] != -1 && maark[par[yy]] && par[yy] != yy)
		{
			nei[yy].push_back(par[yy]);
			nei[par[yy]].push_back(yy);
		}
	}
	for(auto yy : x[q])

		if(!mark[yy])
		{
			ind = N - 1;
			dis[yy] = 1;
			dfs(yy , -1 , 0);
		//	for(auto xx : x[q])
		//		mark[xx] = false , dis[xx] = 0;
			dis[ind] = 1;
			dfs(ind , -1 , 1);
			mxt = max(mxt , dis[ind]);
		}
	for (auto yy : x[q])
		mark[yy] = false , maark[yy] = 0 , dis[yy] = 0;
	return mxt;
}

void dfsp(int v , int pr = -1)
{
	for(int u : nei[v])
		if(u != pr)
		{
			par[u] = v;
			dfsp(u , v);
		}
}

int main()
{
	ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);
	cin >> n;
	memset(mrk , -1 , sizeof mrk);
	for(int i = 2 ; i < N ; i++)
		if(mrk[i] == -1)
		{
			p.push_back(i);
			for(int j = i + i ; j < N ; j += i)
				mrk[j] = i;
		}
	for(int i = 0 ; i < n ; i++)
	{
		cin >> a[i];
		while(a[i] > 1)
		{
			r = mrk[a[i]];
			if ( r == -1 )
				r = a[i] ;
			x[r].push_back(i);
			while(a[i] % r == 0 && a[i] > 1)
				a[i] /= r;
		}
	}
	for(int i = 0 ; i < n - 1 ; i++)
	{
		cin >> aa >> b;
		aa-- , b--;
		nei[aa].push_back(b);
		nei[b].push_back(aa);
	}
	dfsp(0);
	for(int i = 0 ; i < p.size() ; i++)
	{
		if(!x[p[i]].size())
			continue;
		t = dfs_all(p[i]);
		mx = max(mx , t);
	}
	cout << mx;
}


#include<bits/stdc++.h>

using namespace std;

const int N = 2e5 + 8 , P = 10;
int n , a[N] , mxt , dis[N] , ind , mx , t , aa , b , par[N];
bool mark[N] , mrk[N] , maark[N];
vector <int> p , x[N] , nei[N];

void dfs(int v , int p = -1)
{
	mark[v] = 1;
	if(dis[ind] < dis[v])
		ind = v;
	for(auto u : nei[v])
	{
		if(u != p)
		{
			dis[u] = dis[v] + 1;
			dfs(u , v);
		}
	}
}

int dfs_all(int q)
{
	for(auto yy : x[q])
		nei[yy].clear();
	mxt = -1;
	memset(mark , 0 , sizeof mark);
	memset(maark , 0 , sizeof maark);
	for(auto yy : x[q])
		maark[yy] = 1;
	for(auto yy : x[q])
	{
		if(par[yy] != -1 && maark[par[yy]] && par[yy] != yy)
		{
			nei[yy].push_back(par[yy]);
			nei[par[yy]].push_back(yy);
		}
	}
	for(auto yy : x[q])

		if(!mark[yy])
		{
			ind = N - 1;
			memset(dis , 0 , sizeof dis);
			dis[yy] = 1;
			dfs(yy);
			memset(dis , 0 , sizeof dis);
			dis[ind] = 1;
			dfs(ind);
			mxt = max(mxt , dis[ind]);
		}
	return mxt;
}

void dfsp(int v , int pr = -1)
{
	for(int u : nei[v])
		if(u != pr)
		{
			par[u] = v;
			dfsp(u , v);
		}
}

int main()
{
	ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);
	cin >> n;
	for(int i = 2 ; i < N ; i++)
		if(!mrk[i])
		{
			p.push_back(i);
			for(int j = i + i ; j < N ; j += i)
				mrk[j] = 1;
		}
	for(int i = 0 ; i < n ; i++)
	{
		cin >> a[i];
		for(int j = 0 ; j < p.size() ; j++)
		{
			if(p[j] > a[i])
				break;
			if(a[i] % p[j] == 0)
				x[p[j]].push_back(i);
		}
	}
	for(int i = 0 ; i < n - 1 ; i++)
	{
		cin >> aa >> b;
		aa-- , b--;
		nei[aa].push_back(b);
		nei[b].push_back(aa);
	}
	dfsp(0);
	for(int i = 0 ; i < p.size() ; i++)
	{
		if(!x[p[i]].size())
			continue;
		t = dfs_all(p[i]);
		mx = max(mx , t);
	}
	cout << mx;
}


#include<bits/stdc++.h>

using namespace std;

const int N = 2e5 + 8 , P = 10;
int n , a[N] , mxt , dis[N] , ind , mx , t , aa , b , par[N] , r , mrk[N] , mark[N];
bool maark[N];
vector <int> p , x[N] , nei[N];

void dfs(int v , int p , int e)
{
	mark[v] = e;
	if(dis[ind] < dis[v])
		ind = v;
	for(auto u : nei[v])
	{
		if(u != p && mark[u] != e)
		{
			dis[u] = dis[v] + 1;
			dfs(u , v , e);
		}
	}
}

int dfs_all(int q)
{
	for(auto yy : x[q])
		nei[yy].clear();
	mxt = 1;
	for(auto yy : x[q])
		maark[yy] = 1;
	for(auto yy : x[q])
	{
		if(par[yy] != -1 && maark[par[yy]] && par[yy] != yy)
		{
			nei[yy].push_back(par[yy]);
			nei[par[yy]].push_back(yy);
		}
	}
	for(auto yy : x[q])

		if(!mark[yy])
		{
			ind = N - 1;
			dis[yy] = 1;
			dfs(yy , -1 , 1);
		//	for(auto xx : x[q])
		//		mark[xx] = false , dis[xx] = 0;
			dis[ind] = 1;
			dfs(ind , -1 , 2);
			mxt = max(mxt , dis[ind]);
		}
	for (auto yy : x[q])
		mark[yy] = false , maark[yy] = 0 , dis[yy] = 0;
	return mxt;
}

void dfsp(int v , int pr = -1)
{
	for(int u : nei[v])
		if(u != pr)
		{
			par[u] = v;
			dfsp(u , v);
		}
}

int main()
{
	ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);
	cin >> n;
	memset(mrk , -1 , sizeof mrk);
	for(int i = 2 ; i < N ; i++)
		if(mrk[i] == -1)
		{
			p.push_back(i);
			for(int j = i + i ; j < N ; j += i)
				mrk[j] = i;
		}
	for(int i = 0 ; i < n ; i++)
	{
		cin >> a[i];
		while(a[i] > 1)
		{
			r = mrk[a[i]];
			if ( r == -1 )
				r = a[i] ;
			x[r].push_back(i);
			while(a[i] % r == 0 && a[i] > 1)
				a[i] /= r;
		}
	}
	for(int i = 0 ; i < n - 1 ; i++)
	{
		cin >> aa >> b;
		aa-- , b--;
		nei[aa].push_back(b);
		nei[b].push_back(aa);
	}
	dfsp(0);
	for(int i = 0 ; i < p.size() ; i++)
	{
		if(!x[p[i]].size())
			continue;
		t = dfs_all(p[i]);
		mx = max(mx , t);
	}
	cout << mx;
}


#include<bits/stdc++.h>

using namespace std;

const int N = 2e5 + 8 , P = 10;
int n , a[N] , mxt , dis[N] , ind , mx , t , aa , b , par[N];
bool mark[N] , mrk[N] , maark[N];
vector <int> p , x[N] , nei[N];

void dfs(int v , int p = -1)
{
	mark[v] = 1;
	if(dis[ind] < dis[v])
		ind = v;
	for(auto u : nei[v])
	{
		if(u != p && !mark[u])
		{
			dis[u] = dis[v] + 1;
			dfs(u , v);
		}
	}
}

int dfs_all(int q)
{
	for(auto yy : x[q])
		nei[yy].clear();
	mxt = 1;
	for(auto yy : x[q])
		maark[yy] = 1;
	for(auto yy : x[q])
	{
		if(par[yy] != -1 && maark[par[yy]] && par[yy] != yy)
		{
			nei[yy].push_back(par[yy]);
			nei[par[yy]].push_back(yy);
		}
	}
	for(auto yy : x[q])

		if(!mark[yy])
		{
			ind = N - 1;
			dis[yy] = 1;
			dfs(yy);
			for(auto xx : x[q])
				mark[xx] =false , dis[xx] = 0;
			dis[ind] = 1;
			dfs(ind);
			mxt = max(mxt , dis[ind]);
		}
	for (auto yy : x[q])
		mark[yy] = false , maark[yy] = 0 , dis[yy] = 0;
	return mxt;
}

void dfsp(int v , int pr = -1)
{
	for(int u : nei[v])
		if(u != pr)
		{
			par[u] = v;
			dfsp(u , v);
		}
}

int main()
{
	ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);
	cin >> n;
	mrk[1] = 1;
	for(int i = 2 ; i < N ; i++)
		if(!mrk[i])
		{
			p.push_back(i);
			for(int j = i + i ; j < N ; j += i)
				mrk[j] = 1;
		}
	for(int i = 0 ; i < n ; i++)
	{
		cin >> a[i];
		for(int j = 2 ; j * j <= a[i] ; j++)
			if(a[i] % j == 0)
			{
				if (!mrk[a[i]/j] && a[i] / j != j)
					x[a[i]/j].push_back(i);
				if ( !mrk[j] )
					x[j].push_back(i);
			}
		if(!mrk[a[i]])
			x[a[i]].push_back(i);
	}
	for(int i = 0 ; i < n - 1 ; i++)
	{
		cin >> aa >> b;
		aa-- , b--;
		nei[aa].push_back(b);
		nei[b].push_back(aa);
	}
	dfsp(0);
	for(int i = 0 ; i < p.size() ; i++)
	{
		if(!x[p[i]].size())
			continue;
		t = dfs_all(p[i]);
		mx = max(mx , t);
	}
	cout << mx;
}


#include<bits/stdc++.h>

using namespace std;

const int N = 2e5 + 8 , P = 10;
int n , a[N] , mxt , dis[N] , ind , mx , t , aa , b , par[N];
bool mark[N] , mrk[N] , maark[N];
vector <int> p , x[N] , nei[N];

void dfs(int v , int p = -1)
{
	mark[v] = 1;
	if(dis[ind] < dis[v])
		ind = v;
	for(auto u : nei[v])
	{
		if(u != p)
		{
			dis[u] = dis[v] + 1;
			dfs(u , v);
		}
	}
}

int dfs_all(int q)
{
	for(auto yy : x[q])
		nei[yy].clear();
	mxt = -1;
	memset(mark , 0 , sizeof mark);
	memset(maark , 0 , sizeof maark);
	for(auto yy : x[q])
		maark[yy] = 1;
	for(auto yy : x[q])
	{
		if(par[yy] != -1 && maark[par[yy]] && par[yy] != yy)
		{
			nei[yy].push_back(par[yy]);
			nei[par[yy]].push_back(yy);
		}
	}
	for(auto yy : x[q])

		if(!mark[yy])
		{
			ind = N - 1;
			memset(dis , 0 , sizeof dis);
			dis[yy] = 1;
			dfs(yy);
			memset(dis , 0 , sizeof dis);
			dis[ind] = 1;
			dfs(ind);
			mxt = max(mxt , dis[ind]);
		}
	return mxt;
}

void dfsp(int v , int pr = -1)
{
	for(int u : nei[v])
		if(u != pr)
		{
			par[u] = v;
			dfsp(u , v);
		}
}

int main()
{
	ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);
	cin >> n;
	for(int i = 2 ; i < N ; i++)
		if(!mrk[i])
		{
			p.push_back(i);
			for(int j = i + i ; j < N ; j += i)
				mrk[j] = 1;
		}
//	cout << p.size() << endl;
	for(int i = 0 ; i < n ; i++)
	{
		cin >> a[i];
		for(int j = 2 ; j * j <= a[i] ; j++)
			if(a[i] % j == 0)
			{
				if(a[i] / j != j)
					x[a[i]/j].push_back(i);
				x[j].push_back(i);
			}
		if(!mrk[a[i]])
			x[a[i]].push_back(i);
	}
	for(int i = 0 ; i < n - 1 ; i++)
	{
		cin >> aa >> b;
		aa-- , b--;
		nei[aa].push_back(b);
		nei[b].push_back(aa);
	}
	dfsp(0);
	for(int i = 0 ; i < p.size() ; i++)
	{
		if(!x[p[i]].size())
			continue;
		t = dfs_all(p[i]);
		mx = max(mx , t);
	}
	cout << mx;
}


#include<bits/stdc++.h>

using namespace std;

const int N = 2e5 + 8 , P = 10;
int n , a[N] , mxt , dis[N] , ind , mx , t , aa , b , par[N];
bool mark[N] , mrk[N] , maark[N];
vector <int> p , x[N] , nei[N];

void dfs(int v , int p = -1)
{
	mark[v] = 1;
	if(dis[ind] < dis[v])
		ind = v;
	for(auto u : nei[v])
	{
		if(u != p && !mark[u])
		{
			dis[u] = dis[v] + 1;
			dfs(u , v);
		}
	}
}

int dfs_all(int q)
{
	for(auto yy : x[q])
		nei[yy].clear();
	mxt = -1;
	memset(mark , 0 , sizeof mark);
	memset(maark , 0 , sizeof maark);
	for(auto yy : x[q])
		maark[yy] = 1;
	for(auto yy : x[q])
	{
		if(par[yy] != -1 && maark[par[yy]] && par[yy] != yy)
		{
			nei[yy].push_back(par[yy]);
			nei[par[yy]].push_back(yy);
		}
	}
	for(auto yy : x[q])

		if(!mark[yy])
		{
			ind = N - 1;
			memset(dis , 0 , sizeof dis);
			dis[yy] = 1;
			dfs(yy);
			memset(mark , 0 , sizeof mark);
			memset(dis , 0 , sizeof dis);
			dis[ind] = 1;
			dfs(ind);
			mxt = max(mxt , dis[ind]);
		}
	return mxt;
}

void dfsp(int v , int pr = -1)
{
	for(int u : nei[v])
		if(u != pr)
		{
			par[u] = v;
			dfsp(u , v);
		}
}

int main()
{
	ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);
	cin >> n;
	for(int i = 2 ; i < N ; i++)
		if(!mrk[i])
		{
			p.push_back(i);
			for(int j = i + i ; j < N ; j += i)
				mrk[j] = 1;
		}
//	cout << p.size() << endl;
	for(int i = 0 ; i < n ; i++)
	{
		cin >> a[i];
		for(int j = 2 ; j * j <= a[i] ; j++)
			if(a[i] % j == 0)
			{
				if(a[i] / j != j)
					x[a[i]/j].push_back(i);
				x[j].push_back(i);
			}
		if(!mrk[a[i]])
			x[a[i]].push_back(i);
	}
	for(int i = 0 ; i < n - 1 ; i++)
	{
		cin >> aa >> b;
		aa-- , b--;
		nei[aa].push_back(b);
		nei[b].push_back(aa);
	}
	dfsp(0);
	for(int i = 0 ; i < p.size() ; i++)
	{
		if(!x[p[i]].size())
			continue;
		t = dfs_all(p[i]);
		mx = max(mx , t);
	}
	cout << mx;
}


#include<bits/stdc++.h>

using namespace std;

const int N = 2e5 + 8 , P = 10;
int n , a[N] , mxt , dis[N] , ind , mx , t , aa , b , par[N] , r , mrk[N];
bool mark[N] , maark[N];
vector <int> p , x[N] , nei[N];

void dfs(int v , int p = -1)
{
	mark[v] = 1;
	if(dis[ind] < dis[v])
		ind = v;
	for(auto u : nei[v])
	{
		if(u != p && !mark[u])
		{
			dis[u] = dis[v] + 1;
			dfs(u , v);
		}
	}
}

int dfs_all(int q)
{
	for(auto yy : x[q])
		nei[yy].clear();
	mxt = 1;
	for(auto yy : x[q])
		maark[yy] = 1;
	for(auto yy : x[q])
	{
		if(par[yy] != -1 && maark[par[yy]] && par[yy] != yy)
		{
			nei[yy].push_back(par[yy]);
			nei[par[yy]].push_back(yy);
		}
	}
	for(auto yy : x[q])

		if(!mark[yy])
		{
			ind = N - 1;
			dis[yy] = 1;
			dfs(yy);
			for(auto xx : x[q])
				mark[xx] =false , dis[xx] = 0;
			dis[ind] = 1;
			dfs(ind);
			mxt = max(mxt , dis[ind]);
		}
	for (auto yy : x[q])
		mark[yy] = false , maark[yy] = 0 , dis[yy] = 0;
	return mxt;
}

void dfsp(int v , int pr = -1)
{
	for(int u : nei[v])
		if(u != pr)
		{
			par[u] = v;
			dfsp(u , v);
		}
}

int main()
{
	ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);
	cin >> n;
	memset(mrk , -1 , sizeof mrk);
	for(int i = 2 ; i < N ; i++)
		if(mrk[i] == -1)
		{
			p.push_back(i);
			for(int j = i + i ; j < N ; j += i)
				mrk[j] = i;
		}
	for(int i = 0 ; i < n ; i++)
	{
		cin >> a[i];
		while(a[i] > 1)
		{
			r = mrk[a[i]];
			if ( r == -1 )
				r = a[i] ;
			x[r].push_back(i);
			while(a[i] % r == 0 && a[i] > 1)
				a[i] /= r;
		}
	}
	for(int i = 0 ; i < n - 1 ; i++)
	{
		cin >> aa >> b;
		aa-- , b--;
		nei[aa].push_back(b);
		nei[b].push_back(aa);
	}
	dfsp(0);
	for(int i = 0 ; i < p.size() ; i++)
	{
		if(!x[p[i]].size())
			continue;
		t = dfs_all(p[i]);
		mx = max(mx , t);
	}
	cout << mx;
}


#include<bits/stdc++.h>

using namespace std;

const int N = 2e5 + 8 , P = 10;
int n , a[N] , mxt , dis[N] , ind , mx , t , aa , b , par[N];
bool mark[N] , mrk[N] , maark[N];
vector <int> p , x[N] , nei[N];

void dfs(int v , int p = -1)
{
	mark[v] = 1;
	if(dis[ind] < dis[v])
		ind = v;
	for(auto u : nei[v])
	{
		if(u != p && !mark[u])
		{
			dis[u] = dis[v] + 1;
			dfs(u , v);
		}
	}
}

int dfs_all(int q)
{
	for(auto yy : x[q])
		nei[yy].clear();
	mxt = 1;
	for(auto yy : x[q])
		maark[yy] = 1;
	for(auto yy : x[q])
	{
		if(par[yy] != -1 && maark[par[yy]] && par[yy] != yy)
		{
			nei[yy].push_back(par[yy]);
			nei[par[yy]].push_back(yy);
		}
	}
	for(auto yy : x[q])

		if(!mark[yy])
		{
			ind = N - 1;
			dis[yy] = 1;
			dfs(yy);
			for(auto xx : x[q])
				mark[xx] =false , dis[xx] = 0;
			dis[ind] = 1;
			dfs(ind);
			mxt = max(mxt , dis[ind]);
		}
	for (auto yy : x[q])
		mark[yy] = false , maark[yy] = 0 , dis[yy] = 0;
	return mxt;
}

void dfsp(int v , int pr = -1)
{
	for(int u : nei[v])
		if(u != pr)
		{
			par[u] = v;
			dfsp(u , v);
		}
}

int main()
{
	ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);
	cin >> n;
	mrk[1] = 1;
	for(int i = 2 ; i < N ; i++)
		if(!mrk[i])
		{
			p.push_back(i);
			for(int j = i + i ; j < N ; j += i)
				mrk[j] = 1;
		}
//	cout << p.size() << endl;
	for(int i = 0 ; i < n ; i++)
	{
		cin >> a[i];
		for(int j = 2 ; j * j <= a[i] ; j++)
			if(a[i] % j == 0)
			{
				if(a[i] / j != j)
					x[a[i]/j].push_back(i);
				x[j].push_back(i);
			}
		if(!mrk[a[i]])
			x[a[i]].push_back(i);
	}
	for(int i = 0 ; i < n - 1 ; i++)
	{
		cin >> aa >> b;
		aa-- , b--;
		nei[aa].push_back(b);
		nei[b].push_back(aa);
	}
	dfsp(0);
	for(int i = 0 ; i < p.size() ; i++)
	{
		if(!x[p[i]].size())
			continue;
		t = dfs_all(p[i]);
		mx = max(mx , t);
	}
	cout << mx;
}


#include<bits/stdc++.h>

using namespace std;

const int N = 2e5 + 8 , P = 10;
int n , a[N] , mxt , dis[N] , ind , mx , t , aa , b;
bool mark[N] , mrk[N];
vector <int> p , x[N] , nei[N];

void dfs(int v , int q , int p = -1)
{
	if(dis[ind] < dis[v])
	{
	//	cout << "H1 " << ind << " " << dis[ind] << endl;
		ind = v;
	//	cout << "H2 " << ind << " " << dis[ind] << endl;
	}
	for(auto  u : nei[v])
		if(u != p && __gcd(a[u] , a[v]) != 1)
		{
			dis[u] = dis[v] + 1;
			dfs(u , q , v);
		}
}

int dfs_all(int q)
{
	mxt = -1;
	for(auto yy : x[q])
		if(!mark[yy])
		{
			ind = N - 1;
			memset(dis , 0 , sizeof dis);
			dis[yy] = 1;
			dfs(yy , q);
			memset(dis , 0 , sizeof dis);
			dis[ind] = 1;
			dfs(ind , q);
	//		cout << "^^^^^ " << dis[ind] << " " << ind << " " << yy << " " << q << endl;
			mxt = max(mxt , dis[ind]);
		}
	return mxt;
}

int main()
{
	ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);
	cin >> n;
	for(int i = 2 ; i < N ; i++)
		if(!mrk[i])
		{
			p.push_back(i);
			for(int j = i + i ; j < N ; j += i)
				mrk[j] = 1;
		}
	for(int i = 0 ; i < n ; i++)
	{
		cin >> a[i];
		for(int j = 0 ; j < p.size() ; j++)
		{
			if(p[j] > a[i])
				break;
			if(a[i] % p[j] == 0)
				x[p[j]].push_back(i);
		}
	}
	for(int i = 0 ; i < n - 1 ; i++)
	{
		cin >> aa >> b;
		aa-- , b--;
		nei[aa].push_back(b);
		nei[b].push_back(aa);
	}
	for(int i = 0 ; i < p.size() ; i++)
	{
		memset(mark , 0 , sizeof mark);
		if(!x[p[i]].size())
			continue;
		t = dfs_all(p[i]);
	//	cout << "&&&& " << i << " " << t << " " << p[i] << endl;
		mx = max(mx , t);
	}
	cout << mx;
}


#include<bits/stdc++.h>

using namespace std;

const int N = 2e5 + 8 , P = 10;
int n , a[N] , mxt , dis[N] , ind , mx , t , aa , b , par[N] , r , mrk[N] , mark[N];
bool maark[N];
vector <int> p , x[N] , nei[N];

void dfs(int v , int p , int e)
{
	mark[v] = e ^ 3;
	if(dis[ind] < dis[v])
		ind = v;
	for(auto u : nei[v])
	{
		if(u != p && mark[u] == e)
		{
			dis[u] = dis[v] + 1;
			dfs(u , v , e);
		}
	}
}

int dfs_all(int q)
{
	for(auto yy : x[q])
		nei[yy].clear();
	mxt = 1;
	for(auto yy : x[q])
		maark[yy] = 1;
	for(auto yy : x[q])
	{
		if(par[yy] != -1 && maark[par[yy]] && par[yy] != yy)
		{
			nei[yy].push_back(par[yy]);
			nei[par[yy]].push_back(yy);
		}
	}
	for(auto yy : x[q])

		if(!mark[yy])
		{
			ind = N - 1;
			dis[yy] = 1;
			dfs(yy , -1 , 1);
		//	for(auto xx : x[q])
		//		mark[xx] = false , dis[xx] = 0;
			dis[ind] = 1;
			dfs(ind , -1 , 2);
			mxt = max(mxt , dis[ind]);
		}
	for (auto yy : x[q])
		mark[yy] = false , maark[yy] = 0 , dis[yy] = 0;
	return mxt;
}

void dfsp(int v , int pr = -1)
{
	for(int u : nei[v])
		if(u != pr)
		{
			par[u] = v;
			dfsp(u , v);
		}
}

int main()
{
	ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);
	cin >> n;
	memset(mrk , -1 , sizeof mrk);
	for(int i = 2 ; i < N ; i++)
		if(mrk[i] == -1)
		{
			p.push_back(i);
			for(int j = i + i ; j < N ; j += i)
				mrk[j] = i;
		}
	for(int i = 0 ; i < n ; i++)
	{
		cin >> a[i];
		while(a[i] > 1)
		{
			r = mrk[a[i]];
			if ( r == -1 )
				r = a[i] ;
			x[r].push_back(i);
			while(a[i] % r == 0 && a[i] > 1)
				a[i] /= r;
		}
	}
	for(int i = 0 ; i < n - 1 ; i++)
	{
		cin >> aa >> b;
		aa-- , b--;
		nei[aa].push_back(b);
		nei[b].push_back(aa);
	}
	dfsp(0);
	for(int i = 0 ; i < p.size() ; i++)
	{
		if(!x[p[i]].size())
			continue;
		t = dfs_all(p[i]);
		mx = max(mx , t);
	}
	cout << mx;
}


#include <bits/stdc++.h>
#define F first
#define S second
#define PB push_back
using namespace std;

typedef pair<int,int> pi;
typedef pair<int,vector<int>> vertex;

int n;
vertex nodes[200000];
int visited[200000];

int max_dist;

int gcd(int a, int b)
{
    int r;

    while(b)
    {
        r=a%b;
        a=b;
        b=r;
    }

    return a;
}

map<int,int> dfs(int cur, int fromm)
{
    int i,j,k;
    map<int,int> cur_list, tmp_list;

    for(auto s:nodes[cur].S)
    {
        if(visited[s]==0)
        {
            visited[s] = 1;
            tmp_list = dfs(s,cur);

            for(auto sp:tmp_list)
            {
                for(auto pp:cur_list)
                    if ( sp.S + pp.S > max_dist && gcd(sp.F, pp.F) > 1 )
                        max_dist = sp.S + pp.S;
            }

            for(auto sp:tmp_list)
            {
                if ( ( k = gcd(sp.F,nodes[cur].F) ) > 1 )
                {
                    if(cur_list.count(k)==0 || sp.S+1 > cur_list[k])
                    {
                        cur_list[k] = sp.S+1;

                        if( sp.S+1 > max_dist )
                            max_dist = sp.S+1;
                    }
                }
            }
        }
    }

    if(nodes[cur].F > 1 && cur_list.count(nodes[cur].F)==0)
        cur_list[nodes[cur].F] = 1;

    return cur_list;
}

int size_count[200000];

int dfs_count(int cur)
{
    int count = 1;

    for(auto s:nodes[cur].S)
    {
        if( visited[s] == 0 )
        {
            visited[s] = 1;
            count += dfs_count(s);
        }
    }

    return size_count[cur] = count;
}

int dfs_center(int cur, int target)
{
    for(auto s:nodes[cur].S)
    {
        if( visited[s] == 1 && size_count[s] > target )
        {
            visited[s] = 2;
            return dfs_center(s,target);
        }
    }
    return cur;
}

int main()
{
    //freopen("Sample.D.txt", "r", stdin);

    int i,j,k;
    int t;

    max_dist = 0;

    scanf("%d", &n);
    for(i=0;i<n;i++)
    {
        scanf("%d", &nodes[i].F);
        visited[i]=0;

        if(nodes[i].F>1)
            max_dist = 1;
    }

    for(i=1;i<n;i++)
    {
        scanf("%d %d", &j, &k);
        if( gcd( nodes[j-1].F, nodes[k-1].F ) != 1 )
        {
            nodes[j-1].S.PB(k-1);
            nodes[k-1].S.PB(j-1);
        }
    }

    for(i=0;i<n;i++)
    {
        if( visited[i] == 0 )
        {
            visited[i] = 1;
            //k = dfs_count(i);

            //visited[i] = 2;
            //k = dfs_center(i, (k-1)/2);

            //visited[k] = -1;
            dfs(k,-1);
        }
    }

    printf("%d\n", max_dist);

    return 0;
}


#include <bits/stdc++.h>
#define F first
#define S second
#define PB push_back
using namespace std;

typedef pair<int,int> pi;
typedef pair<int,vector<int>> vertex;

int n;
vector<vertex> nodes;
vector<int> visited;

int max_dist;

int gcd(int a, int b)
{
    int r;

    while(b)
    {
        r=a%b;
        a=b;
        b=r;
    }
    return a;
}

vector<pi> dfs(int cur)
{
    int i,j,k;
    vector<pi> cur_list, tmp_list;

    for(auto s:nodes[cur].S)
    {
        if(!visited[s])
        {
            visited[s] = 1;
            tmp_list = dfs(s);

            for(auto sp:tmp_list)
            {
                for(auto pp:cur_list)
                    if ( sp.S + pp.S > max_dist && gcd(sp.F, pp.F) > 1 )
                        max_dist = sp.S + pp.S;
            }

            for(auto sp:tmp_list)
            {
                if ( ( k = gcd(sp.F,nodes[cur].F) ) > 1 )
                {
                    cur_list.PB({k, sp.S+1});

                    if( sp.S + 1 > max_dist )
                        max_dist = sp.S + 1;
                }
            }
        }
    }

    cur_list.PB({nodes[cur].F,1});

    return cur_list;
}

int main()
{
    //freopen("Sample.D.txt", "r", stdin);

    int i,j,k;
    int t;

    max_dist = 0;

    scanf("%d", &n);
    for(i=0;i<n;i++)
    {
        scanf("%d", &k);
        nodes.PB(vertex({k,{}}));
        visited.PB(0);

        if(k>1)
            max_dist = 1;
    }

    for(i=1;i<n;i++)
    {
        scanf("%d %d", &j, &k);
        if( gcd( nodes[j-1].F, nodes[k-1].F ) != 1 )
        {
            nodes[j-1].S.PB(k-1);
            nodes[k-1].S.PB(j-1);
        }
    }

    for(i=0;i<n;i++)
    {
        if( visited[i] == 0 )
        {
            visited[i] = 1;
            dfs(i);
        }
    }

    printf("%d\n", max_dist);

    return 0;
}


#include <bits/stdc++.h>
#define F first
#define S second
#define PB push_back
using namespace std;

typedef pair<int,int> pi;
typedef pair<int,vector<int>> vertex;

int n;
vector<vertex> nodes;
vector<int> visited;

int is_prime[200020];

void prime_table()
{
    int i,j,k;

    k=200020;
    for(i=0;i<k;i++)
        is_prime[i]=1;
    is_prime[1] = 0;
    for(i=2;i<k;i++)
    {
        if(is_prime[i])
            for(j=i*2;j<k;j+=i)
                is_prime[j] = 0;
    }
}

int max_dist;

int gcd(int a, int b)
{
    int r;

    while(b)
    {
        r=a%b;
        a=b;
        b=r;
    }
    return a;
}

vector<pi> dfs(int cur)
{
    int i,j,k;
    vector<pi> cur_list, tmp_list;

    for(auto s:nodes[cur].S)
    {
        if(!visited[s])
        {
            visited[s] = 1;
            tmp_list = dfs(s);

            for(auto sp:tmp_list)
            {
                for(auto pp:cur_list)
                    if ( gcd(sp.F, pp.F) > 1 && sp.S + pp.S > max_dist )
                        max_dist = sp.S + pp.S;
            }

            for(auto sp:tmp_list)
            {
                if ( ( k = gcd(sp.F,nodes[cur].F) ) > 1 )
                {
                    cur_list.PB({k, sp.S+1});

                    if( sp.S + 1 > max_dist )
                        max_dist = sp.S + 1;
                }
            }
        }
    }

    cur_list.PB({nodes[cur].F,1});

    if( nodes[cur].F > 1 && max_dist == 0 )
        max_dist = 1;

    return cur_list;
}

int main()
{
    //freopen("Sample.D.txt", "r", stdin);

    int i,j,k;
    int t;

    //prime_table();

    scanf("%d", &n);
    for(i=0;i<n;i++)
    {
        scanf("%d", &k);
        nodes.PB(vertex({k,{}}));
        visited.PB(0);
    }

    for(i=1;i<n;i++)
    {
        scanf("%d %d", &j, &k);
        nodes[j-1].S.PB(k-1);
        nodes[k-1].S.PB(j-1);
    }

    max_dist = 0;
    visited[0] = 1;
    dfs(0);

    printf("%d\n", max_dist);

    return 0;
}


#include <bits/stdc++.h>
#define F first
#define S second
#define PB push_back
using namespace std;

typedef pair<int,int> pi;
typedef pair<int,vector<int>> vertex;

int n;
vertex nodes[200000];
int visited[200000];

int max_dist;

int gcd(int a, int b)
{
    int r;

    while(b)
    {
        r=a%b;
        a=b;
        b=r;
    }
    return a;
}

vector<pi> dfs(int cur)
{
    int i,j,k;
    vector<pi> cur_list, tmp_list;

    for(auto s:nodes[cur].S)
    {
        if(!visited[s])
        {
            visited[s] = 1;
            tmp_list = dfs(s);

            for(auto sp:tmp_list)
            {
                for(auto pp:cur_list)
                    if ( sp.S + pp.S > max_dist && gcd(sp.F, pp.F) > 1 )
                        max_dist = sp.S + pp.S;
            }

            for(auto sp:tmp_list)
            {
                if ( ( k = gcd(sp.F,nodes[cur].F) ) > 1 )
                {
                    sp.F = k;
                    sp.S++;
                    cur_list.PB(sp);//{k, sp.S+1});

                    if( sp.S > max_dist )
                        max_dist = sp.S;
                }
            }
        }
    }

    cur_list.PB({nodes[cur].F,1});

    return cur_list;
}

int main()
{
    freopen("Sample.D.txt", "r", stdin);

    int i,j,k;
    int t;

    max_dist = 0;

    scanf("%d", &n);
    for(i=0;i<n;i++)
    {
        scanf("%d", &nodes[i].F);
        visited[i]=0;

        if(nodes[i].F>1)
            max_dist = 1;
    }

    for(i=1;i<n;i++)
    {
        scanf("%d %d", &j, &k);
        if( gcd( nodes[j-1].F, nodes[k-1].F ) != 1 )
        {
            nodes[j-1].S.PB(k-1);
            nodes[k-1].S.PB(j-1);
        }
    }

    for(i=0;i<n;i++)
    {
        if( visited[i] == 0 )
        {
            visited[i] = 1;
            dfs(i);
        }
    }

    printf("%d\n", max_dist);

    return 0;
}