//两个Dijkstra,虽然是多元最短路径,但是不能
//用Floyd,会TLE,模板题
#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxv=1010;
const int maxe=100010;
const int INF=0x3f3f3f3f;
int head[maxv],dis[maxv],cnt,cnt2,head2[maxv];
bool visit[maxv];
struct Edge{
int to,val,next;
}edge[maxe],edge2[maxe];
struct Node{
int u,dis;
bool operator< (const Node rhs) const{
return this->dis>rhs.dis;
}
}now,temp;
void init(){
memset(head,-1,sizeof head);
memset(head2,-1,sizeof head2);
memset(dis,INF,sizeof dis);
}
void addedge(int from,int to,int val){
edge[cnt].to=to;
edge[cnt].val=val;
edge[cnt].next=head[from];
head[from]=cnt++;
}
void addedge2(int from,int to,int val){
edge2[cnt2].to=to;
edge2[cnt2].val=val;
edge2[cnt2].next=head2[from];
head2[from]=cnt2++;
}
void Dijkstra(int s,int head[],Edge edge[],int dist[],bool visit[]) {
int i,v;
dist[s]=0;
priority_queue<Node> pq;
temp.dis=0,temp.u=s;
pq.push(temp);
while(!pq.empty()) {
temp=pq.top();
pq.pop();
if(visit[temp.u]==true)
continue;
visit[temp.u]=true;
for(i=head[temp.u]; i!=-1; i=edge[i].next) {
v=edge[i].to;
if(visit[v]==false&&dist[v]>dist[temp.u]+edge[i].val) {
dist[v]=dist[temp.u]+edge[i].val;
now.u=v;
now.dis=dist[v];
pq.push(now);
}
}
}
}
int main(void) {
#ifndef ONLINE_JUDGE
freopen("E:\\input.txt","r",stdin);
#endif // ONLINE_JUDGE
int v,e,x,ans;
init();
scanf("%d%d%d",&v,&e,&x);
int t1,t2,t3;
for(int i=0;i<e;i++){
scanf("%d%d%d",&t1,&t2,&t3);
addedge(t1,t2,t3);
addedge2(t2,t1,t3);
}
Dijkstra(x,head2,edge2,dis,visit);//去程
int ret[maxv]={0};
for(int i=1;i<=v;i++){
ret[i]+=dis[i];
}
memset(dis,INF,sizeof dis);
memset(visit,false ,sizeof visit);
Dijkstra(x,head,edge,dis,visit);//返程
for(int i=1;i<=v;i++)
ret[i]+=dis[i];
ans=(*max_element(ret+1,ret+v+1));
printf("%d\n",ans);
return 0;
}