#include <bits/stdc++.h>
using namespace std;
const int N = 1005;
const long long INF = 1e13 + 7;
int n, m, l, s, t;
struct edge {
  int from, to, next, w;
} e[N * N];
int head[N], cntE;
void addedge(int u, int v, int w) {
  e[cntE].from = u;
  e[cntE].to = v;
  e[cntE].next = head[u];
  e[cntE].w = w;
  head[u] = cntE++;
  e[cntE].from = v;
  e[cntE].to = u;
  e[cntE].next = head[v];
  e[cntE].w = w;
  head[v] = cntE++;
}
int cnt[N], pre[N];
long long d[N];
bool inq[N];
int spfa() {
  queue<int> q;
  memset(inq, 0, sizeof inq);
  memset(cnt, 0, sizeof cnt);
  for (int i = 0; i <= n; ++i) d[i] = INF;
  d[s] = 0;
  inq[s] = true;
  q.push(s);
  while (q.size()) {
    int u = q.front();
    q.pop();
    inq[u] = false;
    for (int i = head[u]; ~i; i = e[i].next) {
      int v = e[i].to;
      int c = e[i].w;
      if (d[u] < INF && d[v] > d[u] + c) {
        d[v] = d[u] + c;
        pre[v] = u;
        if (!inq[v]) {
          q.push(v);
          inq[v] = true;
        }
      }
    }
  }
  return d[t];
}
vector<int> zeroedge;
int main() {
  while (~scanf("%d%d%d%d%d", &n, &m, &l, &s, &t)) {
    memset(head, -1, sizeof head);
    cntE = 0;
    zeroedge.clear();
    int u, v, c;
    for (int i = 0; i < m; ++i) {
      scanf("%d%d%d", &u, &v, &c);
      addedge(u, v, c == 0 ? 1 : c);
      if (c == 0) zeroedge.push_back(cntE - 1);
    }
    long long tmp = spfa();
    if (tmp > l) {
      puts("NO");
      continue;
    }
    if (tmp == l) {
      puts("YES");
      for (int i = 0; i < cntE; i += 2) {
        printf("%d %d %d\n", e[i].from, e[i].to, e[i].w);
      }
      continue;
    }
    int fg = false;
    for (int i = 0; i < zeroedge.size(); ++i) {
      int x = zeroedge[i];
      e[x].w = e[x ^ 1].w = l - tmp + 1;
      tmp = spfa();
      if (tmp == l) {
        fg = true;
        puts("YES");
        for (int i = 0; i < cntE; i += 2) {
          printf("%d %d %d\n", e[i].from, e[i].to, e[i].w);
        }
        break;
      }
    }
    if (!fg) puts("NO");
  }
  return 0;
}
