#include <bits/stdc++.h>
using namespace std;
const int maxN = 1000, maxM = 10000;
const long long INF = 1000000000000000LL;
vector<pair<int, int> > G[maxN];
int n, E[maxM];
long long dist[maxN];
vector<int> editable_edges;
bool vis[maxN];
priority_queue<pair<long long, int> > H;
void Dijkstra(int source) {
  fill(dist, dist + n, INF);
  dist[source] = 0;
  H.push(make_pair(0, source));
  while (!H.empty()) {
    int v = H.top().second;
    long long curr_dist = -H.top().first;
    H.pop();
    if (dist[v] != curr_dist) continue;
    for (int i = 0; i < G[v].size(); i++) {
      int u = G[v][i].first, edge = E[G[v][i].second];
      if (dist[u] > dist[v] + edge) {
        dist[u] = dist[v] + edge;
        H.push(make_pair(-dist[u], u));
      }
    }
  }
}
void print() {
  printf("YES\n");
  for (int v = 0; v < n; v++) {
    for (int i = 0; i < G[v].size(); i++) {
      int u = G[v][i].first, edge = E[G[v][i].second];
      if (v < u) printf("%d %d %d\n", v, u, edge);
    }
  }
}
int main() {
  int m, L, src, trg;
  scanf("%d%d%d%d%d", &n, &m, &L, &src, &trg);
  for (int i = 0; i < m; i++) {
    int a, b;
    scanf("%d%d%d", &a, &b, E + i);
    G[a].push_back(make_pair(b, i));
    G[b].push_back(make_pair(a, i));
    if (E[i] == 0) {
      E[i] = 1;
      editable_edges.push_back(i);
    }
  }
  Dijkstra(src);
  long long k = dist[trg];
  if (k > L or (k < L and editable_edges.empty())) {
    printf("NO\n");
    return 0;
  }
  if (k == L) {
    print();
    return 0;
  }
  for (int i = 0; i < editable_edges.size(); i++) {
    int ind = editable_edges[i];
    E[ind] += (L - dist[trg]);
    Dijkstra(src);
    if (dist[trg] == L) {
      print();
      return 0;
    }
  }
  printf("NO\n");
  return 0;
}
