#include <bits/stdc++.h>
using namespace std;
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
#pragma GCC optimize("Ofast,no-stack-protector")
#pragma GCC target("avx,tune=native")
const long long mod = 1000000007;
const int maxn = 100100;
long long exponentiation(long long A, long long B, long long MOD) {
  long long ans = 1;
  for (; B; A = (A * A) % MOD, B >>= 1)
    if (B & 1) ans = (ans * A) % MOD;
  return ans;
}
pair<int, int> tree[maxn << 2];
pair<int, int> operator+(pair<int, int> a, pair<int, int> b) {
  return {1ll * a.first * b.first % mod, a.second + b.second};
}
void upd(int pos, int v) {
  for (pos++; pos < maxn << 2; pos += pos & -pos)
    tree[pos] = tree[pos] + make_pair(v, 1);
}
void update(int pos, int v) { upd(pos + 2 * maxn - 100, v); }
void ree(int pos) {
  for (pos++; pos < maxn << 2; pos += pos & -pos) tree[pos] = make_pair(1, 0);
}
void remove(int pos) { ree(pos + 2 * maxn - 100); }
void clear() {
  for (int e = 0; e < maxn << 2; e++) tree[e] = {1, 0};
}
pair<int, int> sum(int pos) {
  pair<int, int> ruu = {1ll, 0};
  for (pos++; pos; pos -= pos & -pos) ruu = ruu + tree[pos];
  return ruu;
}
pair<int, int> query(int x, int y) {
  pair<int, int> down = sum(x + 2 * maxn - 101);
  pair<int, int> up = sum(y + 2 * maxn - 100);
  return make_pair(
      1ll * exponentiation(down.first, mod - 2, mod) * up.first % mod,
      up.second - down.second);
}
int online[maxn], sz[maxn];
int color[maxn], clam[maxn];
int u[maxn], v[maxn], x[maxn], c[maxn];
vector<int> g[maxn];
vector<long long> res;
void init(int cur, int p) {
  sz[cur] = 1;
  for (int d : g[cur]) {
    int nxt = u[d];
    if (nxt == cur) nxt = v[d];
    if (nxt != p && !online[nxt]) {
      init(nxt, cur);
      sz[cur] += sz[nxt];
    }
  }
}
int get_centroid(int cur, int p, int w) {
  int biggest = -1;
  for (int d : g[cur]) {
    int nxt = u[d];
    if (nxt == cur) nxt = v[d];
    if (nxt != p && !online[nxt] && (biggest == -1 || sz[biggest] < sz[nxt]))
      biggest = nxt;
  }
  if (biggest == -1 || sz[biggest] * 2 <= w) return cur;
  return get_centroid(biggest, cur, w);
}
const int zx = 100000;
void count0(int cur, int p, int r, int b, int co) {
  pair<int, int> mul = query(-2 * zx, 2 * r - b);
  if (mul.second) {
    res.back() *= 1ll * mul.first * exponentiation(co, mul.second, mod) % mod;
    res.back() %= mod;
  }
  for (int d : g[cur]) {
    int nxt = u[d];
    if (nxt == cur) nxt = v[d];
    if (nxt != p && !online[nxt]) {
      count0(nxt, cur, r + 1 - c[d], b + c[d], 1ll * co * x[d] % mod);
    }
  }
}
void add0(int cur, int p, int r, int b, int co) {
  update(b - 2 * r, co);
  for (int d : g[cur]) {
    int nxt = u[d];
    if (nxt == cur) nxt = v[d];
    if (nxt != p && !online[nxt])
      add0(nxt, cur, r + 1 - c[d], b + c[d], 1ll * co * x[d] % mod);
  }
}
void rem0(int cur, int p, int r, int b) {
  remove(b - 2 * r);
  for (int d : g[cur]) {
    int nxt = u[d];
    if (nxt == cur) nxt = v[d];
    if (nxt != p && !online[nxt]) rem0(nxt, cur, r + 1 - c[d], b + c[d]);
  }
}
void find0(int cur) {
  init(cur, -1);
  cur = get_centroid(cur, -1, sz[cur]);
  update(0, 1);
  for (int d : g[cur]) {
    int nxt = u[d];
    if (nxt == cur) nxt = v[d];
    if (online[nxt]) continue;
    count0(nxt, cur, 1 - c[d], c[d], x[d]);
    add0(nxt, cur, 1 - c[d], c[d], x[d]);
  }
  remove(0);
  rem0(cur, -1, 0, 0);
  online[cur] = 1;
  for (int d : g[cur]) {
    int nxt = u[d];
    if (nxt == cur) nxt = v[d];
    if (online[nxt]) continue;
    find0(nxt);
  }
}
void count1(int cur, int p, int r, int b, int co) {
  pair<int, int> mul = query(2 * b - r + 1, 2 * zx + 1);
  if (mul.second) {
    res.back() *= 1ll * mul.first * exponentiation(co, mul.second, mod) % mod;
    res.back() %= mod;
  }
  for (int d : g[cur]) {
    int nxt = u[d];
    if (nxt == cur) nxt = v[d];
    if (nxt != p && !online[nxt]) {
      count1(nxt, cur, r + 1 - c[d], b + c[d], 1ll * co * x[d] % mod);
    }
  }
}
void add1(int cur, int p, int r, int b, int co) {
  update(r - 2 * b, co);
  for (int d : g[cur]) {
    int nxt = u[d];
    if (nxt == cur) nxt = v[d];
    if (nxt != p && !online[nxt])
      add1(nxt, cur, r + 1 - c[d], b + c[d], 1ll * co * x[d] % mod);
  }
}
void rem1(int cur, int p, int r, int b) {
  remove(r - 2 * b);
  for (int d : g[cur]) {
    int nxt = u[d];
    if (nxt == cur) nxt = v[d];
    if (nxt != p && !online[nxt]) rem1(nxt, cur, r + 1 - c[d], b + c[d]);
  }
}
void find1(int cur) {
  init(cur, -1);
  cur = get_centroid(cur, -1, sz[cur]);
  update(0, 1);
  for (int d : g[cur]) {
    int nxt = u[d];
    if (nxt == cur) nxt = v[d];
    if (online[nxt]) continue;
    count1(nxt, cur, 1 - c[d], c[d], x[d]);
    add1(nxt, cur, 1 - c[d], c[d], x[d]);
  }
  remove(0);
  rem1(cur, -1, 0, 0);
  online[cur] = 1;
  for (int d : g[cur]) {
    int nxt = u[d];
    if (nxt == cur) nxt = v[d];
    if (online[nxt]) continue;
    find1(nxt);
  }
}
int main() {
  int n;
  scanf("%d", &n);
  for (int e = 0; e < n - 1; e++) {
    scanf("%d %d %d %d", u + e, v + e, x + e, c + e);
    u[e]--;
    v[e]--;
    g[u[e]].push_back(e);
    g[v[e]].push_back(e);
  }
  clear();
  memset(online, 0, sizeof(online));
  res.push_back(1ll);
  find0(0);
  memset(online, 0, sizeof(online));
  res.push_back(1ll);
  find1(0);
  cout << res[0] * exponentiation(res[1], mod - 2, mod) % mod << endl;
  return 0;
}
