#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
vector<pair<int, int> > g[2005];
long long dp[2005][2005];
long long mx[2005];
struct frac {
  long long x, y;
  frac(long long a, long long b) {
    if (b < 0) a = -a, b = -b;
    x = a, y = b;
  }
};
bool operator<=(const frac &a, const frac &b) { return a.x * b.y <= a.y * b.x; }
struct line {
  long long m, c;
  frac intersectX(const line &l) { return frac{c - l.c, l.m - m}; }
};
bool cmp(line a, line b) {
  if (a.m == b.m) return a.c > b.c;
  return a.m < b.m;
}
long long cal2(int l, int r) {
  long long ans = r * 1ll * (r + 1) / 2 % mod;
  ans = (ans - (l - 1) * 1ll * (l) / 2 % mod + mod) % mod;
  return ans;
}
long long cal(line L, int l, int r) {
  long long ans = 0;
  int le = r - l + 1;
  ans = (ans + L.c * 1ll * le) % mod;
  ans = (ans + L.m * cal2(l, r)) % mod;
  return ans;
}
int main() {
  int n, m, q;
  scanf("%d%d%d", &n, &m, &q);
  for (int i = 1; i <= m; i++) {
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);
    g[a].emplace_back(make_pair(b, c));
    g[b].emplace_back(make_pair(a, c));
    mx[a] = max(mx[a], c * 1ll);
    mx[b] = max(mx[b], c * 1ll);
  }
  memset(dp, -1, sizeof(dp));
  dp[1][0] = 0;
  for (int i = 1; i <= m; i++) {
    for (int u = 1; u <= n; u++) {
      if (dp[u][i - 1] == -1) continue;
      for (int j = 0; j < g[u].size(); j++) {
        int v = g[u][j].first, w = g[u][j].second;
        dp[v][i] = max(dp[v][i], dp[u][i - 1] + w);
      }
      dp[u][i] = max(dp[u][i], dp[u][i - 1]);
    }
  }
  long long ans = 0;
  for (int j = 1; j <= m; j++) {
    long long res = 0;
    for (int i = 1; i <= n; i++) {
      res = max(res, dp[i][j]);
    }
    ans = (ans + res) % mod;
  }
  if (m == q) {
    printf("%lld\n", ans);
    return 0;
  }
  vector<line> v, v2, l;
  for (int i = 1; i <= n; i++) {
    long long M = mx[i], C = dp[i][m];
    v.emplace_back(line{M, C});
  }
  sort(v.begin(), v.end(), cmp);
  for (int i = 0; i < v.size(); i++) {
    if (i == 0)
      v2.emplace_back(v[i]);
    else {
      if (v2.back().m == v[i].m) continue;
      v2.emplace_back(v[i]);
    }
  }
  for (int i = 0; i < v2.size(); i++) {
    while (l.size() >= 2 && v2[i].intersectX(l.back()) <=
                                l.back().intersectX(l[(int)l.size() - 2]))
      l.pop_back();
    l.emplace_back(v2[i]);
  }
  int cur = 1;
  q -= m;
  for (int i = 0; i < l.size(); i++) {
    if (i == (int)l.size() - 1) {
      long long r = q;
      if (r < cur) continue;
      long long res = cal(l[i], cur, r);
      ans = (ans + res) % mod;
      cur = r + 1;
    } else {
      frac f = l[i].intersectX(l[i + 1]);
      long long r = min(q * 1ll, f.x / f.y);
      if (r < cur) continue;
      long long res = cal(l[i], cur, r);
      ans = (ans + res) % mod;
      cur = r + 1;
    }
  }
  printf("%lld\n", ans);
}
