#include<iostream>
#include<vector>
#include<set>
#include<queue>
#include<map>
#include<algorithm>
#include<cstring>
#include<string>
#include<cassert>
#include<cmath>
#include<climits>
#include<iomanip>
#include<stack>
#include<unordered_map>
#include<bitset>
#include<limits>
using namespace std;
#define MOD 1000000007
#define rep(i,m,n) for(int (i)=(int)(m);i<(int)(n);i++)
#define REP(i,n) rep(i,0,n)
#define FOR(i,c) for(decltype((c).begin())i=(c).begin();i!=(c).end();++i)
#define ll long long
typedef pair<ll, ll> P;
const long long INF = 1LL << 60;
const long double EPS = 1e-10;

template<class T> inline bool chmin(T& a, T b) {
	if (a > b) {
		a = b;
		return true;
	}
	return false;
}
template<class T> inline bool chmax(T& a, T b) {
	if (a < b) {
		a = b;
		return true;
	}
	return false;
}
class Edge {
public:
	ll src;
	ll dest;
	ll weight;
	bool rev;
	Edge(ll f, ll t, ll w, bool r)
	{
		src = f;
		dest = t;
		weight = w;
		rev = r;
	}
};
class Vertex {
public:
	ll no;
	ll point;
	ll visitedCnt;
	bool cango;
	vector<Edge> edges;
	Vertex() {
		int i = 0;
	}
	Vertex(ll n, ll p) {
		no = n;
		point = p;
		visitedCnt = 0;
		cango = false;
	}
	bool operator < (const Vertex& v2) const {
		return this->point < v2.point;
	};
};
class Graph {
public:
	ll cost;
	vector<Vertex> vlist;
	map<ll, vector<Edge>> emap;
	vector<Edge> edges;
	Graph(int n) {
		vlist.resize(n);
		REP(i, n) {
			vlist[i].no = -1;
		}
	}
	void addEdge(ll src, ll dest, ll weight, bool rev) {
		if (vlist[src].no < 0) vlist[src] = Vertex(src, 0);
		if (vlist[dest].no < 0) vlist[dest] = Vertex(dest, 0);
		Edge e(src, dest, weight, rev);
		emap[src].push_back(e);
		edges.push_back(e);
	}

	void checkEdge(ll no) {
		if (vlist[no].cango) return;
		vlist[no].cango = true;
		REP(i, emap[no].size()) {
			Edge& e = emap[no][i];
			checkEdge(e.dest);
		}
	}
	ll BellmanFord() {
		vlist[0].point = 0;
		for (int i = 1; i < (int)vlist.size(); i++) {
			vlist[i].point = -INF;
		}
		for (int i = 0; i < (int)vlist.size() - 1; i++) {
			bool updated = false;
			for (int k = 0; k < (int)edges.size(); k++) {
				Edge& e = edges[k];
				Vertex& u = vlist[e.src];
				Vertex& v = vlist[e.dest];
				ll getPoint = u.point + e.weight - cost;
				if (v.point < getPoint) {
					v.point = getPoint;
					updated = true;
				}
			}
			if (!updated) {
				break;
			}
		}

		REP(k, edges.size()) {
			Edge& e = edges[k];
			Vertex& u = vlist[e.src];
			Vertex& v = vlist[e.dest];
			if (v.point == -INF) continue;
			ll pp = u.point + e.weight - cost;
			if (pp > v.point) {
				return -1;
			}
		}

		Vertex& vg = vlist[vlist.size() - 1];
		if (vg.point < 0) return 0;
		return vg.point;
	}
	ll Dijkstra() {
		vlist[0].point = 0;
		vlist[0].visitedCnt = 1;

		priority_queue<Vertex, vector<Vertex>> pq;
		pq.push(vlist[0]);
		while (!pq.empty()) {
			Vertex v = pq.top();
			pq.pop();

			REP(i, v.edges.size()) {
				Edge& e = v.edges[i];
				ll getPoint = v.point + e.weight - cost;
				if (vlist[e.dest].point < getPoint) {
					vlist[e.dest].point = getPoint;
					pq.push(vlist[e.dest]);
				}
			}
		}
		return vlist[vlist.size() - 1].point;
	}
};

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	ll n, m, p;
	cin >> n >> m >> p;
	Graph g(n);
	g.cost = p;
	Graph rg(n);
	rg.cost = p;
	REP(i, m) {
		ll a, b, c;
		cin >> a >> b >> c;
		a--; b--;
		g.addEdge(a, b, c, false);
		rg.addEdge(b, a, c, false);
	}
	g.checkEdge(0);
	rg.checkEdge(n - 1);

	Graph newg(n);
	newg.cost = p;
	REP(i, n) {
		if (!g.vlist[i].cango || !rg.vlist[i].cango) {
			continue;
		}
		REP(k, g.emap[i].size()) {
			newg.addEdge(g.emap[i][k].src, g.emap[i][k].dest, g.emap[i][k].weight, false);
		}
	}
	ll ret = newg.BellmanFord();

	cout << ret << endl;

	return 0;
}


Measured memory_bytes: 2552