#include <bits/stdc++.h>
using ll = long long;
using ld = long double;
using namespace std;
const int MAXN = 200001;
const int MOD = 1000 * 1000 * 1000 + 7;
ll ans = 1;
int n;
void mul(ll x) { ans = (ans * x) % MOD; }
ll pw(ll a, ll b) {
  if (b == 0) {
    return 1;
  }
  ll v = pw(a, b / 2);
  v = (v * v) % MOD;
  if (b & 1) v = (v * a) % MOD;
  return v;
}
void div(ll x) { mul(pw(x, MOD - 2)); }
struct Edge {
  int dest;
  int col;
  int x;
  Edge() = default;
  Edge(int dest, int col, int x) : dest(dest), col(col), x(x) {}
};
vector<Edge> e[MAXN];
int dfs1(int v, int p) {
  int sz = 1;
  for (int i = 0; i < e[v].size(); i++) {
    if (e[v][i].dest == p) {
      e[v].erase(e[v].begin() + i);
    }
  }
  for (auto& edge : e[v]) {
    int sz2 = dfs1(edge.dest, v);
    mul(pw(edge.x, ll(sz2) * ll(n - sz2)));
    sz += sz2;
  }
  return sz;
}
ll mmul(ll a, int b) { return (a * b) % MOD; }
class Value {
 public:
  vector<ll> fen;
  vector<int> fencount;
  vector<pair<int, ll>> vals;
  int modifier;
  ll modm;
  int height = 0;
  int capacity = 6;

 private:
  ll getfen(int x) {
    ll v = 1;
    for (int i = x; i >= 0; i = (i & (i + 1)) - 1) v = mmul(v, fen[i]);
    return v;
  }
  int getfencount(int x) {
    int sm = 0;
    for (int i = x; i >= 0; i = (i & (i + 1)) - 1) sm += fencount[i];
    return sm;
  }
  void addfen(int x, ll vl) {
    for (int i = x; i < fen.size(); i = (i | (i + 1))) {
      fencount[i]++;
      fen[i] = mmul(fen[i], vl);
    }
  }
  void makenul() {
    for (auto& val : fen) val = 1;
    for (auto& cn : fencount) cn = 0;
  }
  void rebuild() {
    capacity *= 2;
    fen.resize(capacity * 2 + 1);
    fencount.resize(capacity * 2 + 1);
    makenul();
    upmod();
    for (auto& val : vals) add_nopush(val.first, val.second);
  }
  void add_nopush(int cs, ll x) {
    assert(abs(cs) <= capacity);
    addfen(capacity + cs, x);
  }

 public:
  void upmod() {
    for (auto& val : vals) {
      val.first += modifier;
      val.second = (val.second * modm) % MOD;
    }
    modifier = 0;
    modm = 1;
  }
  void add(int cs, ll x) {
    cs = cs - modifier;
    x = (x * pw(modm, MOD - 2)) % MOD;
    vals.emplace_back(cs, x);
    add_nopush(cs, x);
  }
  void add_edge(int cs, int x) {
    modifier += cs;
    modm = (modm * x) % MOD;
    height += 2;
    if (2 * height > capacity) {
      rebuild();
    }
  }
  void get(int cs, ll val) {
    int lg = capacity - cs - 1 - modifier;
    lg = min(lg, 2 * capacity);
    ll vl = getfen(lg);
    int cn = getfencount(lg);
    div(pw(val, cn));
    div(pw(modm, cn));
    div(vl);
  }
  Value() : modifier(0), modm(1) { rebuild(); }
};
Value* dfs(int v) {
  Value* res;
  if (e[v].empty()) {
    res = new Value();
    res->add(0, 1);
    return res;
  }
  vector<Value*> children;
  for (auto& ed : e[v]) {
    Value* thisV = dfs(ed.dest);
    thisV->add_edge(3 * ed.col - 1, ed.x);
    children.push_back(thisV);
  }
  Value* resV = children[0];
  for (auto val : children) {
    if (val->height > resV->height) {
      resV = val;
    }
  }
  for (auto val : children) {
    if (val == resV) continue;
    val->upmod();
    for (auto& p : val->vals) {
      resV->get(p.first, p.second);
    }
    for (auto& p : val->vals) {
      resV->add(p.first, p.second);
    }
  }
  resV->get(0, 1);
  resV->add(0, 1);
  return resV;
}
int main() {
  ios_base::sync_with_stdio(false);
  cout.setf(ios::fixed);
  cout.precision(20);
  scanf("%d", &n);
  for (int i = 1; i < n; i++) {
    int u, v, col, x;
    scanf("%d%d%d%d", &u, &v, &x, &col);
    e[u].emplace_back(v, col, x);
    e[v].emplace_back(u, col, x);
  }
  dfs1(1, 1);
  dfs(1);
  for (int i = 1; i <= n; i++) {
    for (auto& edge : e[i]) {
      edge.col ^= 1;
    }
  }
  dfs(1);
  cout << ans << endl;
  return 0;
}
