#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int h[N], idx;
int l, s, t;
struct Edge {
  int from, to, nex;
  long long w;
} edge[N << 1];
void add(int u, int v, long long w) {
  Edge E = {u, v, h[u], w};
  edge[idx] = E;
  h[u] = idx++;
}
int d[N];
struct node {
  long long d;
  int id;
  bool operator<(const node &a) const { return d > a.d; }
};
void init() {
  memset(h, -1, sizeof(h));
  idx = 0;
}
priority_queue<node> q;
int vis[N];
void dij() {
  memset(d, 0x3f, sizeof(d));
  memset(vis, 0, sizeof(vis));
  d[s] = 0;
  q.push({d[s], s});
  while (!q.empty()) {
    auto nw = q.top();
    q.pop();
    if (vis[nw.id]) continue;
    vis[nw.id] = 1;
    for (int i = h[nw.id]; ~i; i = edge[i].nex) {
      int v = edge[i].to;
      long long w = edge[i].w;
      if (!w) continue;
      if (d[v] > d[nw.id] + w) {
        d[v] = d[nw.id] + w;
        q.push({d[v], v});
      }
    }
  }
}
int d2[N];
void dij2() {
  memset(d2, 0x3f, sizeof(d2));
  memset(vis, 0, sizeof(vis));
  d2[t] = 0;
  q.push({d2[t], t});
  while (!q.empty()) {
    auto nw = q.top();
    q.pop();
    if (vis[nw.id]) continue;
    vis[nw.id] = 1;
    for (int i = h[nw.id]; ~i; i = edge[i].nex) {
      int v = edge[i].to;
      long long w = edge[i].w;
      if (!w) {
        w = edge[i].w = edge[i ^ 1].w = max(1, l - d[v] - d2[nw.id]);
      }
      if (d2[v] > d2[nw.id] + w) {
        d2[v] = d2[nw.id] + w;
        q.push({d2[v], v});
      }
    }
  }
}
int main() {
  int m, n;
  cin >> n >> m >> l >> s >> t;
  init();
  for (int i = 1; i <= m; i++) {
    int u, v, w;
    cin >> u >> v >> w;
    add(u, v, w);
    add(v, u, w);
  }
  dij();
  if (d[t] < l) {
    printf("NO\n");
    return 0;
  }
  dij2();
  if (d2[s] != l)
    printf("NO\n");
  else {
    printf("YES\n");
    for (int i = 0; i < idx; i += 2) {
      printf("%d %d %lld\n", edge[i].from, edge[i].to, edge[i].w);
    }
  }
  return 0;
}
