#include <bits/stdc++.h>
std::vector<std::vector<std::pair<int, int> > > g;
std::vector<std::pair<std::pair<int, int>, int> > edges;
const int MOD = 1000000007;
const long long INF = 1000000000ll * 1000000000ll;
const int ILE = 2002;
int dp[2005][2005];
int main() {
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(0);
  int n, m, q;
  std::cin >> n >> m >> q;
  g.resize(n);
  for (int i = 0; i < (m); ++i) {
    int a, b, c;
    std::cin >> a >> b >> c;
    a--;
    b--;
    g[a].push_back(std::make_pair(b, c));
    g[b].push_back(std::make_pair(a, c));
    edges.push_back(std::make_pair(std::make_pair(a, b), c));
  }
  for (int i = 0; i < (ILE); ++i)
    for (int j = 0; j < (ILE); ++j) dp[i][j] = -1;
  dp[0][0] = 0;
  for (int k = (1); k < (ILE); ++k) {
    for (int i = 0; i < (n); ++i) {
      for (auto& ch : (g[i])) {
        if (dp[ch.first][k - 1] == -1) continue;
        dp[i][k] = std::max(dp[i][k], dp[ch.first][k - 1] + ch.second);
      }
    }
  }
  std::map<long long, long long> map;
  long long ans = 0;
  for (int k = (1); k < (std::min(q + 1, ILE)); ++k) {
    for (auto& ed : (edges)) {
      long long b = std::max(dp[ed.first.first][k], dp[ed.first.second][k]);
      if (b == -1) continue;
      b -= 1ll * k * ed.second;
      if (map.count(ed.second) == 0) map[ed.second] = -INF;
      map[ed.second] = std::max(map[ed.second], b);
    }
    long long best = 0;
    for (auto& pr : (map)) {
      long long cur = 1ll * pr.first * k + pr.second;
      if (cur > best) best = cur;
    }
    ans = (ans + best) % MOD;
  }
  std::vector<std::pair<long long, long long> > vec;
  auto fun = [&](std::pair<long long, long long> a,
                 std::pair<long long, long long> b,
                 std::pair<long long, long long> c) {
    long long u1 = a.second - c.second;
    long long d1 = c.first - a.first;
    if (d1 < 0) d1 *= -1, u1 *= -1;
    long long u2 = a.second - b.second;
    long long d2 = b.first - a.first;
    if (d2 < 0) d2 *= -1, u2 *= -1;
    return u1 * d2 <= u2 * d1;
  };
  for (auto& pr : (map)) {
    while (((int)(vec).size()) >= 2 &&
           fun(vec[((int)(vec).size()) - 2], vec.back(),
               std::make_pair(pr.first, pr.second))) {
      vec.pop_back();
    }
    vec.push_back(std::make_pair(pr.first, pr.second));
  }
  auto eval = [&](std::pair<long long, long long> f, long long x) {
    __int128_t xd = x;
    __int128_t a = f.first;
    __int128_t b = f.second;
    return xd * a + b;
  };
  std::vector<int> bad(((int)(vec).size()) - 1);
  for (int i = 0; i < (((int)(vec).size()) - 1); ++i) {
    int left = 0;
    int right = q + 2;
    while (left < right) {
      int mid = (left + right) / 2;
      if (eval(vec[i], mid) >= eval(vec[i + 1], mid))
        left = mid + 1;
      else
        right = mid;
    }
    bad[i] = left;
  }
  bad.push_back(q + 1);
  int from = ILE;
  for (int i = 0; i < (((int)(vec).size())); ++i) {
    int upto = bad[i] - 1;
    upto = std::min(upto, q);
    if (from <= upto) {
      long long a = vec[i].first % MOD;
      long long b = vec[i].second % MOD;
      if (b < 0) b += MOD;
      long long il = upto - from + 1;
      ans = (ans + 1ll * il * b) % MOD;
      int cg = (1ll * (from - 1) * il) % MOD;
      cg = (cg + 1ll * il * (il + 1) / 2) % MOD;
      ans = (ans + 1ll * a * cg) % MOD;
    }
    from = std::max(from, upto + 1);
  }
  std::cout << ans << "\n";
  return 0;
}
