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;
const long long inf = 1e15;
int n, m, s, t;
long long L;
long long dst[3][1007];
struct edge {
  int to;
  long long w;
  bool q;
  edge() {}
  edge(int to, long long w, bool q) : to(to), w(w), q(q) {}
};
vector<edge> adj[1007];
bool G[1007][1007];
void dijkstra(int x) {
  dst[1][x] = 0;
  priority_queue<pair<long long, int> > pq;
  pq.push(make_pair(0, x));
  while (!pq.empty()) {
    int u = pq.top().second;
    long long w = -pq.top().first;
    pq.pop();
    if (w != dst[1][u]) continue;
    for (auto b : adj[u]) {
      int v = b.to;
      long long dw = b.w;
      if (dst[1][v] > dst[1][u] + dw) {
        dst[1][v] = dst[1][u] + dw;
        pq.push(make_pair(-dst[1][v], v));
      }
    }
  }
}
void dijkstra1() {
  priority_queue<pair<long long, int> > pq;
  dst[0][s] = 0;
  pq.push(make_pair(0, s));
  while (!pq.empty()) {
    int u = pq.top().second;
    long long w = -pq.top().first;
    pq.pop();
    for (int i = 0; i < adj[u].size(); i++) {
      int v = adj[u][i].to;
      long long nw = adj[u][i].w;
      bool e = adj[u][i].q;
      if (e) {
        adj[u][i].w = L - dst[1][v] - w;
        nw = adj[u][i].w;
      }
      if (dst[0][v] > dst[0][u] + nw) {
        dst[0][v] = dst[0][u] + nw;
        pq.push(make_pair(-dst[0][v], v));
      }
    }
  }
}
int main() {
  cin >> n >> m >> L >> s >> t;
  for (int i = 0; i < m; i++) {
    int u, v, w;
    cin >> u >> v >> w;
    bool q = 0;
    if (w == 0) {
      w = 1;
      q = 1;
    }
    adj[u].push_back(edge(v, w, q));
    adj[v].push_back(edge(u, w, q));
  }
  fill(dst[0], dst[0] + n + 1, inf);
  fill(dst[1], dst[1] + n + 1, inf);
  dijkstra(t);
  if (dst[1][s] > L) {
    printf("NO\n");
    return 0;
  }
  dijkstra1();
  fill(dst[1], dst[1] + n + 1, inf);
  dijkstra(s);
  if (dst[1][t] != L) {
    printf("NO\n");
    return 0;
  }
  printf("YES\n");
  for (int i = 0; i < n; i++) {
    for (auto x : adj[i]) {
      if (G[x.to][i] || G[i][x.to]) continue;
      G[x.to][i] = G[i][x.to] = 1;
      printf("%d %d %lld\n", i, x.to, x.w);
    }
  }
  return 0;
}
