#include <bits/stdc++.h>
using namespace std;
const long long INF = 1000000000000000;
const int MAXN = 1005;
struct qnode {
  int v;
  int c;
  qnode(int _v = 0, int _c = 0) : v(_v), c(_c) {}
  bool operator<(const qnode &r) const { return c > r.c; }
};
struct Edge {
  int v;
  long long cost;
  bool flag;
  Edge(int _v = 0, int _cost = 0, bool _flag = false)
      : v(_v), cost(_cost), flag(_flag) {}
};
vector<Edge> E[MAXN];
bool vis[MAXN];
long long dist[MAXN];
long long dist1[MAXN];
long long l;
void Dijkstra(int n, int start) {
  memset(vis, false, sizeof(vis));
  for (int i = 0; i < n; i++) {
    dist[i] = INF;
  }
  priority_queue<qnode> que;
  while (!que.empty()) {
    que.pop();
  }
  dist[start] = 0;
  que.push(qnode(start, 0));
  qnode tmp;
  while (!que.empty()) {
    tmp = que.top();
    que.pop();
    int u = tmp.v;
    if (vis[u]) {
      continue;
    }
    vis[u] = true;
    for (int i = 0; i < E[u].size(); i++) {
      int v = E[tmp.v][i].v;
      int cost = E[u][i].cost;
      if (cost == 0) {
        continue;
      }
      if (!vis[v] && dist[v] > dist[u] + cost) {
        dist[v] = dist[u] + cost;
        que.push(qnode(v, dist[v]));
      }
    }
  }
}
void Dijkstra1(int n, int start) {
  memset(vis, false, sizeof(vis));
  for (int i = 0; i < n; i++) {
    dist1[i] = INF;
  }
  priority_queue<qnode> que;
  while (!que.empty()) {
    que.pop();
  }
  dist1[start] = 0;
  que.push(qnode(start, 0));
  qnode tmp;
  while (!que.empty()) {
    tmp = que.top();
    que.pop();
    int u = tmp.v;
    if (vis[u]) {
      continue;
    }
    vis[u] = true;
    for (int i = 0; i < E[u].size(); i++) {
      int v = E[tmp.v][i].v;
      long long cost = E[u][i].cost;
      if (cost == 0) {
        long long tmpp = l - dist1[u] - dist[v];
        if (tmpp <= 0) {
          tmpp = 1;
        }
        cost = E[u][i].cost = tmpp;
        for (int kk = 0; kk < E[v].size(); kk++) {
          if (E[v][kk].v == u) {
            E[v][kk].cost = tmpp;
          }
        }
      }
      if (!vis[v] && dist1[v] > dist1[u] + cost) {
        dist1[v] = dist1[u] + cost;
        que.push(qnode(v, dist1[v]));
      }
    }
  }
}
void addedge(int u, int v, int w, bool flag) {
  E[u].push_back(Edge(v, w, flag));
}
int a[10001], b[10001];
int main() {
  int n, m, s, t;
  while (~scanf("%d%d%lld%d%d", &n, &m, &l, &s, &t)) {
    for (int i = 0; i < n; i++) {
      E[i].clear();
    }
    for (int i = 0; i < m; i++) {
      long long c;
      scanf("%d%d%lld", &a[i], &b[i], &c);
      addedge(a[i], b[i], c, true);
      addedge(b[i], a[i], c, false);
    }
    Dijkstra(n, t);
    if (dist[s] < l) {
      printf("NO\n");
    } else {
      Dijkstra1(n, s);
      if (dist1[t] != l) {
        printf("NO\n");
      } else {
        printf("YES\n");
        for (int i = 0; i < n; i++) {
          for (int j = 0; j < E[i].size(); j++) {
            if (E[i][j].flag == true)
              printf("%d %d %lld\n", i, E[i][j].v, E[i][j].cost);
          }
        }
      }
    }
  }
  return 0;
}
