#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;   }