// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;

#define rep(i, a) for(int i=0; i<(int)(a); i++)

typedef long long ll;

const ll mod = 1000000007;

const ll INF = 1LL<<60;



struct edge {

  int from, to, cost;

};



vector<edge> es;

vector<vector<int>> g1(2510);

vector<vector<int>> gn(2510);

vector<bool> r1(2510, false);

vector<bool> rn(2510, false);



void dfs(int s)

{

  if (r1[s]) return;

  r1[s] = true;

  for (auto v:g1[s]) dfs(v);

}



void rdfs(int s)

{

  if (rn[s]) return;

  rn[s] = true;

  for (auto v:gn[s]) rdfs(v);

}



int main()

{

  int n, m, p; cin >> n >> m >> p;

  rep(i, m) {

    int a, b, c; cin >> a >> b >> c;

    a--; b--;

    es.push_back(edge{a, b, p-c});

    g1[a].push_back(b);

    gn[b].push_back(a);

  }

  dfs(0);

  rdfs(n-1);



  if (!(r1[n-1]&&rn[0])) {

    cout << -1 << endl;

    return 0;

  }



  vector<ll> d(n, INF);

  d[0] = 0;

  bool upd = true;

  int step = 0;

  while (upd) {

    upd = false;

    for (int j=0; j<(int)(es.size()); j++) {

      edge e = es[j];

      if (!(r1[e.from]&&rn[e.from]) || !(r1[e.to]&&rn[e.to])) continue;

      if (d[e.from] == INF) continue;

      if (d[e.to] > d[e.from]+e.cost) {

        upd = true;

        d[e.to] = min(d[e.to], d[e.from]+e.cost);

      }

    }

    step++;

    if (step > n) {

      cout << -1 << endl;

      return 0;

    }

  }



  cout << max(0LL, -d[n-1]) << endl;



  return 0;

}


// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std;

#define rep(i, a) for(int i=0; i<(a); i++)

typedef long long ll;

template<typename T>

struct edge {

  int src, to;

  T cost;

  edge(int to, T cost) : src(-1), to(to), cost(cost) {}

  edge(int src, int to, T cost) : src(src), to(to), cost(cost) {}

  edge &operator=(const int &x) {

    to = x;

    return *this;

  }

  operator int() const { return to; }

};

template<typename T>

using Edges = vector<edge<T>>;

template<typename T>

using WeightedGraph = vector<Edges<T>>;

using UnWeightedGraph = vector<vector<int>>;

template<typename T>

using Matrix = vector<vector<T>>;



/////////////////////////////////////////////////////////////////////

const ll inf = 1LL<<60;



template<typename T>

struct Bellman {

  int n;

  Edges<T> es;

  vector<T> dist;

  vector<int> prev;

  UnWeightedGraph g1;

  UnWeightedGraph g2;

  vector<bool> r1;

  vector<bool> r2;

  bool is_negative = false;

  Bellman(int _n, Edges<T> _es) {

    init(_n, _es);

  }

  void init(int _n, Edges<T> _es) {

    n = _n; es = _es;

  }

  void reset() {

    dist.assign(n, inf);

    prev.assign(n, -1);

    is_negative = false;

  }

  void run(int s) {

    reset();

    dist[s] = 0;

    bool upd = true;

    int step = 0;

    while (upd) {

      upd = false;

      for (int i=0; i<(int)es.size(); i++) {

        edge<T> e = es[i];

        if (dist[e.src] == inf) continue;

        if (dist[e.to] > dist[e.src] + e.cost) {

          dist[e.to] = dist[e.src] + e.cost;

          prev[e.to] = e.src;

          upd = true;

        }

      }

      step++;

      if (step > n) {

        is_negative = true;

        return;

      }

    }

  }

  vector<int> getpath(int t) {

    vector<int> path;

    for (; t!=-1; t=prev[t]) path.push_back(t);

    return path;

  }

  void dfs(int s) { if (r1[s]) return; r1[s] = true; for (auto v:g1[s]) dfs(v); }

  void rdfs(int s) { if (r2[s]) return; r2[s] = true; for (auto v:g2[s]) rdfs(v); }

  void remove_unneccessary_edges(int s, int t) {

    g1.assign(n, vector<int>()); g2.assign(n, vector<int>());

    r1.assign(n, false); r2.assign(n, false);

    for (auto e:es) {

      g1[e.src].push_back(e.to);

      g2[e.to].push_back(e.src);

    }

    dfs(s); rdfs(t);

    Edges<T> new_es;

    for (auto e:es) {

      if (!(r1[e.src]&&r2[e.src]) || !(r1[e.to]&&r2[e.to])) continue;

      new_es.push_back(e);

    }

    es = new_es;

  }

};



int main()

{

  ll n,m,p; cin>>n>>m>>p;

  Edges<ll> es;

  rep(i, m) {

    int a,b; ll c;

    cin>>a>>b>>c;

    a--; b--;

    es.push_back(edge<ll>{a,b,p-c});

  }

  Bellman<ll> bl(n, es);

  bl.remove_unneccessary_edges(0, n-1);

  bl.run(0);

  if (bl.is_negative) {

    cout << -1 << endl;

    return 0;

  }

  cout << max(0LL, -bl.dist[n-1]) << endl;



  return 0;

}


// Fastest known solution for this problem: