7 9 999999999 0 3
0 1 0
1 2 0
2 3 0
0 4 1
4 1 1
1 5 499999999
5 2 499999999
2 6 1
6 3 1
 7 9 320 0 3
0 1 0
1 2 0
2 3 0
0 4 1
4 1 1
1 5 100
5 2 100
2 6 59
6 3 61
 4 5 7 0 3
0 1 0
1 2 3
2 3 0
0 2 5
1 3 5
 8 9 10 1 0
1 2 1
2 4 1
1 3 0
3 4 0
4 5 0
5 6 1
6 0 1
5 7 0
7 0 0
 4 4 14 1 3
1 3 13
2 3 0
2 0 0
1 0 12
 5 6 1000000000 0 4
0 1 1
2 0 2
3 0 3
4 1 0
4 2 0
3 4 0
 4 5 10 1 2
0 1 3
1 2 0
1 3 4
2 3 4
2 0 6
 4 4 2 1 3
1 3 13
2 3 0
2 0 0
1 0 0
 5 5 2 0 2
0 1 1
1 2 1
0 4 0
4 3 0
3 2 0
 5 5 3 0 2
0 1 1
1 2 1
0 4 0
4 3 0
3 2 0
 4 4 8 1 3
1 3 13
2 3 0
2 0 0
1 0 6
 1000 1 1000000000 998 0
0 999 0
 5 5 1 0 2
0 1 1
1 2 1
0 4 0
4 3 0
3 2 0
 100 1 123456 99 0
0 99 123456
 4 4 13 1 3
1 3 13
2 3 0
2 0 0
1 0 12
 7 9 319 0 3
0 1 0
1 2 0
2 3 0
0 4 1
4 1 1
1 5 100
5 2 100
2 6 59
6 3 61
 1000 1 5 999 0
0 999 0

YES
0 1 1
1 2 999999996
2 3 999999997
0 4 1
4 1 1
1 5 499999999
5 2 499999999
2 6 1
6 3 1
 YES
0 1 1
1 2 199
2 3 318
0 4 1
4 1 1
1 5 100
5 2 100
2 6 59
6 3 61
 YES
0 1 3
1 2 3
2 3 2
0 2 5
1 3 5
 YES
1 2 1
2 4 1
1 3 1
3 4 1
4 5 6
5 6 1
6 0 1
5 7 1
7 0 1
 NO YES
0 1 1
2 0 2
3 0 3
4 1 999999999
4 2 999999998
3 4 999999997
 NO NO YES
0 1 1
1 2 1
0 4 1
4 3 1
3 2 1
 NO YES
1 3 13
2 3 1
2 0 1
1 0 6
 NO NO YES
0 99 123456
 YES
1 3 13
2 3 1
2 0 1
1 0 12
 YES
0 1 1
1 2 198
2 3 317
0 4 1
4 1 1
1 5 100
5 2 100
2 6 59
6 3 61
 YES
0 999 5

#include <bits/stdc++.h>
using namespace std;
struct edge {
  int u, v;
  int w;
  int other(int node) { return (u == node) ? v : u; }
};
int n, m, second, e;
int used[1003], parent[1003];
edge E[10004];
int dis[1003];
int L;
vector<int> g[1003];
void djkstra(int second, int e) {
  priority_queue<pair<int, int>, vector<pair<int, int> >,
                 greater<pair<int, int> > >
      Q;
  for (int i = 0; i < n; i++) {
    dis[i] = (2000000000 >> 1) + 1;
    used[i] = 0;
  }
  dis[second] = 0;
  Q.push(make_pair(0, second));
  while (!Q.empty() && (!used[e])) {
    pair<int, int> cur = Q.top();
    Q.pop();
    used[cur.second] = 1;
    for (int i = 0; i < g[cur.second].size(); i++) {
      int idx = g[cur.second][i];
      int to = E[idx].other(cur.second);
      if (!used[to] && E[idx].w + dis[cur.second] < dis[to]) {
        dis[to] = E[idx].w + dis[cur.second];
        Q.push(make_pair(dis[to], to));
        parent[to] = idx;
      }
    }
  }
}
bool cmp(edge e1, edge e2) { return e1.w > e2.w; }
int main() {
  scanf("%d", &n);
  scanf("%d", &m);
  scanf("%d", &L);
  scanf("%d", &second);
  scanf("%d", &e);
  for (int i = 1; i <= m; i++) {
    scanf("%d", &E[i].u);
    scanf("%d", &E[i].v);
    scanf("%d", &E[i].w);
  }
  sort(E + 1, E + m + 1, cmp);
  int last = 0;
  for (int i = 1; i <= m; i++) {
    if (E[i].w == 0) break;
    g[E[i].u].push_back(i);
    g[E[i].v].push_back(i);
    last = i;
  }
  djkstra(second, e);
  if (dis[e] < L) {
    puts("NO");
    return 0;
  }
  for (int i = last + 1; i <= m; i++) {
    E[i].w = 1;
    g[E[i].u].push_back(i);
    g[E[i].v].push_back(i);
  }
  djkstra(second, e);
  if (dis[e] > L) {
    puts("NO");
    return 0;
  }
  puts("YES");
  for (int i = last + 1; i <= m; i++) {
    E[i].w = L;
  }
  int node = e;
  while (node != second) {
    int idx = parent[node];
    if (idx > last) {
      E[idx].w = 1;
    }
    node = E[idx].other(node);
  }
  while (dis[e] < L) {
    node = e;
    while (node != second) {
      int idx = parent[node];
      if (idx > last) {
        E[idx].w += (L - dis[e]);
        break;
      }
      node = E[idx].other(node);
    }
    djkstra(second, e);
  }
  for (int i = 1; i <= m; i++) {
    printf("%d %d %d\n", E[i].u, E[i].v, E[i].w);
  }
  return 0;
}
