#include <bits/stdc++.h>
using namespace std;
void Dijkstra(int64_t zero, int Source, vector<vector<int>> &Graph,
              map<pair<int, int>, int64_t> &Weight, vector<int64_t> &Dist) {
  priority_queue<pair<int64_t, int>, vector<pair<int64_t, int>>,
                 bool (*)(const pair<int64_t, int> &,
                          const pair<int64_t, int> &)>
      pq([](const pair<int64_t, int> &a, const pair<int64_t, int> &b) {
        return a.first > b.first;
      });
  pq.push({0, Source});
  Dist[Source] = 0;
  while (!pq.empty()) {
    int cur = pq.top().second;
    int64_t Dist_t = pq.top().first;
    pq.pop();
    if (Dist[cur] != Dist_t) continue;
    for (int &child : Graph[cur]) {
      int64_t Edge_w = Weight[{min(child, cur), max(child, cur)}];
      Edge_w += Edge_w == 0;
      if (Dist_t + Edge_w < Dist[child]) {
        Dist[child] = Dist_t + Edge_w;
        pq.push({Dist[child], child});
      }
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  int N, M, Source, Target;
  int64_t L;
  cin >> N >> M >> L >> Source >> Target;
  vector<vector<int>> Graph(N);
  map<pair<int, int>, int64_t> Weight;
  vector<pair<int, int>> Edges(M);
  for (int i = 0; i < M; ++i) {
    int u, v, w;
    cin >> u >> v >> w;
    Graph[u].push_back(v);
    Graph[v].push_back(u);
    Weight[{min(v, u), max(v, u)}] = w;
    Edges[i] = {u, v};
  }
  vector<int64_t> Dist(N, 4e18), Tdist(N, 4e18), last(N, 4e18);
  Dijkstra(1, Target, Graph, Weight, Tdist);
  priority_queue<pair<int64_t, int>, vector<pair<int64_t, int>>,
                 bool (*)(const pair<int64_t, int> &,
                          const pair<int64_t, int> &)>
      pq([](const pair<int64_t, int> &a, const pair<int64_t, int> &b) {
        return a.first > b.first;
      });
  pq.push({0, Source});
  Dist[Source] = 0;
  while (!pq.empty()) {
    int cur = pq.top().second;
    int64_t Dist_t = pq.top().first;
    pq.pop();
    if (Dist_t != Dist[cur]) continue;
    for (int &child : Graph[cur]) {
      int64_t Edge_w = Weight[{min(child, cur), max(child, cur)}];
      if (Edge_w == 0) Edge_w = max(int64_t(1), L - Dist[cur] - Tdist[child]);
      Weight[{min(child, cur), max(child, cur)}] = Edge_w;
      if (Dist[child] > Dist_t + Edge_w) {
        Dist[child] = Dist_t + Edge_w;
        pq.push({Dist_t + Edge_w, child});
      }
    }
  }
  Dijkstra(1, Source, Graph, Weight, last);
  if (last[Target] != L)
    cout << "NO\n";
  else {
    cout << "YES\n";
    for (auto &[u, v] : Edges)
      cout << u << ' ' << v << ' ' << Weight[{min(u, v), max(u, v)}] << '\n';
  }
  return 0;
}
