#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int n, m, s, t;
long long L;
int pre[N * 2], last[N], other[N * 2], num = 1;
long long w[N * 2];
long long d[N];
bool no[N];
struct node {
  int i;
  long long dis;
};
priority_queue<node> q;
bool operator<(node a, node b) { return a.dis > b.dis; }
void dijkstra() {
  memset(d, 0x3f, sizeof(d));
  q.push((node){s, 0});
  d[s] = 0;
  while (!q.empty()) {
    node u = q.top();
    q.pop();
    if (u.dis != d[u.i]) continue;
    for (int i = last[u.i]; i; i = pre[i]) {
      int v = other[i];
      if (u.dis + w[i] < d[v]) {
        d[v] = u.dis + w[i];
        q.push((node){v, d[v]});
      }
    }
  }
}
inline void add(int x, int y, long long z) {
  num++;
  pre[num] = last[x];
  last[x] = num;
  other[num] = y;
  w[num] = z;
}
int main() {
  int x, y;
  long long z;
  scanf("%d%d%I64d%d%d", &n, &m, &L, &s, &t);
  s++, t++;
  for (int i = 1; i <= m; i++) {
    scanf("%d%d%I64d", &x, &y, &z);
    x++, y++;
    if (z == 0) {
      add(x, y, 1);
      add(y, x, 1);
      no[num] = 1;
    } else
      add(x, y, z), add(y, x, z);
  }
  dijkstra();
  if (d[t] > L) {
    puts("NO");
    return 0;
  }
  bool ok = 0;
  for (int i = 1; i <= n; i++) {
    for (int j = last[i]; j; j = pre[j]) {
      if (j & 1) {
        if (no[j]) {
          if (d[t] == L) {
            ok = 1;
            break;
          }
          if (d[t] < L) w[j] = w[j ^ 1] = L - d[t] + 1;
          dijkstra();
        }
      }
    }
    if (ok) break;
  }
  if (!ok && d[t] != L)
    puts("NO");
  else {
    puts("YES");
    for (int i = 1; i <= n; i++) {
      for (int j = last[i]; j; j = pre[j]) {
        if (j & 1)
          printf("%d %d %I64d\n", other[j] - 1, other[j ^ 1] - 1, w[j]);
      }
    }
  }
  return 0;
}
