#include <bits/stdc++.h>
using namespace std;
const int inf_int = 1e8;
const long long inf_ll = 1e16;
const double pi = 3.1415926535898;
bool debug = 0;
const int MAXN = 1e5 + 10;
const int LOG = 20;
const int mod = 1e9 + 7;
vector<int> g[MAXN];
int tin[MAXN];
int tout[MAXN];
int timer;
int up[MAXN][LOG];
int h[MAXN];
void dfs(int v, int p) {
  tin[v] = ++timer;
  up[v][0] = p;
  for (int i = 1; i < LOG; ++i) {
    up[v][i] = up[up[v][i - 1]][i - 1];
  }
  for (int to : g[v]) {
    if (to == p) continue;
    h[to] = h[v] + 1;
    dfs(to, v);
  }
  tout[v] = timer;
}
int lca(int a, int b) {
  if (h[a] < h[b]) swap(a, b);
  int dif = h[a] - h[b];
  for (int i = 0; i < LOG; ++i) {
    if (dif & (1 << i)) a = up[a][i];
  }
  assert(h[a] == h[b]);
  if (a == b) return a;
  for (int i = LOG - 1; i >= 0; --i) {
    if (up[a][i] != up[b][i]) {
      a = up[a][i];
      b = up[b][i];
    }
  }
  return up[a][0];
}
const int MX = 1e7 + 1;
int mn[MX];
void sieve() {
  for (int i = 2; i < MX; ++i) {
    if (!mn[i]) {
      mn[i] = i;
      if (1ll * i * i < MX) {
        for (int e = i * i; e < MX; e = e + i) {
          if (!mn[e]) mn[e] = i;
        }
      }
    }
  }
}
int a[MAXN];
int ans[MAXN];
pair<int, int> query[MAXN];
vector<pair<pair<int, int>, int>> add_ver;
vector<pair<pair<int, int>, int>> add_quer;
void process_ver(int v) {
  int x = a[v];
  while (x > 1) {
    int cur = mn[x];
    int cnt = 0;
    while (mn[x] == cur) {
      cnt++;
      x /= cur;
    }
    add_ver.push_back({{cur, cnt}, v});
  }
}
void process_quer(int val, int ind) {
  int x = val;
  while (x > 1) {
    int cur = mn[x];
    int cnt = 0;
    while (mn[x] == cur) {
      cnt++;
      x /= cur;
    }
    add_quer.push_back({{cur, cnt}, ind});
  }
}
vector<int> quer_ind[2][MAXN];
struct Fenwick_tree {
  int t[MAXN];
  Fenwick_tree() { memset(t, 0, sizeof t); }
  inline void add(int pos, int val) {
    for (; pos < MAXN; pos = pos + (pos & -pos)) {
      t[pos] += val;
    }
  }
  inline int get(int pos) {
    int res = 0;
    for (; pos > 0; pos = pos - (pos & -pos)) {
      res += t[pos];
    }
    return res;
  }
  inline void add(int l, int r, int x) {
    add(r + 1, -x);
    add(l, x);
  }
} tree;
inline int my_pow(long long a, int n) {
  int res = 1;
  while (n) {
    if (n & 1) res = (res * a) % mod;
    a = (a * a) % mod;
    n >>= 1;
  }
  return res;
}
int was_added[MAXN];
void solve() {
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n - 1; ++i) {
    int a, b;
    scanf("%d %d", &a, &b);
    g[a].push_back(b);
    g[b].push_back(a);
  }
  dfs(1, 1);
  sieve();
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &a[i]);
    process_ver(i);
  }
  int q;
  cin >> q;
  for (int i = 1; i <= q; ++i) {
    int a, b, x;
    scanf("%d %d %d", &a, &b, &x);
    ans[i] = 1;
    query[i] = {a, b};
    process_quer(x, i);
  }
  sort(add_quer.begin(), add_quer.end());
  sort(add_ver.begin(), add_ver.end());
  for (int top_v = 0, top_q = 0;
       top_v < (int(add_ver.size())) && top_q < (int(add_quer.size()));) {
    int mx = max(add_quer[top_q].first.first, add_ver[top_v].first.first);
    while (top_q < (int(add_quer.size())) && add_quer[top_q].first.first < mx)
      ++top_q;
    while (top_v < (int(add_ver.size())) && add_ver[top_v].first.first < mx)
      ++top_v;
    if (top_q == (int(add_quer.size())) || top_v == (int(add_ver.size())) ||
        add_quer[top_q].first.first != add_ver[top_v].first.first)
      continue;
    int l = top_v, r = top_v;
    while (r < (int(add_ver.size())) && add_ver[r].first.first == mx) ++r;
    int mx_power = 0;
    while (top_q < (int(add_quer.size())) &&
           add_quer[top_q].first.first == mx) {
      int cur_power = add_quer[top_q].first.second;
      if (cur_power > mx_power) {
        for (int i = l; i < r; ++i) {
          if (add_ver[i].first.second > mx_power) {
            int v = add_ver[i].second;
            int temp = min(add_ver[i].first.second, cur_power) - mx_power;
            tree.add(tin[v], tout[v], temp);
            was_added[v] += temp;
          }
        }
        mx_power = cur_power;
      }
      int id = add_quer[top_q].second;
      int a, b;
      tie(a, b) = query[id];
      int lc = lca(a, b);
      int res = tree.get(tin[a]) + tree.get(tin[b]) - tree.get(tin[lc]);
      if (lc != 1) res = res - tree.get(tin[up[lc][0]]);
      ans[id] = (1ll * my_pow(mx, res) * ans[id]) % mod;
      ++top_q;
    }
    for (int i = l; i < r; ++i) {
      int v = add_ver[i].second;
      tree.add(tin[v], tout[v], -was_added[v]);
      was_added[v] = 0;
    }
    top_v = r;
  }
  for (int i = 1; i <= q; ++i) {
    printf("%d\n", ans[i]);
  }
}
signed main() {
  int t = 1;
  while (t--) solve();
}
