You are given a tree consisting of n vertices. A number is written on each vertex; the number on vertex i is equal to a_i.

Let's denote the function g(x, y) as the greatest common divisor of the numbers written on the vertices belonging to the simple path from vertex x to vertex y (including these two vertices). Also let's denote dist(x, y) as the number of vertices on the simple path between vertices x and y, including the endpoints. dist(x, x) = 1 for every vertex x.

Your task is calculate the maximum value of dist(x, y) among such pairs of vertices that g(x, y) > 1.

Input

The first line contains one integer n — the number of vertices (1 ≤ n ≤ 2 ⋅ 10^5).

The second line contains n integers a_1, a_2, ..., a_n (1 ≤ a_i ≤ 2 ⋅ 10^5) — the numbers written on vertices.

Then n - 1 lines follow, each containing two integers x and y (1 ≤ x, y ≤ n, x ≠ y) denoting an edge connecting vertex x with vertex y. It is guaranteed that these edges form a tree.

Output

If there is no pair of vertices x, y such that g(x, y) > 1, print 0. Otherwise print the maximum value of dist(x, y) among such pairs.

Examples

Input

3
2 3 4
1 2
2 3


Output

1


Input

3
2 3 4
1 3
2 3


Output

2


Input

3
1 1 1
1 2
2 3


Output

0
//created by Whiplash99
import java.io.*;
import java.util.*;
public class D
{
    private static int[] spf,a;
    private static ArrayDeque<Integer>[] edge;
    private static HashMap<Integer,Integer>[] map;
    private static final int LIM=(int)(2e5);
    private static void sieve()
    {
        for(int i=2;i<=LIM;i++)
        {
            if(spf[i]!=0) continue;
            spf[i]=i;
            if((long)i*i<=LIM)
                for(int j=i*i;j<=LIM;j+=i) if(spf[j]==0) spf[j]=i;
        }
    }
    private static int DFS(int u, int p)
    {
        int ans=0, x=a[u];
        for(int v:edge[u]) if(v!=p) ans=Math.max(ans,DFS(v,u));
        while (x>1)
        {
            int prime=spf[x], max1=0, max2=0;
            while (x%prime==0) x/=prime;

            for(int v:edge[u])
            {
                if(a[v]%prime!=0) continue;
                int c=map[v].getOrDefault(prime,0);
                if(c>max1){max2=max1;max1=c;}
                else if(c>max2) max2=c;
            }
            ans=Math.max(ans,max1+max2+1);
            map[u].put(prime,max1+1);
        }
        return ans;
    }
    public static void main(String[] args) throws IOException
    {
        Reader r=new Reader();

        int i,N;

        spf=new int[LIM+5];
        sieve();

        N=r.nextInt();
        edge=new ArrayDeque[N]; a=new int[N];
        map=new HashMap[N]; for(i=0;i<N;i++) map[i]=new HashMap<>();
        for(i=0;i<N;i++) edge[i]=new ArrayDeque<>();

        for(i=0;i<N;i++) a[i]=r.nextInt();
        for(i=0;i<N-1;i++)
        {
            int u=r.nextInt()-1;
            int v=r.nextInt()-1;

            edge[u].add(v); edge[v].add(u);
        }

        System.out.println(DFS(0,-1));
    }
    static class Reader
    {
        final private int BUFFER_SIZE = 1 << 16;private DataInputStream din;private byte[] buffer;private int bufferPointer, bytesRead;
        public Reader(){din=new DataInputStream(System.in);buffer=new byte[BUFFER_SIZE];bufferPointer=bytesRead=0;
        }public Reader(String file_name) throws IOException{din=new DataInputStream(new FileInputStream(file_name));buffer=new byte[BUFFER_SIZE];bufferPointer=bytesRead=0;
        }public String readLine() throws IOException{byte[] buf=new byte[64];int cnt=0,c;while((c=read())!=-1){if(c=='\n')break;buf[cnt++]=(byte)c;}return new String(buf,0,cnt);
        }public int nextInt() throws IOException{int ret=0;byte c=read();while(c<=' ')c=read();boolean neg=(c=='-');if(neg)c=read();do{ret=ret*10+c-'0';}while((c=read())>='0'&&c<='9');if(neg)return -ret;return ret;
        }public long nextLong() throws IOException{long ret=0;byte c=read();while(c<=' ')c=read();boolean neg=(c=='-');if(neg)c=read();do{ret=ret*10+c-'0';}while((c=read())>='0'&&c<='9');if(neg)return -ret;return ret;
        }public double nextDouble() throws IOException{double ret=0,div=1;byte c=read();while(c<=' ')c=read();boolean neg=(c=='-');if(neg)c = read();do {ret=ret*10+c-'0';}while((c=read())>='0'&&c<='9');if(c=='.')while((c=read())>='0'&&c<='9')ret+=(c-'0')/(div*=10);if(neg)return -ret;return ret;
        }private void fillBuffer() throws IOException{bytesRead=din.read(buffer,bufferPointer=0,BUFFER_SIZE);if(bytesRead==-1)buffer[0]=-1;
        }private byte read() throws IOException{if(bufferPointer==bytesRead)fillBuffer();return buffer[bufferPointer++];
        }public void close() throws IOException{if(din==null) return;din.close();}
    }
}