#include <algorithm>
#include <array>
#include <cassert>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#define FOR(i,a,b) for (int i=(a),for_##i##_max=(b);i<=(for_##i##_max);++i)
#define RFOR(i,a,b) for (int i=(a),rfor_##i##_min=(b);i>=(rfor_##i##_min);--i)
#define REP(i,n) for (int i=0,rep_##i##_len=(n);i<(rep_##i##_len);++i)
#define RREP(i,n) for (int i=(n)-1;i>=0;--i)

namespace { // Basics

template<typename T>
void chmin(T &x, T y) {
  x = std::min(x, y);
}

template<typename T>
void chmax(T &x, T y) {
  x = std::max(x, y);
}

template<typename T>
__attribute__((unused))
const auto minimum = static_cast<T const &(*)(T const &, T const &)>(std::min);

template<typename T>
__attribute__((unused))
const auto maximum = static_cast<T const &(*)(T const &, T const &)>(std::max);

template<typename T>
__attribute__((unused))
T constexpr infty = std::numeric_limits<T>::max / 3;
template<>
__attribute__((unused))
auto constexpr infty<int> = 1'100'100'100;
template<>
__attribute__((unused))
auto constexpr infty<long long int> = 100'500'400'300'200'100LL;

using lli = long long int;
using ld = long double;

} // namespace

namespace { // Graph Basics

template<typename WeightT>
struct Edge {
  int from, to;
  WeightT weight;
  Edge(int s, int d, WeightT w): from(s), to(d), weight(w) {}
};

template<typename WeightT>
bool
operator< (Edge<WeightT> const &lhs, Edge<WeightT> const &rhs) {
  if (lhs.weight != rhs.weight) {
    return lhs.weight < rhs.weight;
  } else if (lhs.from != rhs.from) {
    return lhs.from < rhs.from;
  }
  return lhs.to < rhs.to;
}

template<typename WeightT>
using Edges = std::vector<Edge<WeightT> >;

template<typename WeightT>
using AdjacencyList = std::vector<Edges<WeightT> >;

template<typename WeightT>
void
add_undir_edge(AdjacencyList<WeightT> &graph, int u, int v, WeightT w) {
  graph[u].emplace_back(u, v, w);
  graph[v].emplace_back(v, u, w);
}

} // namespace

template<typename WeightT>
std::tuple<std::vector<WeightT>, std::vector<size_t> >
bellman_ford(AdjacencyList<WeightT> const &graph, size_t src) {
  auto const n = graph.size();
  auto const INF = infty<WeightT>;
  std::vector<WeightT> dist(n, INF);
  dist[src] = 0;
  std::vector<size_t> prev(n);
  std::iota(begin(prev), end(prev), 0);
  for (size_t cnt = 0; cnt < n; ++cnt) for (auto &&edges : graph) for (auto &&e : edges) {
    if (dist[e.from] < INF && dist[e.to] > dist[e.from] + e.weight) {
      dist[e.to] = dist[e.from] + e.weight;
      prev[e.to] = e.from;
    }
  }
  for (auto &&edges : graph) for (auto &&e : edges) {
    if (dist[e.from] < INF && dist[e.to] > dist[e.from] + e.weight) {
      dist[e.to] = -INF;
      prev[e.to] = e.to;
    }
  }
  return std::make_tuple(dist, prev);
}

std::vector<size_t>
make_path(size_t n, std::vector<size_t> const &prev, size_t src, size_t dst) {
  std::vector<bool> used(n, false);
  std::vector<size_t> res;
  for (size_t v = dst; v != src; v = prev[v]) {
    if (used[v]) { return {}; }
    used[v] = true;
    res.push_back(v);
  }
  std::reverse(begin(res), end(res));
  return res;
}

using namespace std;

using Graph = AdjacencyList<lli>;

void solve(int n, Graph const &g) {
  vector<lli> dist; vector<size_t> prev;
  tie(dist, prev) = bellman_ford(g, 0);
  auto const path = make_path(n, prev, 0, n-1);
  auto const score = -dist[n-1];

  cout << (score == infty<lli> || path.empty() ? -1LL : std::max(0LL, score)) << "\n";
}

int main() {
  // cout << fixed << setprecision(10);

  int N, M, P;
  cin >> N >> M >> P;
  Graph g(N);
  REP(i, M) {
    lli A, B, C;
    cin >> A >> B >> C;
    --A, --B;
    g[A].emplace_back(A, B, P-C);
  }
  solve(N, g);
  return 0;
}


Measured memory_bytes: 512