#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e3 + 5;
const int mod = 1e9 + 7;
long long dp[maxn][maxn], g[maxn][maxn];
vector<int> gx[maxn];
struct node {
  long long x, y;
  bool operator<(const node& n) const {
    if (y == n.y) return x < n.x;
    return y < n.y;
  }
} a[maxn];
struct nodex {
  int locate, id;
  nodex(int a, int b) {
    locate = a;
    id = b;
  }
};
vector<nodex> s;
int find(int mid) {
  int l = 0, r = s.size() - 1;
  int res;
  while (l <= r) {
    int midx = (l + r) >> 1;
    if (s[midx].locate <= mid) {
      res = s[midx].id;
      l = midx + 1;
    } else
      r = midx - 1;
  }
  return res;
}
long long q_pow(long long a, long long b) {
  long long ans = 1;
  while (b) {
    if (b & 1) ans = ans * a % mod;
    a = a * a % mod;
    b >>= 1;
  }
  return ans;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int n, m, q;
  cin >> n >> m >> q;
  for (int i = 1; i <= m; i++) {
    int x, y;
    long long v;
    cin >> x >> y >> v;
    g[x][y] = max(g[x][y], v);
    g[y][x] = g[x][y];
    gx[x].push_back(y);
    gx[y].push_back(x);
  }
  long long ans = 0;
  memset(dp, -1, sizeof(dp));
  dp[1][0] = 0;
  for (int i = 1; i <= m; i++) {
    long long tmp = 0;
    for (int j = 1; j <= n; j++) {
      for (int l = 0; l < gx[j].size(); l++) {
        int t = gx[j][l];
        if (dp[t][i - 1] != -1)
          dp[j][i] = max(dp[j][i], dp[t][i - 1] + g[t][j]);
      }
      tmp = max(tmp, dp[j][i]);
    }
    if (i <= q) ans = (ans + tmp) % mod;
  }
  if (q - m <= 0) {
    cout << ans << '\n';
    return 0;
  }
  for (int i = 1; i <= n; i++) {
    long long tmp = 0;
    for (int j = 0; j < gx[i].size(); j++) {
      tmp = max(tmp, g[gx[i][j]][i]);
    }
    a[i].x = dp[i][m], a[i].y = tmp;
  }
  sort(a + 1, a + 1 + n);
  s.push_back(nodex(1, 1));
  for (int i = 2; i <= n; i++) {
    long long l = 1, r = q - m;
    int lx = -1;
    while (l <= r) {
      int mid = (l + r) >> 1;
      int idx = find(mid);
      if (a[i].x + a[i].y * mid >= a[idx].x + a[idx].y * mid) {
        lx = mid;
        r = mid - 1;
      } else
        l = mid + 1;
    }
    if (lx == -1) continue;
    while (!s.empty() && s.back().locate >= lx) s.pop_back();
    s.push_back(nodex(lx, i));
  }
  for (int i = 0; i < s.size(); i++) {
    int id = s[i].id;
    long long len;
    if (i == s.size() - 1)
      len = q - m - s[i].locate + 1;
    else
      len = s[i + 1].locate - s[i].locate;
    long long begin = a[id].x + a[id].y * s[i].locate;
    long long end = begin + a[id].y * (len - 1);
    begin %= mod;
    end %= mod;
    ans += ((begin + end) * len % mod) * q_pow(2, mod - 2) % mod;
    ans %= mod;
  }
  cout << ans << '\n';
  return 0;
}
