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 javafx.util.*;
import java.util.*;
import java.io.*;
import java.math.*;

public class Test8 {


    PrintWriter pw = new PrintWriter(System.out);
    Random rnd = new Random();
    int a, o=0;
    int[] m, d = new int[200005];
    ArrayList<Integer>[] l;

    void run(){
        a = ni();
        for(int q=2; q<200005; q++){
            if(d[q]!=0) continue;
            for(int w=q; w<200005; w+=q) d[w] = q;
        }
        if(a==1){
            System.out.println(ni()==1 ? 1 : 0);
            return;
        }
        l = new ArrayList[a];
        for(int q=0; q<a; q++) l[q] = new ArrayList<>();
        m = na(a);
        for(int q=1; q<a; q++){
            int x = ni()-1, y = ni()-1;
            l[x].add(y);
            l[y].add(x);
        }
        dfs(0, -1);
        pw.print(o);
        pw.flush();
    }

    HashMap<Integer, Integer> dfs(int v, int p){
        HashMap<Integer, Integer> h = new HashMap<>();
        for(int i : get(m[v])) h.put(i, 1);
        if(l[v].size()==1 && l[v].get(0)==p){
            if(h.size()>0) o = Math.max(o, 1);
            return h;
        }
        for(int i : l[v]){
            if(i==p) continue;
            for(Map.Entry<Integer, Integer> mp : dfs(i, v).entrySet()){
                int k = mp.getKey(), val = mp.getValue();
                if(!h.containsKey(k)) continue;
                int c = h.get(k);
                if(c==1){
                    h.put(k, 1+val);
                    o = Math.max(o, 1+val);
                }
                else{
                    o = Math.max(o, val+c);
                    if(1+val>c) h.put(k, 1+val);
                }
            }
        }
        return h;
    }

    HashSet<Integer> get(int c){
        HashSet<Integer> o = new HashSet<>();
        for(; c>1; c/=d[c]) o.add(d[c]);
        return o;
    }

    int gcd(int a, int b){
        for(; a>0 && b>0;){
            if(a>b) a%=b;
            else b%=a;
        }
        return a+b;
    }

    static class PyraSort {

        private static int heapSize;

        public static void sort(int[] a) {
            buildHeap(a);
            while (heapSize > 1) {
                swap(a, 0, heapSize - 1);
                heapSize--;
                heapify(a, 0);
            }
        }

        private static void buildHeap(int[] a) {
            heapSize = a.length;
            for (int i = a.length / 2; i >= 0; i--) {
                heapify(a, i);
            }
        }

        private static void heapify(int[] a, int i) {
            int l = 2 * i + 2;
            int r = 2 * i + 1;
            int largest = i;
            if (l < heapSize && a[i] < a[l]) {
                largest = l;
            }
            if (r < heapSize && a[largest] < a[r]) {
                largest = r;
            }
            if (i != largest) {
                swap(a, i, largest);
                heapify(a, largest);
            }
        }

        private static void swap(int[] a, int i, int j) {
            a[i] ^= a[j] ^= a[i];
            a[j] ^= a[i];
        }
    }

    public static void main(String[] args) {
        new Test8().run();
    }

    InputStream is = System.in;
    private byte[] inbuf = new byte[1024];
    public int lenbuf = 0, ptrbuf = 0;

    private int readByte() {
        if (lenbuf == -1) throw new InputMismatchException();
        if (ptrbuf >= lenbuf) {
            ptrbuf = 0;
            try {
                lenbuf = is.read(inbuf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (lenbuf <= 0) return -1;
        }
        return inbuf[ptrbuf++];
    }

    private boolean isSpaceChar(int c) {
        return !(c >= 33 && c <= 126);
    }

    private int skip() {
        int b;
        while ((b = readByte()) != -1 && isSpaceChar(b)) ;
        return b;
    }

    private double nd() {
        return Double.parseDouble(ns());
    }

    private char nc() {
        return (char) skip();
    }

    private String nline(){
        int b = readByte();
        StringBuilder sb = new StringBuilder();
        while (b!=10) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private String ns() {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while (!(isSpaceChar(b))) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private char[] ns(int n) {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while (p < n && !(isSpaceChar(b))) {
            buf[p++] = (char) b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private char[][] nm(int n, int m) {
        char[][] map = new char[n][];
        for (int i = 0; i < n; i++) map[i] = ns(m);
        return map;
    }

    private int[] na(int n) {
        int[] a = new int[n];
        for (int i = 0; i < n; i++) a[i] = ni();
        return a;
    }

    private int ni() {
        int num = 0, b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
        if (b == '-') {
            minus = true;
            b = readByte();
        }
        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private long nl() {
        long num = 0;
        int b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
        if (b == '-') {
            minus = true;
            b = readByte();
        }
        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }
}

class O{
    int l, r, n;

    O(int a, int b, int c){
        l  =a;
        r = b;
        n = c;
    }
}