#include <bits/stdc++.h>
using namespace std;
const long long INF = 10000000000000000;
const int maxN = 1000 + 10;
const int maxM = 20000 + 10;
long long d1;
int er[maxM];
vector<int> paths1;
struct Edge {
  int from, to;
  long long dist;
};
struct HeapNode {
  long long d;
  int u;
  bool operator<(const HeapNode& rhs) const { return d > rhs.d; }
};
vector<Edge> edges;
vector<int> G[maxN];
bool done[maxN];
long long d[maxN];
int p[maxM];
struct Dijkstra {
  int n, m;
  void init(int n) {
    this->n = n;
    for (int i = 0; i < n; i++) G[i].clear();
    edges.clear();
  }
  void AddEdge(int from, int to, long long dist) {
    edges.push_back((Edge){from, to, dist});
    m = edges.size();
    G[from].push_back(m - 1);
  }
  void dijkstra(int s) {
    priority_queue<HeapNode> Q;
    for (int i = 0; i < n; i++) d[i] = INF;
    d[s] = 0;
    memset(done, 0, sizeof(done));
    Q.push((HeapNode){0, s});
    while (!Q.empty()) {
      HeapNode x = Q.top();
      Q.pop();
      int u = x.u;
      if (done[u]) continue;
      done[u] = true;
      for (int i = 0; i < G[u].size(); i++) {
        Edge& e = edges[G[u][i]];
        if (d[e.to] > d[u] + e.dist) {
          d[e.to] = d[u] + e.dist;
          p[e.to] = G[u][i];
          Q.push((HeapNode){d[e.to], e.to});
        }
      }
    }
  }
  void GetShortestPaths(int s, int u) {
    dijkstra(s);
    if (d[u] >= INF) {
      d1 = d[u];
      return;
    }
    for (int i = u; i <= u; i++) {
      d1 = d[i];
      paths1.clear();
      int t = i;
      paths1.push_back(t);
      while (t != s) {
        paths1.push_back(edges[p[t]].from);
        t = edges[p[t]].from;
      }
      reverse(paths1.begin(), paths1.end());
    }
  }
};
Dijkstra solver;
Edge ei[10000 + 10];
int main() {
  int n, m, s, t;
  long long L;
  while (~scanf("%d%d%lld%d%d", &n, &m, &L, &s, &t)) {
    memset(er, 0, sizeof(er));
    int er_cnt = 0;
    for (long long i = 0; i < m; i++) {
      scanf("%d%d%lld", &ei[i].from, &ei[i].to, &ei[i].dist);
      if (ei[i].dist == 0) {
        er[i] = ++er_cnt;
      }
    }
    solver.init(n);
    for (int i = 0; i < m; i++) {
      if (er[i]) ei[i].dist = L;
      solver.AddEdge(ei[i].from, ei[i].to, ei[i].dist);
      solver.AddEdge(ei[i].to, ei[i].from, ei[i].dist);
    }
    solver.GetShortestPaths(s, t);
    if (d1 < L)
      printf("NO\n");
    else if (d1 == L) {
      printf("YES\n");
      for (long long i = 0; i < m; i++)
        printf("%d %d %lld\n", ei[i].from, ei[i].to, ei[i].dist);
    } else {
      solver.init(n);
      for (int i = 0; i < m; i++) {
        if (er[i]) ei[i].dist = 1;
        solver.AddEdge(ei[i].from, ei[i].to, ei[i].dist);
        solver.AddEdge(ei[i].to, ei[i].from, ei[i].dist);
      }
      solver.GetShortestPaths(s, t);
      if (d1 > L)
        printf("NO\n");
      else if (d1 == L) {
        printf("YES\n");
        for (int i = 0; i < m; i++)
          printf("%d %d %lld\n", ei[i].from, ei[i].to, ei[i].dist);
      } else {
        int x = 1, y = er_cnt, ans;
        while (x <= y) {
          int mid = (x + y) / 2;
          solver.init(n);
          for (int i = 0; i < m; i++) {
            if (1 <= er[i] && er[i] <= mid)
              ei[i].dist = 1;
            else if (er[i] > mid)
              ei[i].dist = L;
            solver.AddEdge(ei[i].from, ei[i].to, ei[i].dist);
            solver.AddEdge(ei[i].to, ei[i].from, ei[i].dist);
          }
          solver.GetShortestPaths(s, t);
          if (d1 <= L) {
            ans = mid;
            y = mid - 1;
          } else
            x = mid + 1;
        }
        solver.init(n);
        for (int i = 0; i < m; i++) {
          if (1 <= er[i] && er[i] <= ans)
            ei[i].dist = 1;
          else if (er[i] > ans)
            ei[i].dist = L;
          solver.AddEdge(ei[i].from, ei[i].to, ei[i].dist);
          solver.AddEdge(ei[i].to, ei[i].from, ei[i].dist);
        }
        solver.GetShortestPaths(s, t);
        long long add = L - d1;
        long long pre, cnt = 0, now;
        printf("YES\n");
        for (int i = 0; i < m; i++) {
          if (er[i] != ans)
            printf("%d %d %lld\n", ei[i].from, ei[i].to, ei[i].dist);
          else
            printf("%d %d %lld\n", ei[i].from, ei[i].to, ei[i].dist + add);
        }
      }
    }
  }
  return 0;
}
