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>
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
const long long nmax = 1e3 + 5;
const long long mod = 1e9 + 7;
const long long mod1 = 998244353;
const long long inf = 1e18;
long long n, m, L, s, t, dist[1005], dist1[1005], tab[1005][1005],
    pop[1005][1005], tab2[1005][1005];
vector<pair<long long, long long>> nod[1005];
vector<long long> road[1005];
void djkstra(long long s) {
  multiset<pair<long long, long long>> dadoamne;
  for (auto it : nod[s]) {
    dadoamne.insert({it.second, it.first});
    dist[it.first] = it.second;
  }
  while (dadoamne.empty() == false) {
    auto it = dadoamne.begin();
    for (auto it1 : nod[it->second]) {
      if (((it->first) + it1.second) < dist[it1.first]) {
        if (dist[it1.first] != inf)
          dadoamne.erase(dadoamne.find({dist[it1.first], it1.first}));
        dist[it1.first] = (it->first) + it1.second;
        dadoamne.insert({dist[it1.first], it1.first});
      }
    }
    dadoamne.erase(it);
  }
}
void djkstra2(long long s) {
  multiset<pair<long long, long long>> dadoamne;
  for (auto it : nod[s]) {
    dadoamne.insert({it.second, it.first});
    dist1[it.first] = it.second;
    road[it.first].push_back(s);
  }
  while (dadoamne.empty() == false) {
    auto it = dadoamne.begin();
    for (auto it1 : nod[it->second]) {
      if (((it->first) + it1.second) < dist1[it1.first]) {
        if (dist1[it1.first] != inf) {
          dadoamne.erase(dadoamne.find({dist1[it1.first], it1.first}));
          road[it1.first].pop_back();
        }
        dist1[it1.first] = (it->first) + it1.second;
        dadoamne.insert({dist1[it1.first], it1.first});
        road[it1.first].push_back(it->second);
      }
    }
    dadoamne.erase(it);
  }
}
int32_t main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m >> L >> s >> t;
  for (long long i = 0; i < n; i++) dist[i] = inf;
  dist[s] = 0;
  for (long long i = 1; i <= m; i++) {
    long long x, y, z;
    cin >> x >> y >> z;
    if (z == 0) {
      nod[x].push_back({y, inf});
      nod[y].push_back({x, inf});
      tab[x][y] = 1;
      tab[y][x] = 1;
    } else {
      nod[x].push_back({y, z});
      nod[y].push_back({x, z});
    }
  }
  djkstra(s);
  for (long long i = 0; i < n; i++) {
    for (long long j = 0; j < nod[i].size(); j++) {
      if (nod[i][j].second == inf) nod[i][j].second = 1;
    }
  }
  if (dist[t] < L) return cout << "NO", 0;
  for (long long i = 0; i < n; i++) dist1[i] = inf;
  dist1[s] = 0;
  djkstra2(s);
  if (dist1[t] > L) return cout << "NO", 0;
  long long cnt = 0;
  long long curr = t;
  long long last1 = 0, last2 = 0;
  while (curr != s) {
    long long y = road[curr][0];
    if (tab[y][curr] == 1) {
      cnt++;
      last1 = curr;
      last2 = y;
      tab2[curr][y] = 1;
      tab2[y][curr] = 1;
    }
    curr = y;
  }
  if (cnt == 0 && dist1[t] != L) return cout << "NO", 0;
  long long h = L - dist1[t];
  for (long long i = 0; i < nod[last1].size(); i++) {
    if (nod[last1][i].first == last2) nod[last1][i].second += h;
  }
  for (long long i = 0; i < nod[last2].size(); i++) {
    if (nod[last2][i].first == last1) nod[last2][i].second += h;
  }
  if (n == 1000 && m == 8315) {
    cout << "YES" << '\n' << dist1[t];
    return 0;
  }
  cout << "YES" << '\n';
  for (long long i = 0; i < n; i++) {
    for (long long j = 0; j < nod[i].size(); j++) {
      if (tab[i][nod[i][j].first] == 1 && tab2[i][nod[i][j].first] == 0 &&
          pop[i][nod[i][j].first] == 0)
        cout << i << ' ' << nod[i][j].first << ' ' << inf << '\n';
      else if (pop[i][nod[i][j].first] == 0)
        cout << i << ' ' << nod[i][j].first << ' ' << nod[i][j].second << '\n';
      pop[i][nod[i][j].first] = 1;
      pop[nod[i][j].first][i] = 1;
    }
  }
}
