#include <bits/stdc++.h>
using namespace std;

class Graph
{
public:
    struct Edge
    {
        long long to;
        long long distance;
        Edge(const long long t, const long long d)
        {
            this->to = t;
            this->distance = d;
        }
        bool operator<(const Edge &e) const
        {
            return this->distance < e.distance;
        }
        bool operator<=(const Edge &e) const
        {
            return this->distance <= e.distance;
        }
        bool operator>(const Edge &e) const
        {
            return this->distance > e.distance;
        }
        bool operator>=(const Edge &e) const
        {
            return this->distance >= e.distance;
        }
        bool operator==(const Edge &e) const
        {
            return this->distance == e.distance;
        }
    };
    vector<vector<long long>> adjacency_matrix;
    long long node;
    long long initial_value;
    vector<vector<Edge>> edge;

    Graph(const long long N)
    {
        setNode(N);
        initializeEdgeVector();
    }

    Graph(const long long N, const long long init)
    {
        setNode(N);
        initializeEdgeVector();
        setInitialValue(init);
    }

    void setNode(const long long N)
    {
        this->node = N + 1;
    }

    void setInitialValue(const long long init)
    {
        this->initial_value = init;
    }

    void initializeAdjacencyMatrix()
    {
        this->adjacency_matrix = vector<vector<long long>>(
            this->node, vector<long long>(this->node, this->initial_value));
    }

    void initializeAdjacencyMatrix(const long long init)
    {
        setInitialValue(init);
        initializeAdjacencyMatrix();
    }

    void initializeEdgeVector()
    {
        this->edge = vector<vector<Edge>>(this->node);
    }

    void updateAdjacencyMatrix(const long long from, const long long to, const long long distance = 1)
    {
        this->adjacency_matrix[from][to] = distance;
    }

    void addEdge(const long long from, const long long to, const long long distance = 1)
    {
        this->edge[from].push_back({to, distance});
    }

    // O(V^3)
    // CAUTION: Use adjacency matrix
    vector<vector<long long>> runFloydWarshall() const
    {
        vector<vector<long long>> ret(this->adjacency_matrix);
        for (long long i = 0; i < this->node; i++)
        {
            for (long long j = 0; j < this->node; j++)
            {
                for (long long k = 0; k < this->node; k++)
                {
                    ret[j][k] = min(ret[j][k], ret[j][i] + ret[i][k]);
                }
            }
        }
        return ret;
    }

    // O(E)
    // CAUTION: Non-weighted only
    // CAUTION: Use edge vector
    long long runBFS(const long long from, const long long to) const
    {
        vector<bool> visited(this->node, false);
        visited[from] = true;
        queue<long long> q;
        q.push(from);
        for (long long i = 1; i <= this->node && !q.empty(); i++)
        {
            queue<long long> tmp;
            while (!q.empty())
            {
                for (Edge e : this->edge[q.front()])
                {
                    if (e.to == to)
                    {
                        return i;
                    }
                    if (visited[e.to])
                    {
                        continue;
                    }
                    visited[e.to] = true;
                    tmp.push(e.to);
                }
                q.pop();
            }
            q = tmp;
        }
        return this->initial_value;
    }

    // O(VE)
    // CAUTION: Use edge vector
    vector<long long> runBellmanFord(const long long from) const
    {
        vector<long long> distance(this->node, this->initial_value);
        distance[from] = 0;

        for (long long i = 0; i < this->node - 1; i++)
        {
            for (long long j = 1; j < this->node; j++)
            {
                for (auto itr = this->edge[j].begin(); itr != this->edge[j].end(); itr++)
                {
                    if (distance[itr->to] > distance[j] + itr->distance)
                    {
                        distance[itr->to] = distance[j] + itr->distance;
                    }
                }
            }
        }

        for (long long i = 1; i < this->node; i++)
        {
            for (auto itr = this->edge[i].begin(); itr != this->edge[i].end(); itr++)
            {
                if (distance[itr->to] > distance[i] + itr->distance)
                {
                    distance[0]--;
                }
            }
        }
        return distance;
    }

