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

import java.io.*;
import java.util.*;
public class Main {
	static ArrayList<ArrayList<Integer>> adjl=new ArrayList<>();
	static int[] height;
	static ArrayList<ArrayList<Integer>> groups=new ArrayList<>();
	static ArrayList<ArrayList<Integer>> prime_div=new ArrayList<>();
	static int MAX=200005;
	
	static boolean[] isMarked=new boolean[MAX];
	static boolean[] vis=new boolean[MAX];
	static int diameter;
	static int furthest;

	static void dfs(int v,int parent,int count) {
		vis[v]=true;
		if(count>diameter) {
			diameter=count;
			furthest=v;
		}
		for(int child:adjl.get(v)) {
			if(isMarked[child]==true && parent!=child) {
				dfs(child,v,count+1);
			}
		}
	}
	
	static int getAns(ArrayList<Integer> grp) {
		for(int z:grp) {
			isMarked[z]=true;
		}
		int path=0;
		for(int v:grp) {
			if(vis[v]==false) {
				diameter=Integer.MIN_VALUE;
				furthest=-1;
				dfs(v,v,1);
				diameter=Integer.MIN_VALUE;
				dfs(furthest,furthest,1);
				path=Math.max(path, diameter);
			}
		}
		for(int z:grp) {
			isMarked[z]=false;
			vis[z]=false;
		}
		return path;
	}
	
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		Reader sc=new Reader();
		int t=1;
		
		for(int i=0;i<MAX;i++) {
			groups.add(new ArrayList<>());
			prime_div.add(new ArrayList<>());
		}
		
		for(int i=2;i<MAX;i++) {
			if(prime_div.get(i).isEmpty()) {
				for(int j=i;j<MAX;j+=i) {
					prime_div.get(j).add(i);
				}
			}
		}
		
		while(t-->0) {
			int n=sc.nextInt();
			int[] a=new int[n];
			height=new int[n];
			for(int i=0;i<n;i++) {
				a[i]=sc.nextInt();
				for(int p:prime_div.get(a[i])) {
					groups.get(p).add(i);
				}
			}
			
			for(int i=0;i<n;i++) {
				adjl.add(new ArrayList<>());
			}
			for(int i=0;i<n-1;i++) {
				int src=sc.nextInt()-1;
				int dest=sc.nextInt()-1;
				adjl.get(src).add(dest);
				adjl.get(dest).add(src);
			}
			int ans=0;
			for(int i=0;i<MAX;i++) {
				if(!groups.get(i).isEmpty()) {
					ans=Math.max(ans, getAns(groups.get(i)));
				}
			}
			System.out.println(ans);
		}
		sc.close();
	}
	
	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]; // line length
            int cnt = 0, c;
            while ((c = read()) != -1) {
                if (c == '\n') {
                    if (cnt != 0) {
                        break;
                    }
                    else {
                        continue;
                    }
                }
                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();
        }
    }

}
