#include <bits/stdc++.h>
using namespace std;
const long long INF = 1e18;
int n, m, s, t, tot;
long long d[1010];
long long L, ans;
bool vis[1010];
struct edge {
  int x, y, sgn;
  long long w;
};
vector<edge> E;
vector<int> G[1010], Z;
struct node {
  int x;
  long long d;
  bool operator<(const node& a) const { return d > a.d; }
};
void add(int x, int y, int z) {
  edge nw;
  nw.x = x, nw.y = y, nw.w = (long long)z, nw.sgn = (z == 0);
  E.push_back(nw);
  tot++;
  G[x].push_back(tot);
  if (z == 0) Z.push_back(tot);
  nw.x = y, nw.y = x;
  E.push_back(nw);
  tot++;
  G[y].push_back(tot);
}
long long dijkstra(int s) {
  priority_queue<node> Q;
  for (int i = 0; i <= n; i++) d[i] = 1e18;
  d[s] = 0;
  memset(vis, 0, sizeof vis);
  Q.push((node){s, 0});
  while (!Q.empty()) {
    node now = Q.top();
    Q.pop();
    int pos = now.x;
    if (vis[pos]) continue;
    vis[pos] = 1;
    for (int i = 0; i < G[pos].size(); i++) {
      edge& nxt = E[G[pos][i]];
      if (nxt.w == 0) continue;
      if (d[nxt.y] > d[pos] + nxt.w) {
        d[nxt.y] = d[pos] + nxt.w;
        Q.push((node){nxt.y, d[nxt.y]});
      }
    }
  }
  return d[t];
}
int main() {
  scanf("%d%d%lld%d%d", &n, &m, &L, &s, &t);
  tot = -1;
  for (int i = 1, j, k, l; i <= m; i++) {
    scanf("%d%d%d", &j, &k, &l);
    add(j, k, l);
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < G[i].size(); j++) {
    }
  }
  ans = dijkstra(s);
  bool flag = 0;
  if (ans < L) {
    puts("NO");
    return 0;
  } else if (ans == L) {
    flag = 1;
  }
  for (int i = 0; i < Z.size() && !flag; i++) {
    E[Z[i]].w = E[Z[i] ^ 1].w = 1;
    ans = dijkstra(s);
    if (ans <= L) {
      E[Z[i]].w = E[Z[i] ^ 1].w += L - ans;
      flag = 1;
      break;
    }
  }
  if (flag) {
    puts("YES");
    for (int i = 0; i < E.size(); i += 2) {
      if (E[i].w == 0) E[i].w = 1e18;
      printf("%d %d %lld\n", E[i].x, E[i].y, E[i].w);
    }
  } else {
    puts("NO");
  }
  return 0;
}
