#include <bits/stdc++.h>
using namespace std;
struct s {
  int to, x;
  bool c;
} st;
int n, cnt[100005], toa[100005], tob[100005], za, zb, tot, ta, tb, tc, td, te;
vector<s> ne[100005];
long long ans = 1, tf;
bool v[100005];
vector<pair<int, long long> > add;
vector<pair<vector<pair<pair<int, int>, pair<int, int> > >, pair<int, int> > >
    aa;
vector<pair<int, int> > va, vb;
vector<int> ca, cb;
long long po(long long b, int p) {
  long long re = 1;
  while (p) {
    if (p % 2) re = re * b % 1000000007;
    b = b * b % 1000000007;
    p /= 2;
  }
  return re;
}
void aad(vector<pair<pair<int, int>, pair<int, int> > > &a) {
  int at = 0;
  a[0].first.first = a[0].first.first * tf % 1000000007;
  a[0].first.second++;
  for (int i = zb - 1; i >= 0; i--) {
    if (td & (1 << i))
      if (a[at].second.second)
        at = a[at].second.second;
      else {
        at = a[at].second.second = a.size();
        a.push_back(make_pair(make_pair(1, 0), make_pair(0, 0)));
      }
    else if (a[at].second.first)
      at = a[at].second.first;
    else {
      at = a[at].second.first = a.size();
      a.push_back(make_pair(make_pair(1, 0), make_pair(0, 0)));
    }
    a[at].first.first = a[at].first.first * tf % 1000000007;
    a[at].first.second++;
  }
}
void ad() {
  int at = 0;
  aad(aa[0].first);
  for (int i = za - 1; i >= 0; i--) {
    if (tc & (1 << i))
      if (aa[at].second.second)
        at = aa[at].second.second;
      else {
        at = aa[at].second.second = aa.size();
        aa.push_back(
            make_pair(vector<pair<pair<int, int>, pair<int, int> > >(
                          1, make_pair(make_pair(1, 0), make_pair(0, 0))),
                      make_pair(0, 0)));
      }
    else if (aa[at].second.first)
      at = aa[at].second.first;
    else {
      at = aa[at].second.first = aa.size();
      aa.push_back(
          make_pair(vector<pair<pair<int, int>, pair<int, int> > >(
                        1, make_pair(make_pair(1, 0), make_pair(0, 0))),
                    make_pair(0, 0)));
    }
    aad(aa[at].first);
  }
}
void f2(int a, int b, int c, int d,
        vector<pair<pair<int, int>, pair<int, int> > > &e, int f) {
  if (a == c && b == d) {
    ans = ans * e[f].first.first % 1000000007;
    te += e[f].first.second % 1000000007;
    return;
  }
  int mi = (c + d) / 2;
  if (b <= mi) {
    if (e[f].second.first) f2(a, b, c, mi, e, e[f].second.first);
  } else if (a >= mi) {
    if (e[f].second.second) f2(a, b, mi, d, e, e[f].second.second);
  } else {
    if (e[f].second.first) f2(a, mi, c, mi, e, e[f].second.first);
    if (e[f].second.second) f2(mi, b, mi, d, e, e[f].second.second);
  }
}
void f1(int a, int b, int c, int d, int e) {
  if (a == c && b == d) {
    f2(td, 1 << zb, 0, 1 << zb, aa[e].first, 0);
    return;
  }
  int mi = (c + d) / 2;
  if (b <= mi) {
    if (aa[e].second.first) f1(a, b, c, mi, aa[e].second.first);
  } else if (a >= mi) {
    if (aa[e].second.second) f1(a, b, mi, d, aa[e].second.second);
  } else {
    if (aa[e].second.first) f1(a, mi, c, mi, aa[e].second.first);
    if (aa[e].second.second) f1(mi, b, mi, d, aa[e].second.second);
  }
}
int dfs1(int a, int b) {
  int w = 0, re = 1;
  for (int i = 0; i < ne[a].size(); i++)
    if (ne[a][i].to != b && !v[ne[a][i].to]) {
      int ret = dfs1(ne[a][i].to, a);
      re += ret;
      w = max(w, ret);
    }
  w = max(w, tot - re);
  if (w < ta) ta = w, tb = a;
  return re;
}
void dfs2(int a, int b, int c, int d) {
  cnt[a] = 1;
  va.push_back(make_pair(c, a));
  vb.push_back(make_pair(d, a));
  for (int i = 0; i < ne[a].size(); i++)
    if (ne[a][i].to != b && !v[ne[a][i].to]) {
      dfs2(ne[a][i].to, a, c + (ne[a][i].c ? 2 : -1),
           d + (ne[a][i].c ? -1 : 2));
      cnt[a] += cnt[ne[a][i].to];
    }
}
void dfs3(int a, int b, long long c) {
  tc = lower_bound(ca.begin(), ca.end(), -ca[toa[a]]) - ca.begin();
  if (tc != ca.size()) {
    td = lower_bound(cb.begin(), cb.end(), -cb[tob[a]]) - cb.begin();
    if (td != cb.size()) {
      te = 0;
      f1(tc, 1 << za, 0, 1 << za, 0);
      ans = ans * po(c, te) % 1000000007;
    }
  }
  add.push_back(make_pair(a, c));
  for (int i = 0; i < ne[a].size(); i++)
    if (ne[a][i].to != b && !v[ne[a][i].to])
      dfs3(ne[a][i].to, a, c * ne[a][i].x % 1000000007);
}
void go(int a, int b) {
  tot = b;
  ta = INT_MAX;
  dfs1(a, 0);
  int rt = tb;
  dfs2(rt, 0, 0, 0);
  sort(va.begin(), va.end());
  for (int i = 0; i < va.size(); i++) {
    if (ca.empty() || ca.back() != va[i].first) ca.push_back(va[i].first);
    toa[va[i].second] = ca.size() - 1;
  }
  va.clear();
  za = 0;
  while (ca.size() > (1 << za)) za++;
  sort(vb.begin(), vb.end());
  for (int i = 0; i < vb.size(); i++) {
    if (cb.empty() || cb.back() != vb[i].first) cb.push_back(vb[i].first);
    tob[vb[i].second] = cb.size() - 1;
  }
  vb.clear();
  zb = 0;
  while (cb.size() > (1 << zb)) zb++;
  aa = vector<
      pair<vector<pair<pair<int, int>, pair<int, int> > >, pair<int, int> > >(
      1, make_pair(vector<pair<pair<int, int>, pair<int, int> > >(
                       1, make_pair(make_pair(1, 0), make_pair(0, 0))),
                   make_pair(0, 0)));
  tc = toa[rt];
  td = tob[rt];
  tf = 1;
  ad();
  for (int i = 0; i < ne[rt].size(); i++)
    if (!v[ne[rt][i].to]) {
      dfs3(ne[rt][i].to, rt, ne[rt][i].x);
      for (int i = 0; i < add.size(); i++) {
        tc = toa[add[i].first];
        td = tob[add[i].first];
        tf = add[i].second;
        ad();
      }
      add.clear();
    }
  ca.clear();
  cb.clear();
  v[rt] = 1;
  for (int i = 0; i < ne[rt].size(); i++)
    if (!v[ne[rt][i].to]) go(ne[rt][i].to, cnt[ne[rt][i].to]);
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i < n; i++) {
    scanf("%d%d%d%d", &ta, &st.to, &st.x, &tb);
    st.c = tb;
    ne[ta].push_back(st);
    swap(ta, st.to);
    ne[ta].push_back(st);
  }
  go(1, n);
  printf("%lld\n", ans);
  return 0;
}
