#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn = 1005;
const int maxm = 100005;
const int INF = 0x3f3f3f3f;
int N,M,X;
int first[maxn];
int en;
int d[maxn],d1[maxn];
struct Edge{
int u,v,w;
int next;
void assign(int a,int b,int c,int d){
u = a; v = b; w = c; next = d;
}
bool operator <(const Edge& r)const {
return w > r.w;
}
}edge[maxm];
void Addedge(int a,int b,int c){
int d = first[a];
first[a] = en;
edge[en++].assign(a,b,c,d);
}
void Dijkstra(int x,int n){
priority_queue <Edge> Q;
while(!Q.empty()) Q.pop();
memset(d,0x3f,sizeof(d));
int vis[maxn];
memset(vis,0,sizeof(vis));
Q.push((Edge){x,0,0}); d[x] = 0;
while(!Q.empty()){
Edge e = Q.top() ; Q.pop() ;
int u = e.u;
if(vis[u]) continue;
vis[u] = true;
for(int i=first[u];i!=-1;i=edge[i].next){
int v = edge[i].v;
if( d[v] > d[u] + edge[i].w){
d[v] = d[u] + edge[i].w;
Q.push((Edge){v,0,d[v]});
}
}
}
}
/*
void SPFA(int x,int n){
queue<int> Q;
memset(d,0x3f,sizeof(d));
bool inq[maxn];
memset(inq,0,sizeof(inq));
int cnt[maxn];
memset(cnt,0,sizeof(cnt));
Q.push(x); inq[x] = true; cnt[x]++; d[x] = 0;
while(!Q.empty()){
int u = Q.front() ; Q.pop() ; inq[u] = false;
for(int i=first[u];i!=-1;i=edge[i].next){
int v = edge[i].v; // printf("%d %d \n",v,inq[v]);
if( d[v] > d[u] + edge[i].w){
d[v] = d[u] + edge[i].w; //printf("%d %d %d\n",v,u,d[v]);
if(!inq[v]){
inq[v] = true;
Q.push(v);
cnt[v]++;
}
if(cnt[v] > n) return;
}
}
}
}*/
void init(){
memset(first,-1,sizeof(first));
en = 1;
}
int main()
{
//if(freopen("input.txt","r",stdin)== NULL) {printf("Error\n"); exit(0);}
cin>>N>>M>>X;
int u[maxm],v[maxm],w[maxm];
init();
for(int i=1;i<=M;i++){
cin>>u[i]>>v[i]>>w[i];
Addedge(u[i],v[i],w[i]);
}
//SPFA(X,N);
Dijkstra(X,N);
for(int i=1;i<=N;i++) d1[i] = d[i];
init();
for(int i=1;i<=M;i++){
Addedge(v[i],u[i],w[i]);
}
//SPFA(X,N);
Dijkstra(X,N);
int ans = 0;
for(int i=1;i<=N;i++) ans = max(ans ,d[i] + d1[i]);
printf("%d\n",ans);
}