#include <bits/stdc++.h>
using namespace std;
const int N = 100005;
const int Ns = 400000;
const int inf = 1000 * 1000 * 1000;
const int mod = 1000 * 1000 * 1000 + 7;
int n;
int a[N], b[N], col[N];
long long c[N];
vector<pair<int, int> > g[N];
long long answ = 1ll;
int order[N], parent[N];
bool used[N];
int nn, gag, mn;
void dfs(int v) {
  nn++;
  order[v] = 1;
  for (int i = 0; i < (int)g[v].size(); i++) {
    int to = g[v][i].first;
    if (to == parent[v] || used[to]) continue;
    parent[to] = v;
    dfs(to);
    order[v] += order[to];
  }
}
void dfs1(int v) {
  int T = nn - order[v];
  for (int i = 0; i < (int)g[v].size(); i++) {
    int to = g[v][i].first;
    if (to == parent[v] || used[to]) continue;
    dfs1(to);
    T = max(T, order[to]);
  }
  if (mn == -1 || T < mn) {
    mn = T;
    gag = v;
  }
}
int find_centroid(int v) {
  nn = 0;
  dfs(v);
  mn = -1;
  dfs1(v);
  return gag;
}
struct node {
  int r, b;
  long long x;
};
long long binpow(long long a, long long b) {
  if (b == 0) return 1ll;
  if (b % 2ll) return (a * binpow(a, b - 1)) % mod;
  long long T = binpow(a, b / 2ll);
  return (T * T) % mod;
}
long long inv(long long a) { return binpow(a, mod - 2); }
pair<long long, long long> T[2][Ns + 2];
void build() {
  for (int i = 0; i < 2; i++) {
    for (int j = 0; j <= Ns; j++) {
      T[i][j].first = 1ll;
      T[i][j].second = 0ll;
    }
  }
}
void update(int ind, int pos, long long sz, long long nval) {
  for (; pos <= Ns; pos = (pos | (pos + 1))) {
    T[ind][pos].first *= nval;
    T[ind][pos].first %= mod;
    T[ind][pos].second += sz;
  }
}
long long getsz(int ind, int i) {
  long long answ = 0;
  for (; i >= 0; i = (i & (i + 1)) - 1) {
    answ += T[ind][i].second;
  }
  return answ;
}
long long getval(int ind, int i) {
  long long answ = 1ll;
  for (; i >= 0; i = (i & (i + 1)) - 1) {
    answ *= T[ind][i].first;
    answ %= mod;
  }
  return answ;
}
pair<long long, long long> get(int ind, int l, int r) {
  pair<long long, long long> answ;
  answ.second = getsz(ind, r) - getsz(ind, l - 1);
  answ.first = (getval(ind, r) * inv(getval(ind, l - 1))) % mod;
  return answ;
}
vector<node> G;
void solve(int v, int p, int r, int b, long long val, int ham) {
  if (r == 0 && b == 0) {
    if (ham) {
      update(0, Ns / 2, 1ll, 1ll);
      update(1, Ns / 2, 1ll, 1ll);
    } else {
      update(0, Ns / 2, -1ll, 1ll);
      update(1, Ns / 2, -1ll, 1ll);
    }
  }
  if (r != 0 || b != 0) {
    node T;
    T.x = val;
    T.r = r;
    T.b = b;
    G.push_back(T);
    if (ham) {
      pair<long long, long long> T1 = get(0, 0, 2 * r - b + Ns / 2);
      pair<long long, long long> T2 = get(1, 2 * b - r + Ns / 2 + 1, Ns);
      long long S1 = (T1.first * binpow(val, T1.second)) % mod;
      long long S2 = (T2.first * binpow(val, T2.second)) % mod;
      answ *= S1;
      answ %= mod;
      answ *= inv(S2);
      answ %= mod;
    }
  }
  for (int i = 0; i < (int)g[v].size(); i++) {
    int to = g[v][i].first;
    int ind = g[v][i].second;
    if (used[to] || to == p) continue;
    if (col[ind])
      solve(to, v, r, b + 1, (val * c[ind]) % mod, ham);
    else
      solve(to, v, r + 1, b, (val * c[ind]) % mod, ham);
    if (r == 0 && b == 0) {
      for (int j = 0; j < (int)G.size(); j++) {
        node T = G[j];
        if (ham) {
          update(0, T.b - 2 * T.r + Ns / 2, 1ll, T.x);
          update(1, T.r - 2 * T.b + Ns / 2, 1ll, T.x);
        } else {
          long long n_val = inv(T.x);
          update(0, T.b - 2 * T.r + Ns / 2, -1ll, n_val);
          update(1, T.r - 2 * T.b + Ns / 2, -1ll, n_val);
        }
      }
      G.clear();
    }
  }
}
void centroid_decomposition() {
  queue<int> q;
  q.push(1);
  while (!q.empty()) {
    int v = q.front();
    q.pop();
    int centroid = find_centroid(v);
    solve(centroid, -1, 0, 0, 1ll, 1);
    solve(centroid, -1, 0, 0, 1ll, 0);
    used[centroid] = true;
    int k = 1;
    for (int i = 0; i < (int)g[centroid].size(); i++) {
      int gag = g[centroid][i].first;
      if (used[gag] || gag == parent[centroid]) continue;
      if (order[gag] > 1) q.push(gag);
      k += order[gag];
    }
    if (nn - k > 1) q.push(v);
  }
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i < n; i++) {
    scanf("%d%d%lld%d", &a[i], &b[i], &c[i], &col[i]);
    g[a[i]].push_back(make_pair(b[i], i));
    g[b[i]].push_back(make_pair(a[i], i));
  }
  build();
  dfs(1);
  centroid_decomposition();
  cout << answ << endl;
  return 0;
}
