#include <bits/stdc++.h>

template<typename T>
class fixed_point : T {
  public:
    explicit constexpr fixed_point (T&& t) noexcept
      : T(std::forward<T>(t)) {}
    template<typename... Args>
    constexpr decltype(auto) operator()(Args&&... args) const
      {return T::operator()(*this, std::forward<Args>(args)...);}
};
template<typename T>
static inline constexpr decltype(auto) fix (T&& t) noexcept {
  return fixed_point<T>{std::forward<T>(t)};
}

template <typename Label>
struct edge
{
  using index_type = int;
  using label_type = Label;

  index_type from;
  index_type to;
  label_type label;

  edge(index_type from, index_type to, label_type label):
    from(from), to(to), label(label)
    {}
};

template <typename Label>
auto std::to_string (const edge<Label>& e) -> std::string
{
  return "edge{"s
    + "from: "  + std::to_string(e.from) + ", "
    + "to: "    + std::to_string(e.to)   + ", "
    + "label: " + std::to_string(e.label)
    + "}";
}

template <typename Label=int>
class graph_base
{
  public:
    using size_type           = int;
    using index_type          = int;
    using label_type          = Label;
    using edge_type           = edge<label_type>;
    using adjacency_list_type = std::vector<std::vector<edge_type>>;
    using edge_list_type      = std::vector<edge_type>;

  private:
    adjacency_list_type         adjacency_list;
    edge_list_type              edge_list;

  public:
    graph_base()=default;
    graph_base(const graph_base&)=default;
    graph_base(graph_base&&)=default;
    graph_base& operator=(const graph_base&)=default;
    graph_base& operator=(graph_base&&)=default;

    graph_base(size_type n) :
      adjacency_list(n),
      edge_list()
      {}

    // Element access
    const auto& at       (index_type i) const {return adjacency_list.at(i);}

    // Iterators
    auto begin           ()             const {return edge_list.begin();}

    auto end             ()             const {return edge_list.end();}

    // Capacity
    auto size            ()             const {return adjacency_list.size();}

    void insert_edge
    (
      index_type from,
      index_type to,
      label_type label = 1
    )
    {
      adjacency_list.at(from).emplace_back(from, to, label);
      edge_list.emplace_back(from, to, label);
    }
};

#define LOCAL
using std::to_string;
auto to_string(std::string s) -> std::string {
  return '"' + s + '"';
}
auto to_string(char c) -> std::string {
  return "'" + std::string{c} + "'";
}
auto to_string(const char* s) -> std::string {
  return to_string((std::string) s);
}
auto to_string(bool b) -> std::string {
  return (b ? "true" : "false");
}
template <typename T, typename U>
auto to_string(std::pair<T, U> p) -> std::string {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}
template <size_t N>
auto to_string(std::bitset<N> bs) -> std::string {
  std::string res{};
  for (size_t i = 0; i < N; i++)
    res.insert(res.begin(), bs.test(i) ? '1' : '0');
  return res;
}
template <typename T>
auto to_string(T v) -> std::string {
  bool flg = false;
  std::string res = "{";
  for (auto const&x : v) {
    if (flg) res += ", ";
    else flg = true;
    res += to_string(x);
  }
  res += "}";
  return res;
}
void debug_out() { std::cerr << std::endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  std::cerr << " " << to_string(H);
  debug_out(T...);
}
#ifdef LOCAL
#define debug(...) std::cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif


template <typename Label>
auto reverse(const graph_base<Label>& graph) -> graph_base<int>
{
  int n = graph.size();
  auto ret = graph_base<int>(n);
  for (auto e : graph)
  {
    ret.insert_edge(e.to, e.from);
  }
  return ret;
}

template <typename Graph>
auto bellman_ford
(
  const Graph&                     graph,
  const typename Graph::index_type start,
  const typename Graph::index_type goal
)
-> std::pair<
  typename Graph::label_type, // dst
  bool                        //  `true` if infinitely near
>
{
  using edge_type          = typename Graph::edge_type;
  using label_type         = typename Graph::label_type;
  using label_vector_type  = std::vector<typename Graph::label_type>;

  constexpr label_type inf = std::numeric_limits<label_type>::max();
  int n                    = graph.size();
  auto reverse_graph       = reverse(graph);

  auto reachable = [&]
  {
    std::vector<int> from_start(n, false);
    fix ([&](auto dfs, int crr) -> void
    {
      from_start.at(crr) = true;
      for (auto const& e : graph.at(crr))
      {
        if (from_start.at(e.to)) continue;
        dfs(e.to);
      }
    })(start);

    std::vector<int> from_goal(n, false);
    fix ([&](auto dfs, int crr) -> void
    {
      from_goal.at(crr) = true;
      for (auto const& e : reverse_graph.at(crr))
      {
        if (from_goal.at(e.to)) continue;
        dfs(e.to);
      }
    })(goal);

    std::vector<int> ret(n);
    for (int i = 0; i < n; i++)
    {
      ret.at(i) = from_start.at(i) && from_goal.at(i);
    }
    return ret;
  }();

  auto dst        = label_vector_type(n, inf);
  dst.at(start)   = 0;
  bool infinitely_near = false;

  auto relax_edge = [&] (edge_type e)
  {
    if (
      dst.at(e.from) != inf
      && reachable.at(e.from)
      && reachable.at(e.to)
      && dst.at(e.from) + e.label < dst.at(e.to))
    {
      dst.at(e.to) = dst.at(e.from) + e.label;
      return true;
    }
    return false;
  };

  for (int i = 0; i < n; i++)
  {
    for (auto e : graph)
    {
      if (relax_edge(e) && i == n - 1)
      {
        return {-inf, true};
      }
    }
  }
  return {dst.at(goal), infinitely_near};
}

int main() {
  std::cin.tie(0); std::cin.sync_with_stdio(false);
  int n, m, p;
  std::cin >> n >> m >> p;
  auto start = 0, goal = n - 1;
  auto graph = graph_base<int>(n);
  for (int i = 0; i < m; i++) {
    int a, b, c;
    std::cin >> a >> b >> c;
    a--, b--;
    graph.insert_edge(a, b, p - c);
  }
  auto pair            = bellman_ford(graph, start, goal);
  auto dst             = pair.first;
  auto infinitely_near = pair.second;
  if (infinitely_near) {
    std::cout << -1 << std::endl;
    return 0;
  }
  std::cout << std::max(0, -dst) << std::endl;
  return 0;
}

Measured memory_bytes: 768