#include <iostream>
#include <fstream>
#include <cmath>
#include <string>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <unordered_set>
#include <bitset>
#include <limits>

using std::string;
using std::cin;
using std::cout;
typedef long long ll;
using std::vector;
template<typename T> void ndarray(vector<T> &vec, int len) { vec.resize(len); }
template<typename T, typename... Args> void ndarray(vector<T> &vec, int len, Args... args) {
    vec.resize(len);
    for (auto &v : vec) ndarray(v, args...);
}

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

enum Status {
    Not = 0,
    Now,
    End,
};

template<typename Edge, typename T>
struct Graph {
    int n;
    vector<vector<Edge>> g;
    vector<T> data;
    vector<Status> s;
    
    Graph(int N) : n(N), g(N+1), data(N+1), s(N+1) {}
    
    void add_edge(int from, Edge e) {
        g[from].push_back(e);
    }
    void set_data(int node, T data) {
        data[node] = data;
    }
    
    //ベルマン-フォード法
    //weightを負を含む距離として最短経路を求める
    //無限ループが存在する場合、trueを1つ目に返す
    std::pair<bool, vector<T>> bellman_ford(int start) {
        T T_INF = std::numeric_limits<T>::max();
        vector<T> d(n+1, T_INF);
        vector<Edge> E;
        for (int i = 0; i <= n; i++) {
            for (auto e: g[i]) {
                E.push_back(e);
            }
        }
        d[start] = 0;
        for (int i = 0; i <= n; i++) {
            for (auto e: E) {
                if (d[e.from] != T_INF && d[e.from] + e.weight < d[e.to]) {
                    //最初or別のstartからe.toへの最短路を発見
                    d[e.to] = d[e.from] + e.weight;
                    //std::cout << "new route find, to: " << e.to << ", distance: " << d[e.to] << std::endl;
                    if (i == n) {
                        //もう全ての辺はチェック済みのはずなのにまだ更新がある：無限ループあり
                        return std::make_pair(true, d);
                    }
                }
            }
        }
        return std::make_pair(false, d);
    }
    
    vector<bool> can_reach_from(int start) {
        vector<bool> reached(n+1, false);
        dfs_reach_from(start, reached);
        return reached;
    }
    void dfs_reach_from(int now, vector<bool> &reached) {
        if (reached[now]) return;
        reached[now] = true;
        for (auto e: g[now]) {
            dfs_reach_from(e.to, reached);
        }
    }
    
    void print() {
        for (auto v: g) {
            for (auto e: v) {
                std::cout << e.from << "-(" << e.weight << ")->" << e.to << ", ";
            }
            std::cout << std::endl;
        }
    }
};

template<typename T>
struct Edge {
    int to;
    int from;
    T weight;
    Edge(int from, int to, T weight) : from(from), to(to), weight(weight) {}
};

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

int main() {
    
    int N, M, P;
    cin >> N >> M >> P;
    
    //1からNまでの経路を考える
    //T*Pを引くのは拾うコインを最初から-Pしておけばいい
    //拾うコインを最大化 = スコアを-1倍にして、最小の経路を探す = 負の距離を含む最小経路問題
    
    //無関係な閉路を検知しないように、ゴールにたどり着けないノードは取り除いておく必要がある
    //逆向きのグラフを作成し、ゴールからそこにたどり着けるかを考えることでこれが実現できる
    //逆に、スタートからたどり着けないところはbellman_fordで探索されないので放置で良い
    
    Graph<Edge<ll>, ll> g(N), g2(N);
    
    for (int i = 0; i < M; i++) {
        int a, b, c;
        cin >> a >> b >> c;
        g.add_edge(b, Edge<ll>(b, a, -1*(c-P)));
    }
    //g.print();
    auto reached = g.can_reach_from(N);
    for (auto v: g.g) {
        for (auto e: v) {
            if (reached[e.to]) {
                g2.add_edge(e.to, Edge<ll>(e.to, e.from, e.weight));
            }
        }
    }
    //g2.print();
    
    auto res = g2.bellman_ford(1);
    if (res.first) {
        cout << -1 << std::endl;
    } else {
        cout << std::max(-1 * res.second[N], 0LL) << std::endl;
    }
    
    return 0;
}



Measured memory_bytes: 896