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;
int Day12[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int prime100[] = {2,  3,  5,  7,  11, 13, 17, 19, 23, 29, 31, 37,  41, 43,
                  47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103};
template <typename T>
inline bool isLeap(T y) {
  return (y % 400 == 0) || (y % 100 ? y % 4 == 0 : false);
}
template <typename T>
inline T GCD(T a, T b) {
  a = abs(a);
  b = abs(b);
  if (a < b) swap(a, b);
  while (b) {
    a = a % b;
    swap(a, b);
  }
  return a;
}
template <typename T>
inline T LCM(T x, T y) {
  T tp = GCD(x, y);
  if ((x / tp) * 1. * y > 9e18) return 9e18;
  return (x / tp) * y;
}
template <typename T>
inline T BIGMOD(T A, T B, T M = 1000000007) {
  T ret = 1;
  while (B) {
    if (B & 1) ret = (ret * A) % M;
    A = (A * A) % M;
    B = B >> 1;
  }
  return ret;
}
template <typename T>
inline T BigMod(T A, T B, T M) {
  T ret = 1;
  while (B) {
    if (B & 1) ret = (ret * A) % M;
    A = (A * A) % M;
    B = B >> 1;
  }
  return ret;
}
long long int MySqrt(long long int n) {
  long long int p = sqrt(n);
  if ((p + 1) * (p + 1) <= n)
    return p + 1;
  else if (p * p <= n)
    return p;
  else
    return p - 1;
}
long long int MyPow(long long int x, long long int n) {
  if (n == 0)
    return 1;
  else if (n % 2 == 0)
    return MyPow(x * x, n / 2);
  else
    return x * MyPow(x * x, ((n - 1) / 2));
}
long long int modInverse(long long int n) {
  return BIGMOD(n, (long long int)1000000007 - 2) % 1000000007;
}
long long BIG = 10000000000;
std::vector<pair<int, int>> G[1005];
std::vector<pair<long long int, pair<int, int>>> V;
std::map<pair<int, int>, int> Mp;
long long Dis[1005];
int Edge[100005];
int Par[1005];
int n, m, src, ter;
void DJK(int check) {
  for (int i = 0; i <= n; i++) Dis[i] = BIG;
  priority_queue<pair<int, int>> PQ;
  PQ.push(make_pair(0, src));
  Dis[src] = 0;
  Par[src] = src;
  while (!PQ.empty()) {
    int u = PQ.top().second;
    long long taka = PQ.top().first * (-1);
    PQ.pop();
    int sz = G[u].size();
    for (int i = 0; i < sz; i++) {
      int v = G[u][i].second;
      long long ok = G[u][i].first;
      if (check == 1) {
        if (Dis[u] + ok < Dis[v] && ok > 0) {
          Dis[v] = Dis[u] + ok;
          PQ.push(make_pair(Dis[v] * (-1), v));
          int x = min(u, v);
          int y = max(u, v);
          int e = Mp[make_pair(x, y)];
          Par[v] = u;
        }
      } else {
        if (Dis[u] + ok < Dis[v]) {
          Dis[v] = Dis[u] + ok;
          PQ.push(make_pair(Dis[v] * (-1), v));
          int x = min(u, v);
          int y = max(u, v);
          int e = Mp[make_pair(x, y)];
          Par[v] = u;
        }
      }
    }
  }
}
int main(int argc, char const *argv[]) {
  long long L;
  scanf("%d%d", &(n), &(m));
  scanf("%lld", &(L));
  scanf("%d%d", &(src), &(ter));
  for (int i = 0; i < m; i++) {
    int u, v;
    long long w;
    cin >> u >> v >> w;
    G[u].push_back(make_pair(w, v));
    G[v].push_back(make_pair(w, u));
    int x = min(u, v);
    int y = max(u, v);
    V.push_back(make_pair(w, make_pair(x, y)));
    if (w == 0) Mp[make_pair(x, y)] = i;
  }
  DJK(1);
  if (Dis[ter] < L) {
    printf("NO\n");
    exit(0);
  }
  if (Dis[ter] == L) {
    printf("YES\n");
    for (int i = 0; i < m; i++) {
      if (V[i].first == 0) {
        printf("%d %d %lld\n", V[i].second.first, V[i].second.second, BIG);
      } else
        printf("%d %d %lld\n", V[i].second.first, V[i].second.second,
               V[i].first);
    }
    exit(0);
  }
  memset(Edge, 0, sizeof Edge);
  memset(Par, 0, sizeof Par);
  DJK(2);
  int u = ter;
  while (Par[u] != u) {
    int x = u;
    int y = Par[u];
    int no = Mp[make_pair(min(x, y), max(x, y))];
    Edge[no] = 1;
    u = Par[u];
  }
  int no = Mp[make_pair(min(u, src), max(src, u))];
  Edge[no] = 1;
  int Cnt = 0;
  for (int i = 0; i < m; i++) {
    if (Edge[i] == 1 && V[i].first == 0) Cnt++;
  }
  if ((Dis[ter] + Cnt > L) || (Cnt == 0 && Dis[ter] != L)) {
    printf("NO\n");
    exit(0);
  }
  L = L - Dis[ter];
  printf("YES\n");
  long long int Sum = 0;
  for (int i = 0; i < m; i++) {
    if (Edge[i] == 1 && V[i].first == 0 && Cnt > 1) {
      printf("%d %d 1\n", V[i].second.first, V[i].second.second);
      Cnt--;
      L -= 1;
    } else if (Edge[i] == 1 && V[i].first == 0 && Cnt == 1) {
      printf("%d %d %lld\n", V[i].second.first, V[i].second.second, L);
      Cnt--;
    } else if (Edge[i] == 0 && V[i].first == 0) {
      printf("%d %d %lld\n", V[i].second.first, V[i].second.second, BIG);
    } else
      printf("%d %d %lld\n", V[i].second.first, V[i].second.second, V[i].first);
  }
  return 0;
}
