#include using namespace std; #define rep(i,n) for(int i = 0; i < (n);i++) #define sz(x) int(x.size()) typedef long long ll; typedef long double ld; typedef pair P; typedef tuple TP; constexpr int mod = 1e9+7; struct mint { ll x; // typedef long long ll; mint(ll x=0):x((x%mod+mod)%mod){} mint operator-() const { return mint(-x);} mint& operator+=(const mint a) { if ((x += a.x) >= mod) x -= mod; return *this; } mint& operator-=(const mint a) { if ((x += mod-a.x) >= mod) x -= mod; return *this; } mint& operator*=(const mint a) { (x *= a.x) %= mod; return *this;} mint operator+(const mint a) const { return mint(*this) += a;} mint operator-(const mint a) const { return mint(*this) -= a;} mint operator*(const mint a) const { return mint(*this) *= a;} mint pow(ll t) const { if (!t) return 1; mint a = pow(t>>1); a *= a; if (t&1) a *= *this; return a; } // for prime mod mint inv() const { return pow(mod-2);} mint& operator/=(const mint a) { return *this *= a.inv();} mint operator/(const mint a) const { return mint(*this) /= a;} }; struct UnionFind{ vector data; int __size; UnionFind(int sz) { data.assign(sz, -1); __size = sz; } bool unite(int x, int y) { x = find(x), y = find(y); if(x == y) return (false); if(data[x] > data[y]) swap(x, y);//親は負でサイズを保存 __size--; data[x] += data[y]; data[y] = x; return (true); } int find(int k) { if(data[k] < 0) return (k); return (data[k] = find(data[k])); } bool same(int x, int y){ return find(x) == find(y); } int size(int k) { return (-data[find(k)]); } int union_count() { return (__size); } }; int main() { int n, m, x; cin >> n >> m >> x; UnionFind uf(n); vector edge; rep(i,m) { int x, y, z; cin >> x >> y >> z; x--; y--; edge.emplace_back(make_tuple(z, x, y)); } sort(edge.begin(), edge.end()); vector> g(n); vector mst; for (int i = 0; i < m; i++) { int u, v, c; tie(c, u, v) = edge[i]; if (uf.same(u, v)) continue; uf.unite(u, v); mst.emplace_back(edge[i]); g[u].emplace_back(v); g[v].emplace_back(u); } vector dp(n, 0); mint res = 0; auto dfs = [&](auto& f, int u = 0, int p = -1)->void{ dp[u] = 1; for (auto v : g[u]) { if (v == p) continue; f(f, v, u); dp[u] += dp[v]; } }; dfs(dfs); for (auto e : mst) { int u, v, c; tie(c, u, v) = e; mint cost = mint(x).pow(c); int cnt = min(dp[u], dp[v]); res += cost * cnt * (n - cnt); } cout << res.x << endl; return 0; }