← Home
package main

import (
	"bufio"
	"fmt"
	"os"
)

const MOD = 1000000007

type Pair struct {
	g int64
	c int
}

func gcd(a, b int64) int64 {
	for b != 0 {
		a, b = b, a%b
	}
	return a
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	buf := make([]byte, 1024*1024)
	scanner.Buffer(buf, 10*1024*1024)

	scanInt := func() int {
		scanner.Scan()
		var res int
		for _, b := range scanner.Bytes() {
			res = res*10 + int(b-'0')
		}
		return res
	}

	scanInt64 := func() int64 {
		scanner.Scan()
		var res int64
		for _, b := range scanner.Bytes() {
			res = res*10 + int64(b-'0')
		}
		return res
	}

	if !scanner.Scan() {
		return
	}
	n := 0
	for _, b := range scanner.Bytes() {
		n = n*10 + int(b-'0')
	}

	x := make([]int64, n+1)
	for i := 1; i <= n; i++ {
		x[i] = scanInt64()
	}

	adj := make([][]int, n+1)
	for i := 0; i < n-1; i++ {
		u := scanInt()
		v := scanInt()
		adj[u] = append(adj[u], v)
		adj[v] = append(adj[v], u)
	}

	var ans int64

	var dfs func(u, p int, parentDP []Pair)
	dfs = func(u, p int, parentDP []Pair) {
		currDP := make([]Pair, 0, len(parentDP)+1)
		currDP = append(currDP, Pair{x[u], 1})

		for _, pair := range parentDP {
			g := gcd(pair.g, x[u])
			found := false
			for i := range currDP {
				if currDP[i].g == g {
					currDP[i].c = (currDP[i].c + pair.c) % MOD
					found = true
					break
				}
			}
			if !found {
				currDP = append(currDP, Pair{g, pair.c})
			}
		}

		for _, pair := range currDP {
			term := (pair.g % MOD) * int64(pair.c) % MOD
			ans = (ans + term) % MOD
		}

		for _, v := range adj[u] {
			if v != p {
				dfs(v, u, currDP)
			}
		}
	}

	dfs(1, 0, nil)

	fmt.Println(ans)
}