#include <bits/stdc++.h>
using namespace std;
template <typename tp>
inline void read(tp& x) {
  x = 0;
  char tmp;
  bool key = 0;
  for (tmp = getchar(); !isdigit(tmp); tmp = getchar()) key = (tmp == '-');
  for (; isdigit(tmp); tmp = getchar()) x = (x << 3) + (x << 1) + (tmp ^ '0');
  if (key) x = -x;
}
const int N = 100010;
const long long INF = 0x3f3f3f3f3f3f3f3f;
int n, m, len, st, en;
namespace graph {
struct edge {
  int la, b, v;
} con[N];
int tot, first[N];
void add(int from, int to, int val) {
  con[++tot] = (edge){first[from], to, val};
  first[from] = tot;
}
void init() {
  tot = 0;
  memset(first, 0, sizeof first);
}
long long dis[N];
struct cmp {
  bool operator()(const pair<long long, int>& a,
                  const pair<long long, int>& b) {
    return a > b;
  }
};
priority_queue<pair<long long, int>, vector<pair<long long, int> >, cmp> q;
long long dijkstra() {
  memset(dis, 0x3f, sizeof dis);
  while (!q.empty()) q.pop();
  dis[st] = 0;
  q.push(pair<long long, int>(0, st));
  for (int pos; !q.empty();) {
    pos = q.top().second;
    if (dis[pos] != q.top().first) {
      q.pop();
      continue;
    }
    q.pop();
    for (int i = first[pos]; i; i = con[i].la) {
      if (dis[con[i].b] > dis[pos] + con[i].v) {
        dis[con[i].b] = dis[pos] + con[i].v;
        q.push(pair<long long, int>(dis[con[i].b], con[i].b));
      }
    }
  }
  return dis[en];
}
}  // namespace graph
struct data {
  int x, y, z;
} dat[N];
int num;
int main() {
  read(n), read(m), read(len), read(st), read(en);
  for (int i = 1, x, y, z; i <= m; ++i) {
    read(x), read(y), read(z);
    dat[i] = (data){x, y, z};
    if (z == 0) ++num;
  }
  for (int i = 1; i <= m; ++i) {
    int v = dat[i].z;
    if (!v) v = 1;
    graph::add(dat[i].x, dat[i].y, v);
    graph::add(dat[i].y, dat[i].x, v);
  }
  if (graph::dijkstra() > len) return puts("NO"), 0;
  graph::init();
  for (int i = 1; i <= m; ++i) {
    int v = dat[i].z;
    if (!v) continue;
    graph::add(dat[i].x, dat[i].y, v);
    graph::add(dat[i].y, dat[i].x, v);
  }
  if (graph::dijkstra() < len) return puts("NO"), 0;
  int l = 0, r = num, ans = num, mid;
  while (l <= r) {
    mid = (l + r) >> 1;
    graph::init();
    for (int i = 1, j = 1; i <= m; ++i) {
      if (dat[i].z) {
        graph::add(dat[i].x, dat[i].y, dat[i].z);
        graph::add(dat[i].y, dat[i].x, dat[i].z);
      } else if (j <= mid) {
        graph::add(dat[i].x, dat[i].y, 1);
        graph::add(dat[i].y, dat[i].x, 1);
        ++j;
      }
    }
    if (graph::dijkstra() <= len)
      ans = mid, r = mid - 1;
    else
      l = mid + 1;
  }
  num = ans;
  l = 1, r = len, ans = len;
  while (l <= r) {
    mid = (l + r) >> 1;
    graph::init();
    for (int i = 1, j = 1; i <= m; ++i) {
      if (dat[i].z) {
        graph::add(dat[i].x, dat[i].y, dat[i].z);
        graph::add(dat[i].y, dat[i].x, dat[i].z);
      } else {
        if (j < num) {
          graph::add(dat[i].x, dat[i].y, 1);
          graph::add(dat[i].y, dat[i].x, 1);
        } else if (j == num) {
          graph::add(dat[i].x, dat[i].y, mid);
          graph::add(dat[i].y, dat[i].x, mid);
        }
        ++j;
      }
    }
    if (graph::dijkstra() <= len)
      ans = mid, l = mid + 1;
    else
      r = mid - 1;
  }
  puts("YES");
  for (int i = 1, j = 1; i <= m; ++i) {
    if (dat[i].z)
      printf("%d %d %d\n", dat[i].x, dat[i].y, dat[i].z);
    else {
      if (j < num)
        printf("%d %d %d\n", dat[i].x, dat[i].y, 1);
      else if (j == num)
        printf("%d %d %d\n", dat[i].x, dat[i].y, ans);
      else
        printf("%d %d %d\n", dat[i].x, dat[i].y, len + 1);
      ++j;
    }
  }
  return 0;
}
