#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
const int mod = 1e9 + 7;
const int LOG = 17;
inline long long mul(long long a, long long b) { return (a * b) % mod; }
long long binpow(long long a, int n) {
  if (n == 0) return 1;
  long long t = binpow(a, n / 2);
  t = mul(t, t);
  if (n & 1) t = mul(t, a);
  return t;
}
inline long long rev(long long a) { return binpow(a, mod - 2); }
struct Edge {
  enum { RED, BLACK };
  int to, x, c;
  Edge(int to, int x, int c) : to(to), x(x), c(c) {}
};
struct Fenwick {
 private:
  int size;
  int ORIGIN;
  int cnt[4 * N];
  long long pro[4 * N];
  void adddd(int i, long long x) {
    for (; i < size; i |= (i + 1)) {
      cnt[i]++;
      pro[i] = mul(pro[i], x);
    }
  }
  int cntPrefix(int r) {
    int res = 0;
    for (; r >= 0; r = (r & (r + 1)) - 1) {
      res += cnt[r];
    }
    return res;
  }
  int cntSuffix(int l) { return cntPrefix(size - 1) - cntPrefix(l - 1); }
  long long prefix(int r) {
    long long res = 1;
    for (; r >= 0; r = (r & (r + 1)) - 1) {
      res = mul(res, pro[r]);
    }
    return res;
  }
  long long suffix(int l) { return mul(prefix(size - 1), rev(prefix(l - 1))); }

 public:
  void init(int sz) {
    size = 4 * sz;
    size = min(size, 4 * N);
    ORIGIN = size / 2;
    for (int i = 0; i < size; ++i) {
      cnt[i] = 0;
      pro[i] = 1;
    }
  }
  long long suf(int l) { return suffix(l + ORIGIN); }
  long long pre(int r) { return prefix(r + ORIGIN); }
  int sufcnt(int l) { return cntSuffix(l + ORIGIN); }
  int precnt(int r) { return cntPrefix(r + ORIGIN); }
  void add(int i, long long x) { adddd(i + ORIGIN, x); }
} pos, neg;
vector<Edge> g[N];
int level[N];
int dfsFind(int v, int size, int &center, int p = -1) {
  int sum = 1;
  if (center != -1) return sum;
  for (const auto &e : g[v]) {
    if (e.to == p || level[e.to] != -1) continue;
    sum += dfsFind(e.to, size, center, v);
    if (center != -1) break;
    if (2 * sum >= size) {
      center = v;
      return sum;
    }
  }
  if (center == -1 && p == -1) {
    center = v;
  }
  return sum;
}
void centroidBuild(int v, int size, int lvl) {
  int center = -1;
  dfsFind(v, size, center);
  level[center] = lvl;
  for (const auto &e : g[center]) {
    if (level[e.to] == -1) {
      centroidBuild(e.to, size / 2, lvl + 1);
    }
  }
}
void dfsSol(int v, int p, int lvl, int r, int b, Fenwick &pos, Fenwick &neg,
            int w, long long &po, long long &ne) {
  po = mul(po, mul(pos.pre(2 * r - b), binpow(w, pos.precnt(2 * r - b))));
  ne = mul(ne,
           mul(neg.suf(2 * b - r + 1), binpow(w, neg.sufcnt(2 * b - r + 1))));
  if (2 * min(r, b) >= max(r, b)) {
    po = mul(po, w);
  }
  for (const auto &e : g[v]) {
    if (level[e.to] <= lvl || p == e.to) continue;
    dfsSol(e.to, v, lvl, r + (e.c == Edge::RED), b + (e.c == Edge::BLACK), pos,
           neg, mul(w, e.x), po, ne);
  }
}
void dfsUpd(int v, int p, int lvl, int r, int b, Fenwick &pos, Fenwick &neg,
            long long w) {
  pos.add(b - 2 * r, w);
  neg.add(r - 2 * b, w);
  for (const auto &e : g[v]) {
    if (level[e.to] <= lvl || p == e.to) continue;
    dfsUpd(e.to, v, lvl, r + (e.c == Edge::RED), b + (e.c == Edge::BLACK), pos,
           neg, mul(w, e.x));
  }
}
int sizeCentroid(int v, int lvl, int p = -1) {
  int res = 1;
  for (const auto &e : g[v]) {
    if (level[e.to] <= lvl || e.to == p) continue;
    res += sizeCentroid(e.to, lvl, v);
  }
  return res;
}
void solCentroid(int v, long long &po, long long &ne) {
  int sz = sizeCentroid(v, level[v]);
  pos.init(sz);
  neg.init(sz);
  for (const auto &e : g[v]) {
    if (level[e.to] <= level[v]) continue;
    dfsSol(e.to, v, level[v], e.c == Edge::RED, e.c == Edge::BLACK, pos, neg,
           e.x, po, ne);
    dfsUpd(e.to, v, level[v], e.c == Edge::RED, e.c == Edge::BLACK, pos, neg,
           e.x);
  }
}
void solve() {
  int n;
  scanf("%d", &n);
  for (int i = 1, a, b, x, c; i < n; ++i) {
    scanf("%d%d%d%d", &a, &b, &x, &c);
    --a, --b;
    g[a].push_back(Edge(b, x, c));
    g[b].push_back(Edge(a, x, c));
  }
  for (int i = 0; i < n; ++i) {
    level[i] = -1;
  }
  centroidBuild(0, n, 0);
  long long po = 1, ne = 1;
  for (int v = 0; v < n; ++v) {
    solCentroid(v, po, ne);
  }
  printf("%d\n", int(mul(po, rev(ne))));
}
int main() {
  solve();
  return 0;
}
