#include using namespace std; const long long MOD = 1000000007; struct unionfind{ vector p; vector sz; unionfind(int N): p(vector(N, -1)), sz(vector(N, 1)){ }; int root(int x){ if (p[x] == -1){ return x; } else { p[x] = root(p[x]); return p[x]; } } bool same(int x, int y){ return root(x) == root(y); } void unite(int x, int y){ x = root(x); y = root(y); if (x != y){ p[x] = y; sz[y] += sz[x]; } } int size(int x){ return sz[root(x)]; } }; long long modpow(long long a, long long b){ long long ans = 1; while (b > 0){ if (b % 2 == 1){ ans *= a; ans %= MOD; } a *= a; a %= MOD; b /= 2; } return ans; } int dfs(vector> &c, vector &dp, int v = 0){ for (int w : c[v]){ dp[v] += dfs(c, dp, w); } return dp[v]; } int main(){ int N, M, X; cin >> N >> M >> X; vector x(M), y(M), z(M); for (int i = 0; i < M; i++){ cin >> x[i] >> y[i] >> z[i]; x[i]--; y[i]--; } unionfind UF(N); vector>> E(N); for (int i = 0; i < M; i++){ if (!UF.same(x[i], y[i])){ UF.unite(x[i], y[i]); long long c = modpow(X, z[i]); E[x[i]].push_back(make_pair(c, y[i])); E[y[i]].push_back(make_pair(c, x[i])); } } vector p(N, -1); vector d(N, 0); vector> c(N); queue Q; Q.push(0); while (!Q.empty()){ int v = Q.front(); Q.pop(); for (auto P : E[v]){ int w = P.second; if (w != p[v]){ p[w] = v; d[w] = P.first; c[v].push_back(w); Q.push(w); } } } vector dp(N, 1); dfs(c, dp); long long ans = 0; for (int i = 1; i < N; i++){ ans += d[i] * dp[i] % MOD * (N - dp[i]) % MOD; ans %= MOD; } cout << ans << endl; }