#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
int T,R,P,S;
const int N = 25010, M = 150010, INF = 0x3f3f3f3f;
int h[N], e[M], ne[M], w[M], idx;
vector<int> blocks[N];
int bid[N], bcnt;
int idu[N];
int dist[N];
bool st[N];
queue<int> q;
void add(int a, int b, int c)
{
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++;
}
void dfs(int u, int bcnt)
{
bid[u] = bcnt;
blocks[bcnt].push_back(u);
for (int i = h[u]; ~i; i = ne[i])
{
int j = e[i];
if (!bid[j])
dfs(j, bcnt);
}
}
void dijkstra(int biid)
{
priority_queue<PII, vector<PII>, greater<PII>> heap;
for (auto i : blocks[biid])
heap.push({dist[i], i});
while (heap.size())
{
PII t = heap.top();
heap.pop();
int ver = t.second, distance = t.first;
if (st[ver]) continue;
st[ver] = true;
for (int i = h[ver]; ~i; i = ne[i])
{
int j = e[i];
if (dist[j] > distance + w[i])
{
dist[j] = distance + w[i];
if (bid[ver] == bid[j])
heap.push({dist[j], j});
}
if (bid[ver] != bid[j] && -- idu[bid[j]] == 0) q.push(bid[j]);
}
}
}
void topsort()
{
memset(dist, 0x3f, sizeof dist);
dist[S] = 0;
for (int i = 1; i <= bcnt; i ++)
if (!idu[i])//入度为0的点加入队列
q.push(i);
while (q.size())
{
int t = q.front();
q.pop();
dijkstra(t);
}
}
int main(void)
{
scanf("%d%d%d%d", &T, &R, &P, &S);
memset(h, -1, sizeof h);
for (int i = 0; i < R; i ++)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
add(a, b, c), add(b, a, c);
}
for (int i = 1; i <= T; i ++)
if (!bid[i])//如果这个i还没有块我们就给这个点i新建一个块放进去
dfs(i, ++ bcnt);
for (int i = 0; i < P; i ++)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
add(a, b, c);
idu[bid[b]] ++;
}
topsort();
for (int i = 1; i <= T; i ++)
{
if (dist[i] >= INF / 2)
printf("NO PATH\n");
else
printf("%d\n", dist[i]);
}
return 0;
}