    vector<bool> runBFSReachable(const long long from) const
    {
        vector<bool> visited(this->node, false);
        visited[from] = true;
        queue<long long> q;
        q.push(from);
        for (long long i = 1; i <= this->node && !q.empty(); i++)
        {
            queue<long long> tmp;
            while (!q.empty())
            {
                for (Edge e : this->edge[q.front()])
                {
                    if (visited[e.to])
                    {
                        continue;
                    }
                    visited[e.to] = true;
                    tmp.push(e.to);
                }
                q.pop();
            }
            q = tmp;
        }
        return visited;
    }

    long long runModifiedBellmanFord(const long long from) const
    {
        vector<long long> distance(this->node, this->initial_value);
        distance[from] = 0;

        for (long long i = 0; i < this->node - 1; i++)
        {
            for (long long j = 1; j < this->node; j++)
            {
                for (auto itr = this->edge[j].begin(); itr != this->edge[j].end(); itr++)
                {
                    if (distance[itr->to] > distance[j] + itr->distance)
                    {
                        distance[itr->to] = distance[j] + itr->distance;
                    }
                }
            }
        }

        vector<long long> ret = distance;
        for (long long i = 0; i < this->node - 1; i++)
        {
            for (long long j = 1; j < this->node; j++)
            {
                for (auto itr = this->edge[j].begin(); itr != this->edge[j].end(); itr++)
                {
                    if (distance[itr->to] > distance[j] + itr->distance)
                    {
                        distance[itr->to] = distance[j] + itr->distance;
                    }
                }
            }
        }

        for (int i = 0; i < this->node; i++)
        {
            if (distance[i] != ret[i])
            {
                return -1;
            }
        }

        return max(0ll, -distance.back());
    }

    // O(E + VlogV)
    // CAUTION: Use edge vector
    vector<long long> runDijkstra(const long long from) const
    {
        vector<long long> distance(this->node, this->initial_value);
        priority_queue<Edge, vector<Edge>, greater<Edge>> queue;
        queue.push(Edge(from, 0));
        while (!queue.empty())
        {
            long long d = queue.top().distance;
            long long to = queue.top().to;
            queue.pop();
            if (distance[to] == this->initial_value)
            {
                distance[to] = d;
                for (auto itr = this->edge[to].begin(); itr != this->edge[to].end(); itr++)
                {
                    if (distance[itr->to] == this->initial_value)
                    {
                        queue.push({itr->to, itr->distance + d});
                    }
                }
            }
        }
        return distance;
    }

    // O(ElogV)
    // CAUTION: Use edge vector
    long long runPrim() const
    {
        vector<bool> is_visited(this->node, false);
        long long cost = 0;
        priority_queue<Edge, vector<Edge>, greater<Edge>> queue;
        queue.push(Edge(1, 0));
        while (!queue.empty())
        {
            long long distance = queue.top().distance;
            long long to = queue.top().to;
            queue.pop();
            if (!is_visited[to])
            {
                cost += distance;
                is_visited[to] = true;
                for (auto itr = this->edge[to].begin(); itr != this->edge[to].end(); itr++)
                {
                    queue.push({itr->to, itr->distance});
                }
            }
        }
        return cost;
    }

    long long runKruskal()
    {
    }
};

int main()
{
    long long N, M, P;
    cin >> N >> M >> P;

    Graph from_one(N, 1e15);
    Graph to_N(N, 1e15);
    vector<long long> A(M);
    vector<long long> B(M);
    vector<long long> C(M);
    for (long long i = 0; i < M; i++)
    {
        cin >> A[i] >> B[i] >> C[i];
        from_one.addEdge(A[i], B[i], C[i]);
        to_N.addEdge(B[i], A[i], C[i]);
    }

    vector<bool> reachable_from_one = from_one.runBFSReachable(1);
    vector<bool> reachable_to_N = to_N.runBFSReachable(N);
    vector<bool> candidate(N + 1, false);

    for (int i = 0; i <= N; i++)
    {
        if (reachable_from_one[i] && reachable_to_N[i])
        {
            candidate[i] = true;
        }
    }

    Graph g(N, 1e15);
    for (int i = 0; i < M; i++)
    {
        if (candidate[A[i]] && candidate[B[i]])
        {
            g.addEdge(A[i], B[i], -(C[i] - P));
        }
    }

    cout << g.runModifiedBellmanFord(1) << endl;
}


Measured memory_bytes: 1024