7 9 999999999 0 3
0 1 0
1 2 0
2 3 0
0 4 1
4 1 1
1 5 499999999
5 2 499999999
2 6 1
6 3 1
 7 9 320 0 3
0 1 0
1 2 0
2 3 0
0 4 1
4 1 1
1 5 100
5 2 100
2 6 59
6 3 61
 4 5 7 0 3
0 1 0
1 2 3
2 3 0
0 2 5
1 3 5
 8 9 10 1 0
1 2 1
2 4 1
1 3 0
3 4 0
4 5 0
5 6 1
6 0 1
5 7 0
7 0 0
 4 4 14 1 3
1 3 13
2 3 0
2 0 0
1 0 12
 5 6 1000000000 0 4
0 1 1
2 0 2
3 0 3
4 1 0
4 2 0
3 4 0
 4 5 10 1 2
0 1 3
1 2 0
1 3 4
2 3 4
2 0 6
 4 4 2 1 3
1 3 13
2 3 0
2 0 0
1 0 0
 5 5 2 0 2
0 1 1
1 2 1
0 4 0
4 3 0
3 2 0
 5 5 3 0 2
0 1 1
1 2 1
0 4 0
4 3 0
3 2 0
 4 4 8 1 3
1 3 13
2 3 0
2 0 0
1 0 6
 1000 1 1000000000 998 0
0 999 0
 5 5 1 0 2
0 1 1
1 2 1
0 4 0
4 3 0
3 2 0
 100 1 123456 99 0
0 99 123456
 4 4 13 1 3
1 3 13
2 3 0
2 0 0
1 0 12
 7 9 319 0 3
0 1 0
1 2 0
2 3 0
0 4 1
4 1 1
1 5 100
5 2 100
2 6 59
6 3 61
 1000 1 5 999 0
0 999 0

YES
0 1 1
1 2 999999996
2 3 999999997
0 4 1
4 1 1
1 5 499999999
5 2 499999999
2 6 1
6 3 1
 YES
0 1 1
1 2 199
2 3 318
0 4 1
4 1 1
1 5 100
5 2 100
2 6 59
6 3 61
 YES
0 1 3
1 2 3
2 3 2
0 2 5
1 3 5
 YES
1 2 1
2 4 1
1 3 1
3 4 1
4 5 6
5 6 1
6 0 1
5 7 1
7 0 1
 NO YES
0 1 1
2 0 2
3 0 3
4 1 999999999
4 2 999999998
3 4 999999997
 NO NO YES
0 1 1
1 2 1
0 4 1
4 3 1
3 2 1
 NO YES
1 3 13
2 3 1
2 0 1
1 0 6
 NO NO YES
0 99 123456
 YES
1 3 13
2 3 1
2 0 1
1 0 12
 YES
0 1 1
1 2 198
2 3 317
0 4 1
4 1 1
1 5 100
5 2 100
2 6 59
6 3 61
 YES
0 999 5

#include <bits/stdc++.h>
using namespace std;
const int DI[] = {-1, 0, 1, 0};
const int DJ[] = {0, 1, 0, -1};
const int MAXINT = 0x7fffffff;
const int BIGINT = 0x20000000;
const long long MAXLL = 0x7fffffffffffffffLL;
const long long BIGLL = 0x2000000000000000LL;
template <typename T>
T gcd(T a, T b) {
  return b ? gcd(b, a % b) : a;
}
template <typename T>
T powmod(T a, T b, T m) {
  T r = 1;
  a %= m;
  for (; b; b >>= 1) {
    if (b & 1) r = r * a % m;
    a = a * a % m;
  }
  return r;
}
int N, M, S, T;
long long L;
vector<vector<pair<int, long long>>> edge, cand;
unordered_set<int> shortest;
vector<long long> Get(bool set_route) {
  vector<int> parent(N, -1);
  vector<long long> D(N, BIGLL);
  parent[S] = S;
  set<pair<long long, int>> Q;
  D[S] = 0;
  Q.insert(make_pair(0, S));
  while (!Q.empty()) {
    pair<long long, int> top = *Q.begin();
    int v = top.second;
    Q.erase(Q.begin());
    for (auto& p : edge[v]) {
      int v2 = p.first;
      long long cost = p.second;
      if (D[v2] > D[v] + cost) {
        if (D[v2] != BIGLL) {
          Q.erase(make_pair(D[v2], v2));
        }
        D[v2] = D[v] + cost;
        if (set_route) parent[v2] = v;
        Q.insert(make_pair(D[v2], v2));
      }
    }
  }
  if (set_route && D[T] != BIGLL) {
    for (int node = T;; node = parent[node]) {
      shortest.insert(node);
      if (node == S) break;
    }
  }
  return D;
}
int main() {
  ios::sync_with_stdio(false);
  cin >> N >> M >> L >> S >> T;
  edge.resize(N);
  cand.resize(N);
  for (int i = 0; i < M; ++i) {
    int a, b;
    long long w;
    cin >> a >> b >> w;
    if (w) {
      edge[a].push_back(make_pair(b, w));
      edge[b].push_back(make_pair(a, w));
    } else {
      cand[a].push_back(make_pair(b, 1));
      cand[b].push_back(make_pair(a, 1));
    }
  }
  vector<long long> dis_wo = Get(false);
  if (dis_wo[T] < L) {
    cout << "NO" << endl;
    return 0;
  } else if (dis_wo[T] == L) {
    cout << "YES" << endl;
    for (int i = 0; i < N; ++i) {
      for (auto& p : edge[i]) {
        if (p.first > i) {
          cout << i << ' ' << p.first << ' ' << p.second << endl;
        }
      }
      for (auto& p : cand[i]) {
        if (p.first > i) {
          cout << i << ' ' << p.first << ' ' << L + 1 << endl;
        }
      }
    }
    return 0;
  }
  for (int i = 0; i < N; ++i) {
    for (auto& p : cand[i]) {
      edge[i].push_back(p);
    }
  }
  vector<long long> dis_w = Get(true);
  if (dis_w[T] > L) {
    cout << "NO" << endl;
    return 0;
  }
  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < cand[i].size(); ++j) {
      edge[i].pop_back();
    }
  }
  cout << "YES" << endl;
  long long rem = L - dis_w[T];
  for (int i = 0; i < N; ++i) {
    for (auto& p : edge[i]) {
      if (p.first > i) {
        cout << i << ' ' << p.first << ' ' << p.second << endl;
      }
    }
    for (auto& p : cand[i]) {
      if (p.first > i) {
        if (shortest.find(i) != shortest.end() &&
            shortest.find(p.first) != shortest.end()) {
          long long upto;
          if (dis_wo[i] != BIGLL && dis_wo[p.first] != BIGLL) {
            upto = min(abs(dis_wo[i] - dis_wo[p.first]), p.second + rem);
          } else {
            upto = p.second + rem;
          }
          cout << i << ' ' << p.first << ' ' << upto << endl;
          rem -= upto - p.second;
        } else {
          cout << i << ' ' << p.first << ' ' << p.second << endl;
        }
      }
    }
  }
  return 0;
}
