#include <bits/stdc++.h>
#define ll long long
#define ii ((i + 1) % k)
using namespace std;
const int N = 1e4 + 10;
const int M = 2e4 + 10;
const int K = 100 + 10;
const int INF = 1e9;
inline int read()
{
int s = 0, w = 1;
char c = getchar();
for ( ; !isdigit(c); c = getchar()) if (c == '-') w = -1;
for ( ; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
return s * w;
}
struct EDGE{
int to;
int pub;
};
struct Node{
int Id;
int val;
bool operator <(const Node a)const{
return a.val < val;
}
};
int n, m, k, u, v, a; vector<EDGE> G[N];
int dis[N][K]; bool vis[N][K];
inline int Wait(int lim, int from)
{
int tmp = (lim - from - 1) / k;
if((lim - from - 1) % k > 0) tmp ++;
return tmp * k;
}
priority_queue<Node> pq;
inline void Dijkstra()
{
for(int i = 1; i <= n; i ++){
for(int j = 0; j < k; j++){
dis[i][j] = INF;
}
}
dis[1][0] = 0;
pq.push({1,dis[1][0]});
while(!pq.empty())
{
int tp = pq.top().Id;
int i = pq.top().val;
pq.pop();
if(vis[tp][i % k] == 1) continue;
vis[tp][i % k] = 1;
for(auto [to, pub] : G[tp]){
int t = (i + 1) % k;
if(i >= pub){
if(dis[to][t] > i + 1){
dis[to][t] = i + 1;
pq.push({to,dis[to][t]});
}
}
else{
int tmp = Wait(pub, i);
if(dis[to][t] > i + 1 + tmp){
dis[to][t] = i + 1 + tmp;
pq.push({to,dis[to][t]});
}
}
}
}
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin>> n >> m >> k;
for(int i = 1; i <= m; i++){
cin>> u >> v >> a;
G[u].push_back({v,a});
}
Dijkstra();
if(dis[n][0] < INF) cout<< dis[n][0] <<"\n";
else cout<<"-1\n";
return 0;
}