#include <bits/stdc++.h>
using namespace std;
const int N = 1010, M = 10010;
int n, m, L, s, t, inf;
int head[N], p = 1, h[M];
struct node {
  int go, next, from, wi, flag;
} d[M << 1];
void build(int a, int b, int c) {
  d[++p] = (node){b, head[a], a, c, c};
  head[a] = p;
  d[++p] = (node){a, head[b], b, c, c};
  head[b] = p;
}
int que[N + 10], dis[N], f[N], fr[N], used[M << 1];
int spfa() {
  for (int i = 1; i <= n; i++) dis[i] = inf;
  memset(used, 0, sizeof used);
  int he, ta;
  he = ta = 1;
  que[1] = s;
  dis[s] = 0;
  while (he <= ta) {
    int a = que[he % N];
    he++;
    used[a] = false;
    for (int i = head[a]; i; i = d[i].next)
      if (dis[d[i].go] > dis[a] + d[i].wi) {
        dis[d[i].go] = dis[a] + d[i].wi;
        f[d[i].go] = a;
        fr[d[i].go] = i;
        if (dis[d[i].go] > inf) dis[d[i].go] = inf;
        if (!used[d[i].go]) {
          used[d[i].go] = true;
          que[(++ta) % N] = d[i].go;
        }
      }
  }
  return dis[t];
}
bool check() {
  for (int i = 1; i <= p; i++)
    if (d[i].flag == 0) d[i].wi = inf;
  if (spfa() < L) return 0;
  for (int i = 1; i <= p; i++)
    if (d[i].flag == 0) d[i].wi = 1;
  if (spfa() > L) return 0;
  return 1;
}
void add(int len) {
  memset(used, 0, sizeof used);
  for (int i = t; i != s; i = f[i]) used[fr[i]] = used[fr[i] ^ 1] = true;
  for (int i = t; i != s; i = f[i])
    if (!d[fr[i]].flag) {
      d[fr[i]].wi += L - len;
      d[fr[i] ^ 1].wi += L - len;
      break;
    }
  for (int i = 2; i <= p; i++)
    if (!used[i] && !d[i].flag) d[i].wi = inf;
}
void solve() {
  while (true) {
    int len = spfa();
    if (len == L) return;
    add(len);
  }
}
int main() {
  cin >> n >> m >> L >> s >> t;
  inf = L + 1;
  s++;
  t++;
  int a, b, c;
  for (int i = 1; i <= m; i++) {
    cin >> a >> b >> c;
    a++;
    b++;
    build(a, b, c);
  }
  if (!check()) {
    printf("NO\n");
    return 0;
  }
  printf("YES\n");
  solve();
  for (int i = 2; i <= p; i += 2)
    printf("%d %d %d\n", d[i].from - 1, d[i].go - 1, d[i].wi);
  return 0;
}
