//蓝桥杯 道路和航路 (SPFA算法求最短路径)
//超时的两组数据
#include<iostream>
#include<cstdio>
#include<string.h>
#include<queue>
using namespace std;
const int N=30000;
const int Inf=100000000;
struct node
{
int to;
int value;
int next;
};
int head[N];
int vis[N];//
int dis[N]={0};//存取距离
int t,r,P,s;
node p[N*6];
void init()
{
memset(head,-1,sizeof(head[0])*(t+2));
memset(vis,0,sizeof(vis[0])*(t+2));
int k=0;
int a,b,c;
for(int i=0;i<r;i++)
{
scanf("%d%d%d",&a,&b,&c);
p[k].to=b;
p[k].value=c;
p[k].next=head[a];
head[a]=k++;
p[k].to=a;
p[k].value=c;
p[k].next=head[b];
head[b]=k++;
}
for(int i=0;i<P;i++)
{
scanf("%d%d%d",&a,&b,&c);
p[k].to=b;
p[k].value=c;
p[k].next=head[a];
head[a]=k++;
}
}
//============关键算法===================
bool relax(int pr,int to,int value)
{
if(dis[to]>dis[pr]+value)
{
dis[to]=dis[pr]+value;
return true;
}
return false;
}
int SPAF(int d)
{
for(int i=0;i<=t;i++)
{
dis[i]=Inf;
}
vis[d]=1;
dis[d]=0;
queue<int> que;
que.push(d);
while(!que.empty())
{
int pre=que.front();
que.pop();
vis[pre]=0;
for(int i=head[pre];i+1;i=p[i].next)
{
if(relax(pre,p[i].to,p[i].value)&&!vis[p[i].to])
{
que.push(p[i].to);
vis[p[i].to]=1;
}
}
}
}
//==========================================
int main()
{
scanf("%d%d%d%d",&t,&r,&P,&s);
init();
SPAF(s);
for(int i=1;i<=t;i++)
{
if(dis[i]==Inf)
{
printf("NO PATH\n");
}
else
{
printf("%d\n",dis[i]);
}
}
return 0;
}