```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)
}
```