#include <bits/stdc++.h>
using namespace std;
struct edge {
  int64_t u, v, w;
};
const int64_t MOD = 1e9 + 7;
struct line {
  int64_t m, n;
  int64_t eval(int64_t first) { return m * first + n; }
  int64_t sum(int64_t a, int64_t b) {
    int64_t r1 = eval(a) + eval(b), r2 = b - a + 1;
    if (r1 & 1)
      r2 /= 2;
    else
      r1 /= 2;
    return ((r1 % MOD) * (r2 % MOD)) % MOD;
  }
  int64_t intersect(const line o) {
    line a = {m - o.m, n - o.n};
    int64_t first = -a.n / a.m;
    int64_t second = a.eval(first);
    if (second == 0) return first;
    if (second > 0) {
      while (second > 0) second -= a.m, --first;
    } else {
      while (second + m < 0) second += a.m, ++first;
    }
    return first;
  }
};
int32_t main() {
  int64_t n, m, q;
  cin >> n >> m >> q;
  vector<vector<pair<int64_t, int64_t>>> g(n);
  vector<edge> edges(m);
  vector<vector<int64_t>> dist(m, vector<int64_t>(n, -1));
  dist[0][0] = 0;
  int64_t res = 0;
  for (auto &e : edges) {
    cin >> e.u >> e.v >> e.w;
    --e.u;
    --e.v;
    g[e.u].push_back({e.v, e.w});
    g[e.v].push_back({e.u, e.w});
    if (e.u == 0) dist[0][e.v] = max(dist[0][e.v], e.w);
    if (e.v == 0) dist[0][e.u] = max(dist[0][e.u], e.w);
  }
  for (auto i = 0; i < n; ++i) res = max(res, dist[0][i]);
  for (auto r = 1; r < m; ++r) {
    for (auto &e : edges) {
      if (dist[r - 1][e.v] != -1)
        dist[r][e.u] = max(dist[r][e.u], dist[r - 1][e.v] + e.w);
      if (dist[r - 1][e.u] != -1)
        dist[r][e.v] = max(dist[r][e.v], dist[r - 1][e.u] + e.w);
    }
    int64_t cur = 0;
    for (auto i = 0; i < n; ++i) cur = max(cur, dist[r][i]);
    res += cur;
  }
  res %= MOD;
  if (q == m) {
    cout << res;
    return 0;
  }
  map<int64_t, int64_t> slops;
  for (auto v = 0; v < n; ++v) {
    int64_t mxe = g[v][0].second;
    for (auto e : g[v]) mxe = max(mxe, e.second);
    if (slops.find(mxe) == slops.end())
      slops[mxe] = dist[m - 1][v] - m * mxe;
    else
      slops[mxe] = max(slops[mxe], dist[m - 1][v] - m * mxe);
  }
  vector<line> ls;
  for (auto &e : slops) ls.push_back({e.first, e.second});
  vector<pair<int64_t, int64_t>> intrs;
  n = ls.size();
  int64_t i = 0;
  for (auto j = 1; j < n; ++j)
    if (ls[j].eval(m + 1) >= ls[i].eval(m + 1)) i = j;
  int64_t first = m + 1;
  while (i < n) {
    int64_t next = q, ni = -1;
    for (auto j = i + 1; j < n; ++j) {
      int64_t xi = ls[j].intersect(ls[i]);
      if (xi <= next) ni = j, next = xi;
    }
    (res += ls[i].sum(first, next) % MOD) %= MOD;
    if (ni == -1)
      break;
    else {
      first = next + 1;
      i = ni;
    }
  }
  cout << res << '\n';
  return 0;
}
