#include <bits/stdc++.h>
using namespace std;
template <typename T>
using MinHeap = priority_queue<T, vector<T>, greater<T>>;
template <typename T>
using MaxHeap = priority_queue<T>;
const long double PI = 3.14159265358979323846;
const long double E = 2.718281828459;
const long long SIZE = 2e6 + 3;
const long long MOD = 1e9 + 7;
long long myMod(long long n) { return (n % MOD + MOD) % MOD; }
long long mul(long long a, long long b) {
  return ((a % MOD) * (b % MOD)) % MOD;
}
long long plu(long long a, long long b) { return (a % MOD + b % MOD) % MOD; }
long long ans;
void calc(long long start, long long len, long long w, long long o) {
  ;
  long long base = o + (start - 2000) * w;
  base %= MOD;
  base = mul(len, base);
  long long addition = mul(len * (len + 1) / 2, w);
  ;
  ans = plu(ans, plu(base, addition));
}
int main(int argn, char** argv) {
  ios::sync_with_stdio(false);
  cout.tie(nullptr);
  cin.tie(nullptr);
  int T = 1;
  for (long long(I) = (0); (I) <= ((T)-1); (I)++) {
    long long n, m, q;
    cin >> n >> m >> q;
    vector<tuple<long long, long long, long long>> edges;
    for (long long(i) = (0); (i) <= ((m)-1); (i)++) {
      long long u, v, w;
      cin >> u >> v >> w;
      edges.emplace_back(u, v, w);
    }
    vector<vector<long long>> dp(2002, vector<long long>(n + 2, -9e9));
    dp[0][1] = 0;
    for (long long(i) = (1); (i) <= (2000); (i)++) {
      for (auto& [u, v, w] : edges) {
        dp[i][u] = max(dp[i][u], dp[i - 1][v] + w);
        dp[i][v] = max(dp[i][v], dp[i - 1][u] + w);
      }
    }
    ans = 0;
    for (long long(i) = (1); (i) <= (min(q, 2000ll)); (i)++) {
      long long mx = 0;
      for (long long(node) = (1); (node) <= (n); (node)++)
        mx = max(mx, dp[i][node]);
      ans = plu(ans, mx);
    }
    vector<pair<long long, long long>> cycle;
    for (auto& [u, v, w] : edges) {
      long long offset = max(dp[2000][u], dp[2000][v]);
      cycle.emplace_back(w, offset);
    }
    sort((cycle).begin(), (cycle).end());
    long long idx = 0, last = 2000;
    while (idx < m - 1 && last < q) {
      auto [w1, o1] = cycle[idx];
      ;
      long long pos = -1, minTime = 2e9;
      for (long long(nxt) = (idx + 1); (nxt) <= (m - 1); (nxt)++) {
        auto [w2, o2] = cycle[nxt];
        ;
        if (w1 == w2 || o1 <= o2) {
          pos = nxt;
          minTime = last;
          break;
        }
        long long delta = (o1 - o2) / (w2 - w1);
        long long time = delta + 2000;
        if (time <= minTime) {
          pos = nxt;
          minTime = time;
        }
        if (minTime <= last) break;
      }
      if (minTime > last) {
        minTime = min(minTime, q);
        calc(last, minTime - last, w1, o1);
        last = minTime;
      }
      idx = pos;
    }
    if (idx == m - 1 && last < q) {
      auto [w, o] = cycle[idx];
      calc(last, q - last, w, o);
    };
    cout << ans << endl;
  }
  return 0;
}
