#include #include using namespace std; using LL = long long; using ULL = unsigned long long; #define rep(i,n) for(int i=0; i<(n); i++) struct dsu{ struct Node{ int v, z; }; vector V; dsu(int N){ V.resize(N); rep(i, N) V[i] = { i, 1 }; } int root(int a){ if (V[a].v == a) return a; return V[a].v = root(V[a].v); } int size(int a){ return V[root(a)].z; } void unite(int a, int b){ a = root(a); b = root(b); V[a].z += V[b].z; V[b].v = a; } }; const ULL M = 1000000007; ULL powm(ULL a, ULL i){ if (i == 0) return 1; ULL res = powm(a * a % M, i / 2); if (i % 2 == 1) res = res * a % M; return res; } int N, nE; ULL X; vector> E[200000]; ULL Z[200000]; ULL ans = 0; void dfs(int p, int pre = -1){ Z[p] = 1; for (auto e : E[p]){ if (e.first == pre) continue; dfs(e.first, p); Z[p] += Z[e.first]; ULL tmp = e.second; tmp = tmp * Z[e.first] % M * (N - Z[e.first]) % M; ans += tmp; ans %= M; } } int main(){ cin >> N >> nE; cin >> X; dsu G(N); rep(i, nE){ int u, v; ULL z; cin >> u >> v >> z; u--; v--; if (G.root(u) == G.root(v)) continue; z = powm(X, z); E[u].push_back({ v, z }); E[v].push_back({ u, z }); G.unite(u, v); } dfs(0); cout << ans << endl; return 0; }