#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
int n;
const int mod = 1e9 + 7;
using vi = vector<int>;
using pii = pair<int, int>;
using vp = vector<pii>;
int mul(int first, int second) { return 1ll * first * second % mod; }
struct fen {
  int n, a[100005 * 4];
  void init(int _n) {
    n = _n;
    for (int i = 0; i <= n; i++) a[i] = 0;
    return;
  }
  void add_upd(int p) {
    for (; p <= n; p += p & -p) a[p]++;
    return;
  }
  int add_calc(int p) {
    int res = 0;
    for (; p; p -= p & -p) res += a[p];
    return res;
  }
} S;
int jd[100005];
vp B;
bool cmpjd(int first, int second) { return B[first] > B[second]; }
vi Mysolve(vp &v) {
  vi X, Y;
  for (auto first : v) {
    X.push_back(2 * first.second - first.first);
    X.push_back(2 * first.first - first.second);
    X.push_back(first.first - 2 * first.second);
    X.push_back(first.second - 2 * first.first);
  }
  sort(X.begin(), X.end());
  int sz = unique(X.begin(), X.end()) - X.begin();
  X.resize(sz);
  vp A;
  B.clear();
  int jds = 0;
  for (auto first : v) {
    int xx = 2 * first.second - first.first,
        yy = 2 * first.first - first.second;
    xx = lower_bound(X.begin(), X.end(), xx) - X.begin() + 1;
    yy = lower_bound(X.begin(), X.end(), yy) - X.begin() + 1;
    A.push_back(pii(xx, yy));
    xx = first.first - 2 * first.second, yy = first.second - 2 * first.first;
    xx = lower_bound(X.begin(), X.end(), xx) - X.begin() + 1;
    yy = lower_bound(X.begin(), X.end(), yy) - X.begin() + 1;
    B.push_back(pii(xx, yy));
    jd[jds] = jds;
    jds++;
  }
  S.init(sz);
  sort(A.begin(), A.end(), greater<pii>());
  sort(jd, jd + jds, cmpjd);
  int cura = 0;
  Y.resize(B.size());
  for (int ii = 0; ii < jds; ii++) {
    int i = jd[ii];
    while (cura < A.size() && A[cura].first >= B[i].first) {
      S.add_upd(sz - A[cura].second + 1);
      cura++;
    }
    int res = S.add_calc(sz - B[i].second + 1);
    Y[i] = res;
  }
  return Y;
}
struct edge {
  int to, w, c;
  edge(int to = 0, int w = 0, int c = 0) : to(to), w(w), c(c) {}
};
int ans = 1;
vector<edge> v[100005];
int node[100005], nodes, pa[100005], sz[100005];
bool del[100005];
int val[100005], r[100005], b[100005];
int bfs(int first) {
  nodes = 0;
  pa[node[++nodes] = first] = 0;
  for (int i = 1; i <= nodes; i++) {
    first = node[i];
    sz[first] = 1;
    for (int j = 0; j < v[first].size(); j++) {
      edge E = v[first][j];
      int second = E.to;
      if (second != pa[first] && !del[second])
        pa[node[++nodes] = second] = first;
    }
  }
  for (int i = nodes; i >= 1; i--) {
    int first = node[i];
    if (sz[first] * 2 >= nodes) return first;
    sz[pa[first]] += sz[first];
  }
  return 0;
}
vp PR;
int tot, id[100005], pw[100005];
void dfs(int k, int p, int col, int w) {
  val[k] = mul(val[p], w);
  r[k] = r[p] + (col == 0);
  b[k] = b[p] + (col == 1);
  id[tot++] = k;
  PR.push_back(pii(r[k], b[k]));
  if (r[k] <= 2 * b[k] && b[k] <= 2 * r[k]) ans = mul(ans, val[k]);
  for (int i = 0; i < v[k].size(); i++) {
    edge E = v[k][i];
    int first = E.to;
    if (first == p || del[first]) continue;
    dfs(first, k, E.c, E.w);
  }
  return;
}
void DFS(int k, int p, int col, int w) {
  PR.push_back(pii(r[k], b[k]));
  for (int i = 0; i < v[k].size(); i++) {
    edge E = v[k][i];
    int first = E.to;
    if (first == p || del[first]) continue;
    DFS(first, k, E.c, E.w);
  }
  return;
}
int expmod(int a, int b, int mod) {
  int res = 1;
  for (; b; b >>= 1) {
    if (b & 1) res = 1ll * res * a % mod;
    a = 1ll * a * a % mod;
  }
  return res;
}
void calc(int k) {
  val[k] = 1;
  r[k] = b[k] = 0;
  tot = 0;
  PR.clear();
  for (int i = 0; i < v[k].size(); i++) {
    edge E = v[k][i];
    int first = E.to;
    if (del[first]) continue;
    dfs(first, k, E.c, E.w);
  }
  for (int i = 0; i < tot; i++) pw[id[i]] = 0;
  vi X = Mysolve(PR);
  for (int i = 0; i < tot; i++) pw[id[i]] += X[i];
  int cur = 0;
  for (int i = 0; i < v[k].size(); i++) {
    PR.clear();
    edge E = v[k][i];
    int first = E.to;
    if (del[first]) continue;
    DFS(first, k, E.c, E.w);
    vi Y = Mysolve(PR);
    for (int ii = 0; ii < PR.size(); ii++) pw[id[cur + ii]] -= Y[ii];
    cur += PR.size();
  }
  for (int i = 0; i < tot; i++)
    assert(pw[id[i]] >= 0), ans = mul(ans, expmod(val[id[i]], pw[id[i]], mod));
}
void solve(int first) {
  int rt = bfs(first);
  del[rt] = 1;
  calc(rt);
  for (int i = 0; i < v[rt].size(); i++)
    if (!del[v[rt][i].to]) solve(v[rt][i].to);
}
void centroid() {
  memset(del, 0, sizeof del);
  solve(1);
  return;
}
int main() {
  scanf("%d", &n);
  for (int i = 1, first, second, z, c; i < n; i++) {
    scanf("%d %d %d %d", &first, &second, &z, &c);
    v[first].push_back(edge(second, z, c));
    v[second].push_back(edge(first, z, c));
  }
  centroid();
  printf("%d\n", ans);
  return 0;
}
