/*
ID: hedichehaidar
TASK: photo
LANG: C++11
*/
#include<bits/stdc++.h>
//#include"dreaming.h"
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef double db;
ll gcd(ll a , ll b) {return b ? gcd(b , a % b) : a ;} // greatest common divisor (PGCD)
ll lcm(ll a , ll b) {return (a * b) / gcd(a , b);} // least common multiple (PPCM)
#define ss second
#define ff first
#define all(x) (x).begin() , (x).end()
#define pb push_back
#define vi vector<int>
#define vii vector<pair<int,int>>
#define vl vector<ll>
#define vll vector<pair<ll,ll>>
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pdd pair<double,double>
#define vdd vector<pdd>
#define dte tuple<double , double , double>
using namespace std;
const int INF = 1000*1000*1000; // 1 e 9
const int MOD = INF + 7;
const double EPS = 0.000000001; // 1 e -9
const ll inf = (ll)1e18;
int n , l;
vii adj[(int)1e5 + 10];
map<int,int> m[(int)1e5 + 10];
pii down[(int)1e5 + 10];
int top[(int)1e5 + 10];
int dp[(int)1e5 + 10];
bool vis[(int)1e5 + 10];
bool p[(int)1e5 + 10];
int dist[(int)1e5 + 10];
vii v;
vi comp;
void dfs(int pos , int par){
int a = 0 , b = 0;
p[pos] = par;
vis[pos] = true;
for(auto c : adj[pos]){
if(c.ff != par){
dfs(c.ff , pos);
if(c.ss + down[c.ff].ff >= a){
swap(a , b);
a = c.ss + down[c.ff].ff;
}
else b = max(b , down[c.ff].ff + c.ss);
}
}
down[pos] = {a , b};
}
void dfs2(int pos , int par){
vis[pos] = true;
comp.pb(pos);
for(auto c : adj[pos]) if(c.ff != par) dfs2(c.ff , pos);
}
void solve(int pos , int par){
vis[pos] = true;
if(par == -1) top[pos] = 0;
else{
top[pos] = m[pos][par] + top[par];
if(down[par].ff == m[pos][par] + down[pos].ff) top[pos] = max(top[pos] , m[pos][par] + down[par].ss);
else top[pos] = max(m[pos][par] + down[par].ff , top[pos]);
}
for(auto c : adj[pos]) if(c.ff != par) solve(c.ff , pos);
dp[pos] = max(top[pos] , down[pos].ff);
}
int travelTime(int N , int M , int L , int a[] , int b[] , int t[]){
n = N; l = L;
for(int i = 0 ; i < M ; i++){
adj[a[i]].pb({b[i] , t[i]});
adj[b[i]].pb({a[i] , t[i]});
m[a[i]][b[i]] = t[i];
m[b[i]][a[i]] = t[i];
}
for(int i = 0 ; i < n ; i++){
if(!vis[i]) dfs(i , -1);
}
memset(vis , 0 , sizeof vis);
for(int i = 0 ; i < n ; i++){
if(!vis[i]) solve(i , -1);
}
memset(vis , 0 , sizeof vis);
for(int i = 0 ; i < n ; i++){
if(!vis[i]){
dfs2(i , -1);
int mn = 0;
for(int j = 1 ; j < comp.size() ; j++) if(dp[comp[j]] < dp[comp[mn]]) mn = j;
v.pb({dp[comp[mn]] , comp[mn]});
//for(auto c : comp) cout << c << " " << dp[c] << " "; cout << "\n";
comp.clear();
}
}
sort(all(v));
// for(auto c : v) cout << c.ff << " " << c.ss << " "; cout << "\n";
for(int i = 0 ; i < v.size() - 1 ; i++){
adj[v.back().ss].pb({v[i].ss , l});
adj[v[i].ss].pb({v.back().ss , l});
}
queue<int> q;
memset(vis , 0 , sizeof vis);
q.push(0);
vis[0] = true;
while(!q.empty()){
int x = q.front(); q.pop();
for(auto c : adj[x]){
if(!vis[c.ff]) {
dist[c.ff] = dist[x] + c.ss;
vis[c.ff] = true;
q.push(c.ff);
}
}
}
int mx = 0;
for(int i = 1 ; i < n ; i++) if(dist[i] > dist[mx]) mx = i;
q.push(mx);
memset(vis , 0 , sizeof vis);
memset(dist , 0 , sizeof dist);
vis[mx] = true;
while(!q.empty()){
int x = q.front(); q.pop();
for(auto c : adj[x]){
if(!vis[c.ff]) {
dist[c.ff] = dist[x] + c.ss;
vis[c.ff] = true;
q.push(c.ff);
}
}
}
int res = 0;
for(int i = 0 ; i < n ; i++) res = max(res , dist[i]);
// for(int i = 0 ; i < n ; i++) cout << dist[i] << " "; cout << endl;
return res;
}
int main() {
//ifstream fin ("race.in");
//ofstream fout ("race.out");
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int N , M , L ;
int A[(int)1e5 + 10];
int B[(int)1e5 + 10];
int T[(int)1e5 + 10];
cin>>N>>M>>L;
for(int i = 0 ; i < M ; i++) cin>>A[i]>>B[i]>>T[i];
cout << travelTime(N , M , L , A , B , T);
return 0;
}
/*
12
8
2
0 8 4
8 2 2
2 7 4
5 11 3
5 1 7
1 3 1
1 9 5
10 6 3
*/
/*
16
14
5
0 1 1
0 6 4
0 7 3
7 8 6
1 2 6
2 3 5
3 4 4
3 5 5
9 10 2
9 11 3
9 12 5
9 13 1
13 14 1
14 15 10
*/
/*
Think of : BS / DFS / BFS / SSSP / SCC / MSP / MAX FLOW / TOPSORT / LCA / MATRIX / DP(bitmask) / 2 POINTERS / SEG TREE / MATH / UN FIND / MO
Read the statement CAREFULLY !!
Make a GREADY APPROACH !!!! (start from highest / lowest)
Make your own TESTS !!
Be careful from CORNER CASES !
*/
Compilation message
dreaming.cpp: In function 'int travelTime(int, int, int, int*, int*, int*)':
dreaming.cpp:96:31: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
96 | for(int j = 1 ; j < comp.size() ; j++) if(dp[comp[j]] < dp[comp[mn]]) mn = j;
| ~~^~~~~~~~~~~~~
dreaming.cpp:104:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
104 | for(int i = 0 ; i < v.size() - 1 ; i++){
| ~~^~~~~~~~~~~~~~
/usr/bin/ld: /tmp/ccTWRckT.o: in function `main':
dreaming.cpp:(.text.startup+0x0): multiple definition of `main'; /tmp/ccDg66aR.o:grader.c:(.text.startup+0x0): first defined here
/usr/bin/ld: /tmp/ccDg66aR.o: in function `main':
grader.c:(.text.startup+0xd1): undefined reference to `travelTime'
collect2: error: ld returned 1 exit status