//{{{
#include<algorithm>
#include<cmath>
#include<deque>
#include<fstream>
#include<iomanip>
#include<iostream>
#include<map>
#include<numeric>
#include<queue>
#include<random>
#include<set>
#include<sstream>
#include<sys/time.h>
#include<unordered_map>
#include<unordered_set>
#include<vector>
using ll = long long;
enum : int { M = (int)1e9 + 7 };
enum : ll { MLL = (ll)1e18L + 9 };
using namespace std;
#ifdef LOCAL
#include"rprint2.hpp"
#else
#define FUNC(name) template <ostream& out = cout, class... T> void name(T&&...){ }
FUNC(printde) FUNC(printdbe) FUNC(printdwe) FUNC(printdu);
#endif
template <template <class T, class = std::allocator<T>> class V, class E>
istream& operator >> (istream& in, V<E>& v){ for(auto& e : v){ in >> e; } return in; }
//}}}

struct Graph{
    struct Edge{
        int cost, from, dest;
        Edge(int cost, int dest): cost(cost), from(-1), dest(dest){ }
        Edge(int cost, int from, int dest): cost(cost), from(from), dest(dest){ }
        // bool operator == (const Edge& e) const { return cost == e.cost; }
        // bool operator < (const Edge& e) const { return cost < e.cost; }
        // bool operator == (const Edge& e) const { return from == e.from && dest == e.dest; }
        ostream& operator >> (ostream& out) const {
            return out << '(' << cost << ':' << from << ' ' << dest << ')';
        }
    };
    struct Node{
        vector<Edge> edges;
    };
    vector<Node> nodes;
    Graph(int num): nodes(num){ }
    int id(Node* n){ return n - &nodes[0]; }
    int id(Node& n){ return &n - &nodes[0]; }
    // void print(){ for(auto& node : nodes){ prints(id(node), node.outEdges); } }
    void add1Edge(int from, int dest, int cost = 1){
        nodes[from].edges.emplace_back(cost, dest);
    }
    void add2Edge2(int from, int dest, int cost = 1){
        add1Edge(from, dest, cost);
        add1Edge(dest, from, cost);
    }
    void dfs(int idx, unordered_set<int>& reachable){
        reachable.insert(idx);
        for(auto e : nodes[idx].edges){
            if(reachable.count(e.dest)){ continue; }
            dfs(e.dest, reachable);
        }
    }
};

struct Edge {
    int from, to, cost;
};
bool bellmanFord(vector<ll>& dists, vector<Edge>& edges, int start = 0){
    int n = dists.size();
    dists[start] = 0;
    for(int i = 0; i < n; i++){
        for(Edge edge : edges){
            if(dists[edge.from] != MLL && dists[edge.from] + edge.cost < dists[edge.to]){
                printde(i, edge.from, edge.to, dists[edge.to]);
                if(i == n - 1){ return false; }
                dists[edge.to] = dists[edge.from] + edge.cost;
            }
        }
    }
    return true;
}

int main(){
    cin.tie(0); ios::sync_with_stdio(false);
    int n, m, p;
    cin >> n >> m >> p;
    Graph g(n);
    vector<int> as(m), bs(m), cs(m);
    for(int i = 0; i < m; i++){
        int a, b, c;
        cin >> a >> b >> c;
        a--; b--;
        c -= p;
        as[i] = a; bs[i] = b; cs[i] = - c;
        g.add1Edge(b, a, c);
    }
    unordered_set<int> reachable;
    g.dfs(n - 1, reachable);
    vector<Edge> edges;
    for(int i = 0; i < m; i++){
        if(!reachable.count(as[i]) || !reachable.count(bs[i])){ continue; }
        edges.push_back({as[i], bs[i], cs[i]});
    }
    vector<ll> dists(n, MLL);
    bool limited = bellmanFord(dists, edges, 0);
    printde(dists);
    if(!limited){
        cout << -1 << '\n';
    }else{
        cout << max(0ll, - dists[n - 1]) << '\n';
    }
}


Measured memory_bytes: 768