#include <bits/stdc++.h>
using namespace std;
struct Graph {
  struct Edge {
    int from, to, cost;
  };
  vector<Edge> edges;
  vector<int> G[1010];
  int V = 1010;
  long long dst[2][1010];
  void dijkstra(int s, int idx) {
    long long *d = dst[idx];
    priority_queue<pair<int, int>, vector<pair<int, int> >,
                   greater<pair<int, int> > >
        pq;
    fill(d, d + V, 2000000000);
    d[s] = 0;
    pq.push(pair<int, int>(0, s));
    while (!pq.empty()) {
      pair<int, int> p = pq.top();
      pq.pop();
      int v = p.second;
      if (d[v] < p.first) continue;
      for (int i : G[v]) {
        Edge e = edges[i];
        if (d[e.to] > d[v] + e.cost) {
          d[e.to] = d[v] + e.cost;
          pq.push(pair<int, int>(d[e.to], e.to));
        }
        if (d[e.from] > d[v] + e.cost) {
          d[e.from] = d[v] + e.cost;
          pq.push(pair<int, int>(d[e.from], e.from));
        }
      }
    }
  }
  void solve(vector<int> q, int t, long long l) {
    long long *d = dst[0];
    priority_queue<pair<int, int>, vector<pair<int, int> >,
                   greater<pair<int, int> > >
        pq;
    for (int i0 : q) {
      Edge &temp = edges[i0];
      pq.push(pair<int, int>(d[temp.from], temp.from));
      pq.push(pair<int, int>(d[temp.to], temp.to));
      temp.cost = 1;
      while (!pq.empty()) {
        pair<int, int> p = pq.top();
        pq.pop();
        int v = p.second;
        if (d[v] < p.first || d[v] >= l) continue;
        for (int i : G[v]) {
          Edge e = edges[i];
          if (d[e.to] > d[v] + e.cost) {
            d[e.to] = d[v] + e.cost;
            pq.push(pair<int, int>(d[e.to], e.to));
          }
          if (d[e.from] > d[v] + e.cost) {
            d[e.from] = d[v] + e.cost;
            pq.push(pair<int, int>(d[e.from], e.from));
          }
        }
      }
      if (d[t] < l) {
        temp.cost = l - d[t] + 1;
        for (Edge e : edges) printf("%d %d %d\n", e.from, e.to, e.cost);
        return;
      }
    }
    for (Edge e : edges) printf("%d %d %d\n", e.from, e.to, e.cost);
  }
  void add_edge(int from, int to, int cost) {
    G[from].push_back(edges.size());
    G[to].push_back(edges.size());
    edges.push_back((Edge){from, to, cost});
  }
} g;
int main() {
  int n, m, s, t;
  long long l;
  cin >> n >> m >> l >> s >> t;
  vector<int> q;
  for (int i = 0; i < m; i++) {
    int u, v, w;
    scanf("%d%d%d", &u, &v, &w);
    if (!w) {
      q.push_back(i);
      w = 1;
    }
    g.add_edge(u, v, w);
  }
  g.dijkstra(s, 1);
  for (int i : q) g.edges[i].cost = 2000000000;
  g.dijkstra(s, 0);
  if (g.dst[0][t] < l || g.dst[1][t] > l) {
    printf("NO\n");
  } else {
    printf("Yes\n");
    g.solve(q, t, l);
  }
  return 0;
}
