← Home
```go
package main

import (
	"io"
	"os"
	"runtime/debug"
	"strconv"
)

const LOG = 17
const MOD int64 = 1000000007

func bitAdd(bit []int32, n, idx int, delta int32) {
	for idx <= n {
		bit[idx] += delta
		idx += idx & -idx
	}
}

func bitSum(bit []int32, idx int) int {
	var s int32
	for idx > 0 {
		s += bit[idx]
		idx -= idx & -idx
	}
	return int(s)
}

func modPow(a, e int) int64 {
	var res int64 = 1
	b := int64(a)
	for e > 0 {
		if e&1 != 0 {
			res = res * b % MOD
		}
		b = b * b % MOD
		e >>= 1
	}
	return res
}

func main() {
	debug.SetGCPercent(-1)

	data, _ := io.ReadAll(os.Stdin)
	p := 0
	nextInt := func() int {
		for p < len(data) && (data[p] < '0' || data[p] > '9') {
			p++
		}
		x := 0
		for p < len(data) && data[p] >= '0' && data[p] <= '9' {
			x = x*10 + int(data[p]-'0')
			p++
		}
		return x
	}

	n := nextInt()

	head := make([]int, n+1)
	to := make([]int, 2*(n-1)+1)
	nxt := make([]int, 2*(n-1)+1)
	ec := 0
	addEdge := func(u, v int) {
		ec++
		to[ec] = v
		nxt[ec] = head[u]
		head[u] = ec
	}

	for i := 0; i < n-1; i++ {
		u := nextInt()
		v := nextInt()
		addEdge(u, v)
		addEdge(v, u)
	}

	a := make([]int, n+1)
	maxNum := 0
	for i := 1; i <= n; i++ {
		a[i] = nextInt()
		if a[i] > maxNum {
			maxNum = a[i]
		}
	}

	parent := make([]int, n+1)
	depth := make([]int, n+1)
	tin := make([]int, n+1)
	tout := make([]int, n+1)
	iter := make([]int, n+1)

	stack := make([]int, 0, n)
	stack = append(stack, 1)
	iter[1] = head[1]
	tin[1] = 1
	timer := 1

	for len(stack) > 0 {
		v := stack[len(stack)-1]
		e := iter[v]
		if e == 0 {
			tout[v] = timer
			stack = stack[:len(stack)-1]
			continue
		}
		iter[v] = nxt[e]
		w := to[e]
		if w == parent[v] {
			continue
		}
		parent[w] = v
		depth[w] = depth[v] + 1
		timer++
		tin[w] = timer
		iter[w] = head[w]
		stack = append(stack, w)
	}

	var up [LOG][]int
	up[0] = parent
	for k := 1; k < LOG; k++ {
		up[k] = make([]int, n+1)
		prev := up[k-1]
		cur := up[k]
		for i := 1; i <= n; i++ {
			cur[i] = prev[prev[i]]
		}
	}

	lca := func(u, v int) int {
		if depth[u] < depth[v] {
			u, v = v, u
		}
		diff := depth[u] - depth[v]
		for k := 0; k < LOG; k++ {
			if diff&(1<<k) != 0 {
				u = up[k][u]
			}
		}
		if u == v {
			return u
		}
		for k := LOG - 1; k >= 0; k-- {
			if up[k][u] != up[k][v] {
				u = up[k][u]
				v = up[k][v]
			}
		}
		return parent[u]
	}

	q := nextInt()
	qu := make([]int, q)
	qv := make([]int, q)
	ql := make([]int, q)
	qx := make([]int, q)

	for i := 0; i < q; i++ {
		u := nextInt()
		v := nextInt()
		x := nextInt()
		qu[i] = u
		qv[i] = v
		qx[i] = x
		ql[i] = lca(u, v)
		if x > maxNum {
			maxNum = x
		}
	}

	limit := 0
	for int64(limit+1)*int64(limit+1) <= int64(maxNum) {
		limit++
	}

	primes := make([]int, 0, 450)
	if limit >= 2 {
		comp := make([]bool, limit+1)
		for i := 2; i <= limit; i++ {
			if !comp[i] {
				primes = append(primes, i)
				if i*i <= limit {
					for j := i * i; j <= limit; j += i {
						comp[j] = true
					}
				}
			}
		}
	}

	queryHead := make([]int32, maxNum+1)
	queryQid := make([]int32, 1, q*24+1)
	queryNext := make([]int32, 1, q*24+1)
	queryUsed := make([]int, 0, q*4+1)
	queryUsedPrime := make([]int, 0, q*4+1)
	ans := make([]int64, q)

	for i := 0; i < q; i++ {
		ans[i] = 1
		m := qx[i]
		for _, pr := range primes {
			if pr*pr > m {
				break
			}
			if m%pr == 0 {
				pw := 1
				for m%pr == 0 {
					m /= pr
					pw *= pr
					if queryHead[pw] == 0 {
						queryUsed = append(queryUsed, pw)
						queryUsedPrime = append(queryUsedPrime, pr)
					}
					queryQid = append(queryQid, int32(i))
					queryNext = append(queryNext, queryHead[pw])
					queryHead[pw] = int32(len(queryQid) - 1)
				}
			}
		}
		if m > 1 {
			if queryHead[m] == 0 {
				queryUsed = append(queryUsed, m)
				queryUsedPrime = append(queryUsedPrime, m)
			}
			queryQid = append(queryQid, int32(i))
			queryNext = append(queryNext, queryHead[m])
			queryHead[m] = int32(len(queryQid) - 1)
		}
	}

	nodeHead := make([]int32, maxNum+1)
	nodeV := make([]int32, 1, n*24+1)
	nodeNext := make([]int32, 1, n*24+1)

	for v := 1; v <= n; v++ {
		m := a[v]
		for _, pr := range primes {
			if pr*pr > m {
				break
			}
			if m%pr == 0 {
				pw := 1
				for m%pr == 0 {
					m /= pr
					pw *= pr
					if queryHead[pw] != 0 {
						nodeV = append(nodeV, int32(v))
						nodeNext = append(nodeNext, nodeHead[pw])
						nodeHead[pw] = int32(len(nodeV) - 1)
					}
				}
			}
		}
		if m > 1 && queryHead[m] != 0 {
			nodeV = append(nodeV, int32(v))
			nodeNext = append(nodeNext, nodeHead[m])
			nodeHead[m] = int32(len(nodeV) - 1)
		}
	}

	bit := make([]int32, n+2)
	fenN := n + 1

	for gi, d := range queryUsed {
		nh := nodeHead[d]
		if nh == 0 {
			continue
		}

		for it := nh; it != 0; it = nodeNext[it] {
			v := int(nodeV[it])
			bitAdd(bit, fenN, tin[v], 1)
			bitAdd(bit, fenN, tout[v]+1, -1)
		}

		pr := queryUsedPrime[gi]
		for it := queryHead[d]; it != 0; it = queryNext[it] {
			id := int(queryQid[it])
			l := ql[id]
			cnt := bitSum(bit, tin[qu[id]]) + bitSum(bit, tin[qv[id]]) - 2*bitSum(bit, tin[l])
			if a[l]%d == 0 {
				cnt++
			}
			if cnt != 0 {
				ans[id] = ans[id] * modPow(pr, cnt) % MOD
			}
		}

		for it := nh; it != 0; it = nodeNext[it] {
			v := int(nodeV[it])
			bitAdd(bit, fenN, tin[v], -1)
			bitAdd(bit, fenN, tout[v]+1, 1)
		}
	}

	out := make([]byte, 0, q*12)
	for i := 0; i < q; i++ {
		out = strconv.AppendInt(out, ans[i], 10)
		out = append(out, '\n')
	}
	_, _ = os.Stdout.Write(out)
}
```