import std.stdio, std.conv, std.string, std.array, std.range, std.algorithm, std.container;
import std.math, std.random, std.bigint, std.datetime, std.format;
import std.typecons;

alias Edge = Tuple!(int, "from", int, "to", long, "cost");

Edge[] edges = new Edge[](0);
int[][] ordg;
int[][] revg;
bool[] isOk;
bool[] isRevOk;

void main() {
	int n = read.to!int;
	int m = read.to!int;
	long p = read.to!long;
	ordg = new int[][](n, 0);
	revg = new int[][](n, 0);
	isOk = new bool[](n);
	isRevOk = new bool[](n);
	foreach (i; 0..m) {
		auto f = read.to!int-1;
		auto t = read.to!int-1;
		edges ~= Edge(f, t, - (read.to!long - p));
		ordg[f] ~= t;
		revg[t] ~= f;
	}
	dfs(0);
	rdfs(n-1);
	long[] d = new long[n];
	fill(d, long.max);
	d[0] = 0;
	int step = 0;
	while(true) {
		bool update = false;
		foreach (i; 0..m) {
			if (! (isOk[edges[i].from] && isRevOk[edges[i].from])) continue;
			if (! (isOk[edges[i].to] && isRevOk[edges[i].to])) continue;
			auto nd = d[edges[i].from] + edges[i].cost;
			if (nd < d[edges[i].to]) {
				update = true;
				d[edges[i].to] = nd;
			}
		}
		step++;
		if (step > n) {
			writeln(-1);
			return;
		}
		if (!update) break;
	}
	auto ret = -d[n-1];
	writeln(max(0, ret));
}

void dfs(int v) {
	if (isOk[v]) return;
	isOk[v] = true;
	foreach (e; ordg[v]) {
		dfs(e);
	}
}

void rdfs(int v) {
	if (isRevOk[v]) return;
	isRevOk[v] = true;
	foreach (e; revg[v]) {
		rdfs(e);
	}
}

string read() {
	static string[] ss;
	while (!ss.length) ss = readln.chomp.split;
	auto res = ss[0];
	ss.popFront;
	return res;
}
