#include <bits/stdc++.h>
using namespace std;
const int N = 400000 + 7;
const int M = N / 3;
const long long MM = 1ll * M * M;
const int inf = 1e9 + 7;
const long long linf = 1ll * inf * inf;
const double pi = acos(-1);
const double eps = 1e-7;
const bool multipleTest = 0;
int inverse(int x, int n) {
  int r = n, newr = x;
  int t = 0, newt = 1;
  while (newr > 0) {
    int q = r / newr;
    int tmp = newr;
    newr = r % newr;
    r = tmp;
    tmp = newt;
    newt = t - q * newt;
    t = tmp;
  }
  if (t < 0) t += n;
  return t;
}
long long pw(long long x, long long k) {
  assert(k >= 0);
  if (!k) return 1;
  if (k & 1) return pw(x, k - 1) * x % inf;
  long long tmp = pw(x, k >> 1);
  return tmp * tmp % inf;
}
vector<pair<pair<int, int>, int>> adj[N];
int n;
int nxt[N];
int f[N];
int c[N];
int d[N];
long long res = 1;
long long res2 = 1;
long long p[N];
int g[N];
long long alterP[N];
vector<pair<long long, int>> all[N];
void dfs2(int u, int r) {
  f[u] = 1;
  nxt[u] = u;
  all[u].clear();
  alterP[u] = 1;
  g[u] = 0;
  for (auto& xx : adj[u]) {
    int v = xx.first.first;
    if (v != r) {
      p[v] = xx.second;
      c[v] = (xx.first.second == 0) ? -2 : 1;
      d[v] = d[u] + c[v];
      dfs2(v, u);
      f[u] += f[v];
      if (nxt[u] == u || f[nxt[u]] < f[v]) {
        nxt[u] = v;
      }
    }
  }
}
void dfs(int u, int r) {
  f[u] = 1;
  nxt[u] = u;
  all[u].clear();
  alterP[u] = 1;
  g[u] = 0;
  for (auto& xx : adj[u]) {
    int v = xx.first.first;
    if (v != r) {
      p[v] = xx.second;
      c[v] = (xx.first.second == 0) ? 1 : -2;
      d[v] = d[u] + c[v];
      dfs(v, u);
      long long k = 1ll * f[v] * (n - f[v]) % (inf - 1);
      res2 = res2 * pw(p[v], k) % inf;
      f[u] += f[v];
      if (nxt[u] == u || f[nxt[u]] < f[v]) {
        nxt[u] = v;
      }
    }
  }
}
long long L[N], T[N];
void update(int x, long long val, int cnt) {
  assert(x >= 0);
  for (int t = x; t > 0; t -= t & -t) {
    L[t] = L[t] * val % inf;
    T[t] += cnt;
  }
}
pair<long long, long long> get(int x) {
  assert(x > 0);
  long long val = 1, cnt = 0;
  for (int t = x; t < N; t += t & -t) {
    val = val * L[t] % inf;
    cnt += T[t];
  }
  return make_pair(val, cnt);
}
void hldtrick(int u, int r, bool keep) {
  for (auto& xx : adj[u]) {
    int v = xx.first.first;
    if (v != r && v != nxt[u]) {
      hldtrick(v, u, false);
    }
  }
  int ru = nxt[u];
  long long invAlter = 1;
  if (nxt[u] != u) {
    hldtrick(nxt[u], u, true);
    ru = nxt[nxt[u]];
    invAlter = inverse(alterP[ru] % inf, inf);
  }
  for (auto& xx : adj[u]) {
    int v = xx.first.first;
    if (v != r && v != nxt[u]) {
      for (auto& rr : all[nxt[v]]) {
        int diff = -g[ru] - g[nxt[v]] - rr.second + 1;
        pair<long long, long long> tmp = get(diff + M);
        if (tmp.second == 0) continue;
        long long diffP = alterP[ru] * rr.first % inf * alterP[nxt[v]] % inf;
        diffP = pw(diffP, tmp.second);
        res = res * diffP % inf * tmp.first % inf;
      }
      for (auto& rr : all[nxt[v]]) {
        long long len = rr.first * alterP[nxt[v]] % inf * invAlter % inf;
        int newC = rr.second + g[nxt[v]] - g[ru];
        update(newC + M, len, 1);
        all[ru].push_back(make_pair(len, newC));
      }
      all[nxt[v]].clear();
    }
  }
  auto tmp = ::get(1 - g[ru] + M);
  res = res * tmp.first % inf * pw(alterP[ru], tmp.second) % inf;
  g[ru] += c[u];
  alterP[ru] = alterP[ru] * p[u] % inf;
  nxt[u] = ru;
  all[ru].push_back(
      make_pair(p[u] * inverse(alterP[ru], inf) % inf, -g[ru] + c[u]));
  update(all[ru].back().second + M, all[ru].back().first, 1);
  if (!keep) {
    for (auto& rr : all[ru]) {
      update(rr.second + M, inverse(rr.first, inf), -1);
    }
  }
}
void solve() {
  cin >> n;
  for (int i = 1; i < n; ++i) {
    int u, v, x, c;
    scanf("%d%d%d%d", &u, &v, &x, &c);
    adj[u].push_back(make_pair(make_pair(v, c), x));
    adj[v].push_back(make_pair(make_pair(u, c), x));
  }
  p[1] = 1;
  c[1] = 0;
  d[1] = 0;
  dfs2(1, -1);
  for (int i = 0; i < N; ++i) {
    L[i] = 1;
    T[i] = 0;
  }
  hldtrick(1, -1, 0);
  p[1] = 1;
  c[1] = 0;
  d[1] = 0;
  dfs(1, -1);
  for (int i = 0; i < N; ++i) {
    L[i] = 1;
    T[i] = 0;
  }
  hldtrick(1, -1, 0);
  res2 = res2 * inverse(res % inf, inf) % inf;
  cout << res2 << '\n';
}
int main() {
  int Test = 1;
  if (multipleTest) cin >> Test;
  for (int i = 0; i < Test; ++i) {
    solve();
  }
}
