/*************************************************************************
    > In god we trust
    > File Name: B.cpp
************************************************************************/
const bool debug = false;
#include <cstdio>
#include <iostream>
#include <cmath>
#include <stack>
#include <queue>
#include <climits>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <algorithm>
#include <stdarg.h>
using namespace std;
#define per(i,a,n) for(int i=n-1;i>=a;--i)
#define rep(i,a,n) for(int i=a;i<n;++i)
#define erep(i,a,n) for(int i=a;i<=n;++i)
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> PII;
#define lc(o) (o<<1)
#define rc(o) (o<<1|1)
ll powmod(ll a,ll b, ll MOD) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void buginfo(const char* f, ...) {if(!debug)return;va_list al; va_start(al, f);vprintf(f, al);va_end(al);}
/*------------------ head-------------------*/
const int maxn = 1e3 + 10;
const ll inf = 1ll<<60;
const ll maxw = 1e18+10;
int n, m, L, s, t;

struct Edge {
    int from, to;
    ll w;
};

struct HeapNode {
    ll d;
    int u;
    bool operator < (const HeapNode& rhs) const {
        return d > rhs.d;
    }
};

struct Dijkstra {
    int n, m, p[maxn];
    ll d[maxn];
    vector<Edge> edges;
    vector<int> G[maxn];
    vector<int> zeros; /*edges with zeros*/
    bool done[maxn];

    void init(int n) {
        this->n = n;
        rep(i, 0, n) G[i].clear();
        edges.clear();
    }

    void setw(ll x) {
        for(int i: zeros) {
            edges[i].w = x;
        }
    }

    void add_edge(int from, int to, ll w) {
        edges.pb((Edge){from, to, w});
        edges.pb((Edge){to, from, w});
        m = edges.size();
        G[from].pb(m-2);
        G[to].pb(m-1);
        if (w == 0) { zeros.pb(m-1); zeros.pb(m-2);}
    }

    ll dijkstra(int s, int t) {
        priority_queue<HeapNode> Q;
        rep(i, 0, n) d[i] = inf;
        d[s] = 0;
        memset(done, 0, sizeof(done));
        Q.push((HeapNode){0, s});
        while(!Q.empty()) {
            HeapNode x = Q.top(); Q.pop();
            int u = x.u;
            if (done[u]) continue;
            done[u] = true;
            rep(i, 0, G[u].size()) {
                Edge& e = edges[G[u][i]];
                if (d[e.to] > d[u] + e.w) {
                    d[e.to] = d[u] + e.w;
                    p[e.to] = G[u][i];
                    Q.push((HeapNode){d[e.to], e.to});
                }
            }
        }
        return d[t];
    }

    void ksprint() {
        printf("YES\n");
        for(int i=0; i<edges.size(); i+=2) {
            Edge& e = edges[i];
            printf("%d %d %lld\n", e.from, e.to, e.w);
        }
    }
} sp;

int main() {
#ifdef ROACH_ONLINE_JUDGE
    freopen("B.txt", "r", stdin);
#endif
    scanf("%d%d%d%d%d", &n, &m, &L, &s, &t);
    sp.init(n);
    rep(i, 0, m) {
        int d1, d2, d3; scanf("%d%d%d", &d1, &d2, &d3);
        sp.add_edge(d1, d2, d3);
    }

    /*sp.setw(0);
    if (sp.dijkstra(s, t) > L) return 0*printf("NO\n");
    sp.setw(maxw);
    if (sp.dijkstra(s, t) < L) return 0*printf("NO\n");*/

    ll fst = 0, lst = maxw;
    while(fst < lst) {
        ll md = (fst+lst)/2;
        sp.setw(md);
        ll j = sp.dijkstra(s, t);
        if (j==L)
        { sp.ksprint(); return 0;}
        else if (j<L) {
            fst = md + 1;
        } else {
            lst = md;
        }
    }

    sp.setw(fst);
    if (sp.dijkstra(s, t) != L) printf("NO\n");

    return 0;
}


/*************************************************************************
  > In god we trust
  > File Name: B.cpp
 ************************************************************************/
const bool debug = false;
#include <cstdio>
#include <iostream>
#include <cmath>
#include <stack>
#include <queue>
#include <assert.h>
#include <climits>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <algorithm>
#include <stdarg.h>
using namespace std;
#define per(i,a,n) for(int i=n-1;i>=a;--i)
#define rep(i,a,n) for(int i=a;i<n;++i)
#define erep(i,a,n) for(int i=a;i<=n;++i)
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> PII;
#define lc(o) (o<<1)
#define rc(o) (o<<1|1)
ll powmod(ll a,ll b, ll MOD) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void buginfo(const char* f, ...) {if(!debug)return;va_list al; va_start(al, f);vprintf(f, al);va_end(al);}
/*------------------ head-------------------*/
const int maxn = 1e3 + 10;
const ll inf = 1e15;
const ll maxw = 1e9+10;
int n, m, L, s, t;

struct Edge {
    int from, to;
    ll w;
};

struct HeapNode {
    ll d;
    int u;
    bool operator < (const HeapNode& rhs) const {
        return d > rhs.d;
    }
};

struct Dijkstra {
    int n, m, p[maxn], s, t;
    bool done[maxn];
    ll d[maxn];
    vector<Edge> edges;
    vector<int> G[maxn], G1[maxn];
    vector<int> zeros; /*edges with zeros*/

    void init(int n, int s, int t) {
        this->n = n;
        rep(i, 0, n) G[i].clear();
        edges.clear();
        this->s = s;
        this->t = t;
    }

    void setw(ll x) {
        for(int i: zeros) {
            edges[i].w = x;
        }
    }

    void setw_s(int id, ll x) {
        edges[id].w = x;
        edges[id^1].w = x;
    }

    void add_edge(int from, int to, ll w) {
        edges.pb((Edge){from, to, w});
        edges.pb((Edge){to, from, w});
        m = edges.size();
        G[from].pb(m-2);
        G[to].pb(m-1);
        if (w==0) {
            zeros.pb(m-1); zeros.pb(m-2);
            G1[from].pb(m-2);
            G1[to].pb(m-1);
        }
    }

    ll dijkstra() {
        priority_queue<HeapNode> Q;
        rep(i, 0, n) d[i] = inf;
        d[s] = 0;
        memset(done, 0, sizeof(done));
        Q.push((HeapNode){0, s});
        while(!Q.empty()) {
            HeapNode x = Q.top(); Q.pop();
            int u = x.u;
            if (done[u]) continue;
            done[u] = true;
            rep(i, 0, G[u].size()) {
                Edge& e = edges[G[u][i]];
                if (d[e.to] > d[u] + e.w) {
                    d[e.to] = d[u] + e.w;
                    p[e.to] = G[u][i];
                    Q.push((HeapNode){d[e.to], e.to});
                }
            }
        }
        return d[t];
    }

    ll dijkstra1(int u) {
        priority_queue<HeapNode> Q;
        memset(done, 0, sizeof(done));
        Q.push((HeapNode){d[u], u});
        while(!Q.empty()) {
            HeapNode x = Q.top(); Q.pop();
            int u = x.u;
            if (done[u]) continue;
            done[u] = true;
            rep(i, 0, G1[u].size()) {
                Edge& e = edges[G1[u][i]];
                if (d[e.to] > d[u] + e.w) {
                    d[e.to] = d[u] + e.w;
                    p[e.to] = G[u][i];
                    Q.push((HeapNode){d[e.to], e.to});
                }
            }
        }
        return d[t];
    }

    void ksprint() {
        printf("YES\n");
        for(int i=0; i<edges.size(); i+=2) {
            Edge& e = edges[i];
            printf("%d %d %lld\n", e.from, e.to, e.w);
        }
    }

    void check(int id) {
        setw_s(id, min(maxw, L-dijkstra1(id)+1));
        ll now = dijkstra1(id);

        if (now == L) {
            ksprint();
            exit(0);
        } else setw_s(id, maxw);
    }
} sp;

int main() {
#ifdef ROACH_ONLINE_JUDGE
    freopen("B.txt", "r", stdin);
#endif
    scanf("%d%d%d%d%d", &n, &m, &L, &s, &t);
    sp.init(n, s, t);
    rep(i, 0, m) {
        int d1, d2, d3; scanf("%d%d%d", &d1, &d2, &d3);
        sp.add_edge(d1, d2, d3);
    }

    if (sp.dijkstra() == L) { sp.ksprint(); return 0;}
    sp.setw(maxw);
    if (sp.dijkstra() < L) return 0*printf("NO\n");
    sp.setw(1);
    if (sp.dijkstra() > L) return 0*printf("NO\n");

    for(int d: sp.zeros) sp.check(d);

    return 0 * printf("NO\n");
}


/*************************************************************************
    > In god we trust
    > File Name: B.cpp
************************************************************************/
const bool debug = false;
#include <cstdio>
#include <iostream>
#include <cmath>
#include <stack>
#include <queue>
#include <climits>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <algorithm>
#include <stdarg.h>
using namespace std;
#define per(i,a,n) for(int i=n-1;i>=a;--i)
#define rep(i,a,n) for(int i=a;i<n;++i)
#define erep(i,a,n) for(int i=a;i<=n;++i)
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> PII;
#define lc(o) (o<<1)
#define rc(o) (o<<1|1)
ll powmod(ll a,ll b, ll MOD) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void buginfo(const char* f, ...) {if(!debug)return;va_list al; va_start(al, f);vprintf(f, al);va_end(al);}
/*------------------ head-------------------*/
const int maxn = 1e3 + 10;
const ll inf = 1e14 + 10;
const int maxw = 1e9+10;
int n, m, L, s, t;

struct Edge {
    int from, to, w;
};

struct HeapNode {
    ll d;
    int u;
    bool operator < (const HeapNode& rhs) const {
        return d > rhs.d;
    }
};

struct Dijkstra {
    int n, m, p[maxn];
    ll d[maxn];
    vector<Edge> edges;
    vector<int> G[maxn];
    vector<int> zeros; /*edges with zeros*/
    bool done[maxn];

    void init(int n) {
        this->n = n;
        rep(i, 0, n) G[i].clear();
        edges.clear();
    }

    void setw(int x) {
        for(int i: zeros) {
            edges[i].w = x;
        }
    }

    void add_edge(int from, int to, int w) {
        edges.pb((Edge){from, to, w});
        edges.pb((Edge){to, from, w});
        m = edges.size();
        G[from].pb(m-2);
        G[to].pb(m-1);
        if (w == 0) { zeros.pb(m-1); zeros.pb(m-2);}
    }

    int dijkstra(int s, int t) {
        priority_queue<HeapNode> Q;
        rep(i, 0, n) d[i] = inf;
        d[s] = 0;
        memset(done, 0, sizeof(done));
        Q.push((HeapNode){0, s});
        while(!Q.empty()) {
            HeapNode x = Q.top(); Q.pop();
            int u = x.u;
            if (done[u]) continue;
            done[u] = true;
            rep(i, 0, G[u].size()) {
                Edge& e = edges[G[u][i]];
                if (d[e.to] > d[u] + e.w) {
                    d[e.to] = d[u] + e.w;
                    p[e.to] = G[u][i];
                    Q.push((HeapNode){d[e.to], e.to});
                }
            }
        }
        return d[t];
    }

    void ksprint() {
        printf("YES\n");
        for(int i=0; i<edges.size(); i+=2) {
            Edge& e = edges[i];
            printf("%d %d %d\n", e.from, e.to, e.w);
        }
    }
} sp;

int main() {
#ifdef ROACH_ONLINE_JUDGE
    freopen("B.txt", "r", stdin);
#endif
    scanf("%d%d%d%d%d", &n, &m, &L, &s, &t);
    sp.init(n);
    rep(i, 0, m) {
        int d1, d2, d3; scanf("%d%d%d", &d1, &d2, &d3);
        sp.add_edge(d1, d2, d3);
    }

    sp.setw(0);
    if (sp.dijkstra(s, t) > L) return 0*printf("NO\n");
    sp.setw(maxw);
    if (sp.dijkstra(s, t) < L) return 0*printf("NO\n");

    int fst = 0, lst = maxw;
    while(fst < lst) {
        int md = (fst+lst)/2;
        sp.setw(md);
        int j = sp.dijkstra(s, t);
        if (j==L)
        { sp.ksprint(); return 0;}
        else if (j<L) {
            fst = md + 1;
        } else {
            lst = md;
        }
    }

    sp.setw(fst);
    if (sp.dijkstra(s, t) != L) printf("NO\n");

    return 0;
}


/*************************************************************************
  > In god we trust
  > File Name: B.cpp
 ************************************************************************/
const bool debug = false;
#include <cstdio>
#include <iostream>
#include <cmath>
#include <stack>
#include <queue>
#include <assert.h>
#include <climits>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <algorithm>
#include <stdarg.h>
using namespace std;
#define per(i,a,n) for(int i=n-1;i>=a;--i)
#define rep(i,a,n) for(int i=a;i<n;++i)
#define erep(i,a,n) for(int i=a;i<=n;++i)
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> PII;
#define lc(o) (o<<1)
#define rc(o) (o<<1|1)
ll powmod(ll a,ll b, ll MOD) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void buginfo(const char* f, ...) {if(!debug)return;va_list al; va_start(al, f);vprintf(f, al);va_end(al);}
/*------------------ head-------------------*/
const int maxn = 1e3 + 10;
const ll inf = 1ll<<60;
const ll maxw = 1e15+10;
int n, m, L, s, t;

struct Edge {
    int from, to;
    ll w;
};

struct HeapNode {
    ll d;
    int u;
    bool operator < (const HeapNode& rhs) const {
        return d > rhs.d;
    }
};

struct Dijkstra {
    int n, m, p[maxn];
    bool done[maxn];
    ll d[maxn];
    vector<Edge> edges;
    vector<int> G[maxn];
    set<int> zeros; /*edges with zeros*/

    void init(int n) {
        this->n = n;
        rep(i, 0, n) G[i].clear();
        edges.clear();
    }

    void setw(ll x) {
        for(int i: zeros) {
            edges[i].w = x;
        }
    }

    void setw_s(int id, ll x) {
        edges[id].w = x;
        edges[id^1].w = x;
    }

    void add_edge(int from, int to, ll w) {
        edges.pb((Edge){from, to, w});
        edges.pb((Edge){to, from, w});
        m = edges.size();
        G[from].pb(m-2);
        G[to].pb(m-1);
        if (w == 0) { zeros.insert(m-1); zeros.insert(m-2);}
    }

    ll dijkstra(int s, int t) {
        priority_queue<HeapNode> Q;
        rep(i, 0, n) d[i] = inf;
        d[s] = 0;
        memset(done, 0, sizeof(done));
        Q.push((HeapNode){0, s});
        while(!Q.empty()) {
            HeapNode x = Q.top(); Q.pop();
            int u = x.u;
            if (done[u]) continue;
            done[u] = true;
            rep(i, 0, G[u].size()) {
                Edge& e = edges[G[u][i]];
                if (d[e.to] > d[u] + e.w) {
                    d[e.to] = d[u] + e.w;
                    p[e.to] = G[u][i];
                    Q.push((HeapNode){d[e.to], e.to});
                }
            }
        }
        return d[t];
    }

    void ksprint() {
        printf("YES\n");
        for(int i=0; i<edges.size(); i+=2) {
            Edge& e = edges[i];
            printf("%d %d %lld\n", e.from, e.to, e.w);
        }
    }

    void check(int id) {
        setw_s(id, min(maxw, L-dijkstra(s, t)+1));
        ll now = dijkstra(s, t);

        if (now == L) {
            ksprint();
            exit(0);
        } else if (now < L) {
            setw_s(id, maxw);
        } else {
            setw_s(id, 1);
        }
    }
} sp;

int main() {
#ifdef ROACH_ONLINE_JUDGE
    freopen("B.txt", "r", stdin);
#endif
    scanf("%d%d%d%d%d", &n, &m, &L, &s, &t);
    sp.init(n);
    rep(i, 0, m) {
        int d1, d2, d3; scanf("%d%d%d", &d1, &d2, &d3);
        sp.add_edge(d1, d2, d3);
    }

    sp.setw(maxw);
    if (sp.dijkstra(s, t) < L) return 0*printf("NO\n");
    sp.setw(1);
    if (sp.dijkstra(s, t) > L) return 0*printf("NO\n");

    for(int d: sp.zeros)
        sp.check(d);

    return 0 * printf("NO\n");
}


/*************************************************************************
    > In god we trust
    > File Name: B.cpp
************************************************************************/
const bool debug = false;
#include <cstdio>
#include <iostream>
#include <cmath>
#include <stack>
#include <queue>
#include <climits>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <algorithm>
#include <stdarg.h>
using namespace std;
#define per(i,a,n) for(int i=n-1;i>=a;--i)
#define rep(i,a,n) for(int i=a;i<n;++i)
#define erep(i,a,n) for(int i=a;i<=n;++i)
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> PII;
#define lc(o) (o<<1)
#define rc(o) (o<<1|1)
ll powmod(ll a,ll b, ll MOD) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void buginfo(const char* f, ...) {if(!debug)return;va_list al; va_start(al, f);vprintf(f, al);va_end(al);}
/*------------------ head-------------------*/
const int maxn = 1e3 + 10;
const ll inf = 1ll<<60;
const int maxw = 1e18+10;
int n, m, L, s, t;

struct Edge {
    int from, to;
    ll w;
};

struct HeapNode {
    ll d;
    int u;
    bool operator < (const HeapNode& rhs) const {
        return d > rhs.d;
    }
};

struct Dijkstra {
    int n, m, p[maxn];
    ll d[maxn];
    vector<Edge> edges;
    vector<int> G[maxn];
    vector<int> zeros; /*edges with zeros*/
    bool done[maxn];

    void init(int n) {
        this->n = n;
        rep(i, 0, n) G[i].clear();
        edges.clear();
    }

    void setw(ll x) {
        for(int i: zeros) {
            edges[i].w = x;
        }
    }

    void add_edge(int from, int to, int w) {
        edges.pb((Edge){from, to, w});
        edges.pb((Edge){to, from, w});
        m = edges.size();
        G[from].pb(m-2);
        G[to].pb(m-1);
        if (w == 0) { zeros.pb(m-1); zeros.pb(m-2);}
    }

    ll dijkstra(int s, int t) {
        priority_queue<HeapNode> Q;
        rep(i, 0, n) d[i] = inf;
        d[s] = 0;
        memset(done, 0, sizeof(done));
        Q.push((HeapNode){0, s});
        while(!Q.empty()) {
            HeapNode x = Q.top(); Q.pop();
            int u = x.u;
            if (done[u]) continue;
            done[u] = true;
            rep(i, 0, G[u].size()) {
                Edge& e = edges[G[u][i]];
                if (d[e.to] > d[u] + e.w) {
                    d[e.to] = d[u] + e.w;
                    p[e.to] = G[u][i];
                    Q.push((HeapNode){d[e.to], e.to});
                }
            }
        }
        return d[t];
    }

    void ksprint() {
        printf("YES\n");
        for(int i=0; i<edges.size(); i+=2) {
            Edge& e = edges[i];
            printf("%d %d %lld\n", e.from, e.to, e.w);
        }
    }
} sp;

int main() {
#ifdef ROACH_ONLINE_JUDGE
    freopen("B.txt", "r", stdin);
#endif
    scanf("%d%d%d%d%d", &n, &m, &L, &s, &t);
    sp.init(n);
    rep(i, 0, m) {
        int d1, d2, d3; scanf("%d%d%d", &d1, &d2, &d3);
        sp.add_edge(d1, d2, d3);
    }

    sp.setw(0);
    if (sp.dijkstra(s, t) > L) return 0*printf("NO\n");
    sp.setw(maxw);
    if (sp.dijkstra(s, t) < L) return 0*printf("NO\n");

    int fst = 0, lst = maxw;
    while(fst < lst) {
        ll md = (fst+lst)/2;
        sp.setw(md);
        ll j = sp.dijkstra(s, t);
        if (j==L)
        { sp.ksprint(); return 0;}
        else if (j<L) {
            fst = md + 1;
        } else {
            lst = md;
        }
    }

    sp.setw(fst);
    if (sp.dijkstra(s, t) != L) printf("NO\n");

    return 0;
}


/*************************************************************************
  > In god we trust
  > File Name: B.cpp
 ************************************************************************/
const bool debug = false;
#include <cstdio>
#include <iostream>
#include <cmath>
#include <stack>
#include <queue>
#include <assert.h>
#include <climits>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <algorithm>
#include <stdarg.h>
using namespace std;
#define per(i,a,n) for(int i=n-1;i>=a;--i)
#define rep(i,a,n) for(int i=a;i<n;++i)
#define erep(i,a,n) for(int i=a;i<=n;++i)
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> PII;
#define lc(o) (o<<1)
#define rc(o) (o<<1|1)
ll powmod(ll a,ll b, ll MOD) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void buginfo(const char* f, ...) {if(!debug)return;va_list al; va_start(al, f);vprintf(f, al);va_end(al);}
/*------------------ head-------------------*/
const int maxn = 1e3 + 10;
const ll inf = 1ll<<60;
const ll maxw = 1e15+10;
int n, m, L, s, t;

struct Edge {
    int from, to;
    ll w;
};

struct HeapNode {
    ll d;
    int u;
    bool operator < (const HeapNode& rhs) const {
        return d > rhs.d;
    }
};

struct Dijkstra {
    int n, m, p[maxn];
    bool done[maxn];
    ll d[maxn];
    vector<Edge> edges;
    vector<int> G[maxn];
    set<int> zeros; /*edges with zeros*/

    void init(int n) {
        this->n = n;
        rep(i, 0, n) G[i].clear();
        edges.clear();
    }

    void setw(ll x) {
        for(int i: zeros) {
            edges[i].w = x;
        }
    }

    void setw_s(int id, ll x) {
        edges[id].w = x;
        edges[id^1].w = x;
    }

    void add_edge(int from, int to, ll w) {
        edges.pb((Edge){from, to, w});
        edges.pb((Edge){to, from, w});
        m = edges.size();
        G[from].pb(m-2);
        G[to].pb(m-1);
        if (w == 0) { zeros.insert(m-1); zeros.insert(m-2);}
    }

    ll dijkstra(int s, int t) {
        priority_queue<HeapNode> Q;
        rep(i, 0, n) d[i] = inf;
        d[s] = 0;
        memset(done, 0, sizeof(done));
        Q.push((HeapNode){0, s});
        while(!Q.empty()) {
            HeapNode x = Q.top(); Q.pop();
            int u = x.u;
            if (done[u]) continue;
            done[u] = true;
            rep(i, 0, G[u].size()) {
                Edge& e = edges[G[u][i]];
                if (d[e.to] > d[u] + e.w) {
                    d[e.to] = d[u] + e.w;
                    p[e.to] = G[u][i];
                    Q.push((HeapNode){d[e.to], e.to});
                }
            }
        }
        return d[t];
    }

    void ksprint() {
        printf("YES\n");
        for(int i=0; i<edges.size(); i+=2) {
            Edge& e = edges[i];
            printf("%d %d %lld\n", e.from, e.to, e.w);
        }
    }

    void check(int id) {
        setw_s(id, min(maxw, L-dijkstra(s, t)+1));
        ll now = dijkstra(s, t);

        if (now == L) {
            ksprint();
            exit(0);
        } else setw_s(id, maxw);
    }
} sp;

int main() {
#ifdef ROACH_ONLINE_JUDGE
    freopen("B.txt", "r", stdin);
#endif
    scanf("%d%d%d%d%d", &n, &m, &L, &s, &t);
    sp.init(n);
    rep(i, 0, m) {
        int d1, d2, d3; scanf("%d%d%d", &d1, &d2, &d3);
        sp.add_edge(d1, d2, d3);
    }

    if (sp.dijkstra(s, t) == L) { sp.ksprint(); return 0;}
    sp.setw(maxw);
    if (sp.dijkstra(s, t) < L) return 0*printf("NO\n");
    sp.setw(1);
    if (sp.dijkstra(s, t) > L) return 0*printf("NO\n");

    for(int d: sp.zeros)
        sp.check(d);

    return 0 * printf("NO\n");
}


/*************************************************************************
    > In god we trust
    > File Name: B.cpp
************************************************************************/
const bool debug = false;
#include <cstdio>
#include <iostream>
#include <cmath>
#include <stack>
#include <queue>
#include <climits>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <algorithm>
#include <stdarg.h>
using namespace std;
#define per(i,a,n) for(int i=n-1;i>=a;--i)
#define rep(i,a,n) for(int i=a;i<n;++i)
#define erep(i,a,n) for(int i=a;i<=n;++i)
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> PII;
#define lc(o) (o<<1)
#define rc(o) (o<<1|1)
ll powmod(ll a,ll b, ll MOD) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void buginfo(const char* f, ...) {if(!debug)return;va_list al; va_start(al, f);vprintf(f, al);va_end(al);}
/*------------------ head-------------------*/
const int maxn = 1e3 + 10;
const ll inf = 1e14 + 10;
const int maxw = 1e9+10;
int n, m, L, s, t;
struct Edge {
    int from, to, w;
};
struct HeapNode {
    ll d;
    int u;
    bool operator < (const HeapNode& rhs) const {
        return d > rhs.d;
    }
};
struct Dijkstra {
    int n, m, p[maxn], pv;
    ll d[maxn];
    vector<Edge> edges;
    vector<int> G[maxn];
    bool done[maxn];

    void init(int n) {
        this->n = n;
        rep(i, 0, n) G[i].clear();
        edges.clear();
    }

    void add_edge(int from, int to, int w) {
        edges.pb((Edge){from, to, w});
        m = edges.size();
        G[from].pb(m-1);
    }

    int dijkstra(int s, int t) {
        priority_queue<HeapNode> Q;
        rep(i, 0, n) d[i] = inf;
        d[s] = 0;
        memset(done, 0, sizeof(done));
        Q.push((HeapNode){0, s});
        while(!Q.empty()) {
            HeapNode x = Q.top(); Q.pop();
            int u = x.u;
            if (done[u]) continue;
            done[u] = true;
            rep(i, 0, G[u].size()) {
                Edge& e = edges[G[u][i]];
                int cw = (e.w==0) ? pv : e.w;
                if (cw == maxw) continue;
                if (d[e.to] > d[u] + cw) {
                    d[e.to] = d[u] + cw;
                    p[e.to] = G[u][i];
                    Q.push((HeapNode){d[e.to], e.to});
                }
            }
        }
        return d[t];
    }

    void ksprint() {
        printf("YES\n");
        for(Edge& e: edges) {
            int cw = (e.w==0) ? pv: e.w;
            printf("%d %d %d\n", e.from, e.to, cw);
        }
    }
} sp;

int main() {
#ifdef ROACH_ONLINE_JUDGE
    freopen("B.txt", "r", stdin);
#endif
    scanf("%d%d%d%d%d", &n, &m, &L, &s, &t);
    sp.init(n);
    rep(i, 0, m) {
        int d1, d2, d3; scanf("%d%d%d", &d1, &d2, &d3);
        sp.add_edge(d1, d2, d3);
    }

    sp.pv = 0;
    if (sp.dijkstra(s, t) > L) return 0*printf("NO\n");
    sp.pv = maxw;
    if (sp.dijkstra(s, t) < L) return 0*printf("NO\n");

    int fst = 0, lst = maxw;
    while(fst < lst) {
        int md = (fst+lst)/2;
        sp.pv = md;
        int j = sp.dijkstra(s, t);
        if (j==L) { sp.ksprint(); return 0;}
        else if (j<L) {
            fst = md + 1;
        } else {
            lst = md;
        }
    }

    return 0;
}


/*************************************************************************
    > In god we trust
    > File Name: B.cpp
************************************************************************/
const bool debug = false;
#include <cstdio>
#include <iostream>
#include <cmath>
#include <stack>
#include <queue>
#include <climits>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <algorithm>
#include <stdarg.h>
using namespace std;
#define per(i,a,n) for(int i=n-1;i>=a;--i)
#define rep(i,a,n) for(int i=a;i<n;++i)
#define erep(i,a,n) for(int i=a;i<=n;++i)
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> PII;
#define lc(o) (o<<1)
#define rc(o) (o<<1|1)
ll powmod(ll a,ll b, ll MOD) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void buginfo(const char* f, ...) {if(!debug)return;va_list al; va_start(al, f);vprintf(f, al);va_end(al);}
/*------------------ head-------------------*/
const int maxn = 1e3 + 10;
const ll inf = 1ll<<60;
const ll maxw = 1e15+10;
int n, m, L, s, t;

struct Edge {
    int from, to;
    ll w;
};

struct HeapNode {
    ll d;
    int u;
    bool operator < (const HeapNode& rhs) const {
        return d > rhs.d;
    }
};

struct Dijkstra {
    int n, m, p[maxn];
    bool done[maxn];
    ll d[maxn];
    vector<Edge> edges;
    vector<int> G[maxn];
    vector<int> zeros; /*edges with zeros*/

    void init(int n) {
        this->n = n;
        rep(i, 0, n) G[i].clear();
        edges.clear();
    }

    void setw(ll x) {
        for(int i: zeros) {
            edges[i].w = x;
        }
    }

    void add_edge(int from, int to, ll w) {
        edges.pb((Edge){from, to, w});
        edges.pb((Edge){to, from, w});
        m = edges.size();
        G[from].pb(m-2);
        G[to].pb(m-1);
        if (w == 0) { zeros.pb(m-1); zeros.pb(m-2);}
    }

    ll dijkstra(int s, int t) {
        priority_queue<HeapNode> Q;
        rep(i, 0, n) d[i] = inf;
        d[s] = 0;
        memset(done, 0, sizeof(done));
        Q.push((HeapNode){0, s});
        while(!Q.empty()) {
            HeapNode x = Q.top(); Q.pop();
            int u = x.u;
            if (done[u]) continue;
            done[u] = true;
            rep(i, 0, G[u].size()) {
                Edge& e = edges[G[u][i]];
                if (d[e.to] > d[u] + e.w) {
                    d[e.to] = d[u] + e.w;
                    p[e.to] = G[u][i];
                    Q.push((HeapNode){d[e.to], e.to});
                }
            }
        }
        return d[t];
    }

    set<int> getpath(int s, int t) {
        set<int> path;
        int x = t;
        while(1) {
            path.insert(x);
            int fa = edges[x].from;
            if (fa == s) break;
            x = p[fa];
        }
        return path;
    }

    void ksprint(int s, int t, ll cnt = 0) {
        set<int> path = getpath(s, t);
        printf("YES\n");
        for(int i=0; i<edges.size(); i+=2) {
            Edge& e = edges[i];
            if (cnt > 0 && path.count(i) > 0) {
                ++e.w; --cnt;
            }
            printf("%d %d %lld\n", e.from, e.to, e.w);
        }
    }
} sp;

int main() {
#ifdef ROACH_ONLINE_JUDGE
    freopen("B.txt", "r", stdin);
#endif
    scanf("%d%d%d%d%d", &n, &m, &L, &s, &t);
    sp.init(n);
    rep(i, 0, m) {
        int d1, d2, d3; scanf("%d%d%d", &d1, &d2, &d3);
        sp.add_edge(d1, d2, d3);
    }

    sp.setw(1);
    if (sp.dijkstra(s, t) > L) return 0*printf("NO\n");
    sp.setw(maxw);
    if (sp.dijkstra(s, t) < L) return 0*printf("NO\n");

    ll fst = 1, lst = maxw;
    while(fst+1 < lst) {
        ll md = (fst+lst)/2;
        sp.setw(md);
        ll j = sp.dijkstra(s, t);
        if (j==L)
        { sp.ksprint(s, t); return 0;}
        else if (j<L) {
            fst = md + 1;
        } else {
            lst = md;
        }
    }

    sp.setw(fst);
    ll cnt = L - sp.dijkstra(s, t);
    sp.ksprint(s, t, cnt);

    return 0;
}


/*************************************************************************
    > In god we trust
    > File Name: B.cpp
************************************************************************/
const bool debug = false;
#include <cstdio>
#include <iostream>
#include <cmath>
#include <stack>
#include <queue>
#include <assert.h>
#include <climits>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <algorithm>
#include <stdarg.h>
using namespace std;
#define per(i,a,n) for(int i=n-1;i>=a;--i)
#define rep(i,a,n) for(int i=a;i<n;++i)
#define erep(i,a,n) for(int i=a;i<=n;++i)
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> PII;
#define lc(o) (o<<1)
#define rc(o) (o<<1|1)
ll powmod(ll a,ll b, ll MOD) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void buginfo(const char* f, ...) {if(!debug)return;va_list al; va_start(al, f);vprintf(f, al);va_end(al);}
/*------------------ head-------------------*/
const int maxn = 1e3 + 10;
const ll inf = 1ll<<60;
const ll maxw = 1e15+10;
int n, m, L, s, t;

struct Edge {
    int from, to;
    ll w;
};

struct HeapNode {
    ll d;
    int u;
    bool operator < (const HeapNode& rhs) const {
        return d > rhs.d;
    }
};

struct Dijkstra {
    int n, m, p[maxn];
    bool done[maxn];
    ll d[maxn];
    vector<Edge> edges;
    vector<int> G[maxn];
    set<int> zeros; /*edges with zeros*/

    void init(int n) {
        this->n = n;
        rep(i, 0, n) G[i].clear();
        edges.clear();
    }

    void setw(ll x) {
        for(int i: zeros) {
            edges[i].w = x;
        }
    }

    void add_edge(int from, int to, ll w) {
        edges.pb((Edge){from, to, w});
        edges.pb((Edge){to, from, w});
        m = edges.size();
        G[from].pb(m-2);
        G[to].pb(m-1);
        if (w == 0) { zeros.insert(m-1); zeros.insert(m-2);}
    }

    ll dijkstra(int s, int t) {
        priority_queue<HeapNode> Q;
        rep(i, 0, n) d[i] = inf;
        d[s] = 0;
        memset(done, 0, sizeof(done));
        Q.push((HeapNode){0, s});
        while(!Q.empty()) {
            HeapNode x = Q.top(); Q.pop();
            int u = x.u;
            if (done[u]) continue;
            done[u] = true;
            rep(i, 0, G[u].size()) {
                Edge& e = edges[G[u][i]];
                if (d[e.to] > d[u] + e.w) {
                    d[e.to] = d[u] + e.w;
                    p[e.to] = G[u][i];
                    Q.push((HeapNode){d[e.to], e.to});
                }
            }
        }
        return d[t];
    }

    set<int> getpath(int s, int t) {
        set<int> path;
        int x = t;
        while(1) {
            path.insert(x);
            int fa = edges[x].from;
            if (fa == s) break;
            x = p[fa];
        }
        return path;
    }

    void ksprint(int s, int t, ll cnt = 0) {
        set<int> path = getpath(s, t);
        printf("YES\n");
        for(int i=0; i<edges.size(); i+=2) {
            Edge& e = edges[i];
            if (cnt > 0 && path.count(i) > 0 && zeros.count(i)>0) {
                ++e.w; --cnt;
            }
            printf("%d %d %lld\n", e.from, e.to, e.w);
        }
    }
} sp;

int main() {
#ifdef ROACH_ONLINE_JUDGE
    freopen("B.txt", "r", stdin);
#endif
    scanf("%d%d%d%d%d", &n, &m, &L, &s, &t);
    sp.init(n);
    rep(i, 0, m) {
        int d1, d2, d3; scanf("%d%d%d", &d1, &d2, &d3);
        sp.add_edge(d1, d2, d3);
    }

    sp.setw(1);
    if (sp.dijkstra(s, t) > L) return 0*printf("NO\n");
    sp.setw(maxw);
    if (sp.dijkstra(s, t) < L) return 0*printf("NO\n");

    ll fst = 1, lst = maxw;
    while(fst < lst) {
        ll md = (fst+lst)/2;
        sp.setw(md);
        ll j = sp.dijkstra(s, t);
        if (j==L)
        { sp.ksprint(s, t); return 0;}
        else if (j<L) {
            fst = md + 1;
        } else {
            lst = md;
        }
    }

    --fst;
    sp.setw(fst);
    ll cnt = L - sp.dijkstra(s, t);
    assert(cnt > 0);
    sp.ksprint(s, t, cnt);

    return 0;
}


/*************************************************************************
    > In god we trust
    > File Name: B.cpp
************************************************************************/
const bool debug = false;
#include <cstdio>
#include <iostream>
#include <cmath>
#include <stack>
#include <queue>
#include <climits>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <algorithm>
#include <stdarg.h>
using namespace std;
#define per(i,a,n) for(int i=n-1;i>=a;--i)
#define rep(i,a,n) for(int i=a;i<n;++i)
#define erep(i,a,n) for(int i=a;i<=n;++i)
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> PII;
#define lc(o) (o<<1)
#define rc(o) (o<<1|1)
ll powmod(ll a,ll b, ll MOD) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void buginfo(const char* f, ...) {if(!debug)return;va_list al; va_start(al, f);vprintf(f, al);va_end(al);}
/*------------------ head-------------------*/
const int maxn = 1e3 + 10;
const ll inf = 1ll<<60;
const ll maxw = 1e15+10;
int n, m, L, s, t;

struct Edge {
    int from, to;
    ll w;
};

struct HeapNode {
    ll d;
    int u;
    bool operator < (const HeapNode& rhs) const {
        return d > rhs.d;
    }
};

struct Dijkstra {
    int n, m, p[maxn];
    ll d[maxn];
    vector<Edge> edges;
    vector<int> G[maxn];
    vector<int> zeros; /*edges with zeros*/
    bool done[maxn];

    void init(int n) {
        this->n = n;
        rep(i, 0, n) G[i].clear();
        edges.clear();
    }

    void setw(ll x) {
        for(int i: zeros) {
            edges[i].w = x;
        }
    }

    void add_edge(int from, int to, ll w) {
        edges.pb((Edge){from, to, w});
        edges.pb((Edge){to, from, w});
        m = edges.size();
        G[from].pb(m-2);
        G[to].pb(m-1);
        if (w == 0) { zeros.pb(m-1); zeros.pb(m-2);}
    }

    ll dijkstra(int s, int t) {
        priority_queue<HeapNode> Q;
        rep(i, 0, n) d[i] = inf;
        d[s] = 0;
        memset(done, 0, sizeof(done));
        Q.push((HeapNode){0, s});
        while(!Q.empty()) {
            HeapNode x = Q.top(); Q.pop();
            int u = x.u;
            if (done[u]) continue;
            done[u] = true;
            rep(i, 0, G[u].size()) {
                Edge& e = edges[G[u][i]];
                if (d[e.to] > d[u] + e.w) {
                    d[e.to] = d[u] + e.w;
                    p[e.to] = G[u][i];
                    Q.push((HeapNode){d[e.to], e.to});
                }
            }
        }
        return d[t];
    }

    void ksprint(ll cnt = 0) {
        printf("YES\n");
        for(int i=0; i<edges.size(); i+=2) {
            Edge& e = edges[i];
            if (cnt>0) { ++e.w; --cnt;}
            printf("%d %d %lld\n", e.from, e.to, e.w);
        }
    }
} sp;

int main() {
#ifdef ROACH_ONLINE_JUDGE
    freopen("B.txt", "r", stdin);
#endif
    scanf("%d%d%d%d%d", &n, &m, &L, &s, &t);
    sp.init(n);
    rep(i, 0, m) {
        int d1, d2, d3; scanf("%d%d%d", &d1, &d2, &d3);
        sp.add_edge(d1, d2, d3);
    }

    sp.setw(0);
    if (sp.dijkstra(s, t) > L) return 0*printf("NO\n");
    sp.setw(maxw);
    if (sp.dijkstra(s, t) < L) return 0*printf("NO\n");

    ll fst = 0, lst = maxw;
    while(fst+1 < lst) {
        ll md = (fst+lst)/2;
        sp.setw(md);
        ll j = sp.dijkstra(s, t);
        if (j==L)
        { sp.ksprint(); return 0;}
        else if (j<L) {
            fst = md + 1;
        } else {
            lst = md;
        }
    }

    sp.setw(fst);
    ll cnt = L - sp.dijkstra(s, t);
    sp.ksprint(cnt);

    return 0;
}


/*************************************************************************
    > In god we trust
    > File Name: B.cpp
************************************************************************/
const bool debug = false;
#include <cstdio>
#include <iostream>
#include <cmath>
#include <stack>
#include <queue>
#include <climits>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <algorithm>
#include <stdarg.h>
using namespace std;
#define per(i,a,n) for(int i=n-1;i>=a;--i)
#define rep(i,a,n) for(int i=a;i<n;++i)
#define erep(i,a,n) for(int i=a;i<=n;++i)
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> PII;
#define lc(o) (o<<1)
#define rc(o) (o<<1|1)
ll powmod(ll a,ll b, ll MOD) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void buginfo(const char* f, ...) {if(!debug)return;va_list al; va_start(al, f);vprintf(f, al);va_end(al);}
/*------------------ head-------------------*/
const int maxn = 1e3 + 10;
const ll inf = 1ll<<60;
const int maxw = 1e18+10;
int n, m, L, s, t;

struct Edge {
    int from, to;
    ll w;
};

struct HeapNode {
    ll d;
    int u;
    bool operator < (const HeapNode& rhs) const {
        return d > rhs.d;
    }
};

struct Dijkstra {
    int n, m, p[maxn];
    ll d[maxn];
    vector<Edge> edges;
    vector<int> G[maxn];
    vector<int> zeros; /*edges with zeros*/
    bool done[maxn];

    void init(int n) {
        this->n = n;
        rep(i, 0, n) G[i].clear();
        edges.clear();
    }

    void setw(ll x) {
        for(int i: zeros) {
            edges[i].w = x;
        }
    }

    void add_edge(int from, int to, ll w) {
        edges.pb((Edge){from, to, w});
        edges.pb((Edge){to, from, w});
        m = edges.size();
        G[from].pb(m-2);
        G[to].pb(m-1);
        if (w == 0) { zeros.pb(m-1); zeros.pb(m-2);}
    }

    ll dijkstra(int s, int t) {
        priority_queue<HeapNode> Q;
        rep(i, 0, n) d[i] = inf;
        d[s] = 0;
        memset(done, 0, sizeof(done));
        Q.push((HeapNode){0, s});
        while(!Q.empty()) {
            HeapNode x = Q.top(); Q.pop();
            int u = x.u;
            if (done[u]) continue;
            done[u] = true;
            rep(i, 0, G[u].size()) {
                Edge& e = edges[G[u][i]];
                if (d[e.to] > d[u] + e.w) {
                    d[e.to] = d[u] + e.w;
                    p[e.to] = G[u][i];
                    Q.push((HeapNode){d[e.to], e.to});
                }
            }
        }
        return d[t];
    }

    void ksprint() {
        printf("YES\n");
        for(int i=0; i<edges.size(); i+=2) {
            Edge& e = edges[i];
            printf("%d %d %lld\n", e.from, e.to, e.w);
        }
    }
} sp;

int main() {
#ifdef ROACH_ONLINE_JUDGE
    freopen("B.txt", "r", stdin);
#endif
    scanf("%d%d%d%d%d", &n, &m, &L, &s, &t);
    sp.init(n);
    rep(i, 0, m) {
        int d1, d2, d3; scanf("%d%d%d", &d1, &d2, &d3);
        sp.add_edge(d1, d2, d3);
    }

    sp.setw(0);
    if (sp.dijkstra(s, t) > L) return 0*printf("NO\n");
    sp.setw(maxw);
    if (sp.dijkstra(s, t) < L) return 0*printf("NO\n");

    ll fst = 0, lst = maxw;
    while(fst < lst) {
        ll md = (fst+lst)/2;
        sp.setw(md);
        ll j = sp.dijkstra(s, t);
        if (j==L)
        { sp.ksprint(); return 0;}
        else if (j<L) {
            fst = md + 1;
        } else {
            lst = md;
        }
    }

    sp.setw(fst);
    if (sp.dijkstra(s, t) != L) printf("NO\n");

    return 0;
}


/*************************************************************************
  > In god we trust
  > File Name: B.cpp
 ************************************************************************/
const bool debug = false;
#include <cstdio>
#include <iostream>
#include <cmath>
#include <stack>
#include <queue>
#include <assert.h>
#include <climits>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <algorithm>
#include <stdarg.h>
using namespace std;
#define per(i,a,n) for(int i=n-1;i>=a;--i)
#define rep(i,a,n) for(int i=a;i<n;++i)
#define erep(i,a,n) for(int i=a;i<=n;++i)
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> PII;
#define lc(o) (o<<1)
#define rc(o) (o<<1|1)
ll powmod(ll a,ll b, ll MOD) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void buginfo(const char* f, ...) {if(!debug)return;va_list al; va_start(al, f);vprintf(f, al);va_end(al);}
/*------------------ head-------------------*/
const int maxn = 1e3 + 10;
const ll inf = 1e15;
const ll maxw = 1e9+10;
int n, m, L, s, t;

struct Edge {
    int from, to;
    ll w;
};

struct HeapNode {
    ll d;
    int u;
    bool operator < (const HeapNode& rhs) const {
        return d > rhs.d;
    }
};

struct Dijkstra {
    int n, m, p[maxn];
    bool done[maxn];
    ll d[maxn];
    vector<Edge> edges;
    vector<int> G[maxn];
    vector<int> zeros; /*edges with zeros*/

    void init(int n) {
        this->n = n;
        rep(i, 0, n) G[i].clear();
        edges.clear();
    }

    void setw(ll x) {
        for(int i: zeros) {
            edges[i].w = x;
        }
    }

    void setw_s(int id, ll x) {
        edges[id].w = x;
        edges[id^1].w = x;
    }

    void add_edge(int from, int to, ll w) {
        edges.pb((Edge){from, to, w});
        edges.pb((Edge){to, from, w});
        m = edges.size();
        G[from].pb(m-2);
        G[to].pb(m-1);
        if (w==0) { zeros.pb(m-1); zeros.pb(m-2);}
    }

    ll dijkstra(int s, int t) {
        priority_queue<HeapNode> Q;
        rep(i, 0, n) d[i] = inf;
        d[s] = 0;
        memset(done, 0, sizeof(done));
        Q.push((HeapNode){0, s});
        while(!Q.empty()) {
            HeapNode x = Q.top(); Q.pop();
            int u = x.u;
            if (done[u]) continue;
            done[u] = true;
            rep(i, 0, G[u].size()) {
                Edge& e = edges[G[u][i]];
                if (d[e.to] > d[u] + e.w) {
                    d[e.to] = d[u] + e.w;
                    p[e.to] = G[u][i];
                    Q.push((HeapNode){d[e.to], e.to});
                }
            }
        }
        return d[t];
    }

    void ksprint() {
        printf("YES\n");
        for(int i=0; i<edges.size(); i+=2) {
            Edge& e = edges[i];
            printf("%d %d %lld\n", e.from, e.to, e.w);
        }
    }

    void check(int id) {
        setw_s(id, min(maxw, L-dijkstra(s, t)+1));
        ll now = dijkstra(s, t);

        if (now == L) {
            ksprint();
            exit(0);
        } else setw_s(id, maxw);
    }
} sp;

int main() {
#ifdef ROACH_ONLINE_JUDGE
    freopen("B.txt", "r", stdin);
#endif
    scanf("%d%d%d%d%d", &n, &m, &L, &s, &t);
    sp.init(n);
    rep(i, 0, m) {
        int d1, d2, d3; scanf("%d%d%d", &d1, &d2, &d3);
        sp.add_edge(d1, d2, d3);
    }

    if (sp.dijkstra(s, t) == L) { sp.ksprint(); return 0;}
    sp.setw(maxw);
    if (sp.dijkstra(s, t) < L) return 0*printf("NO\n");
    sp.setw(1);
    if (sp.dijkstra(s, t) > L) return 0*printf("NO\n");

    for(int d: sp.zeros) sp.check(d);

    return 0 * printf("NO\n");
}


/*************************************************************************
  > In god we trust
  > File Name: B.cpp
 ************************************************************************/
const bool debug = false;
#include <cstdio>
#include <iostream>
#include <cmath>
#include <stack>
#include <queue>
#include <assert.h>
#include <climits>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <algorithm>
#include <stdarg.h>
using namespace std;
#define per(i,a,n) for(int i=n-1;i>=a;--i)
#define rep(i,a,n) for(int i=a;i<n;++i)
#define erep(i,a,n) for(int i=a;i<=n;++i)
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> PII;
#define lc(o) (o<<1)
#define rc(o) (o<<1|1)
ll powmod(ll a,ll b, ll MOD) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void buginfo(const char* f, ...) {if(!debug)return;va_list al; va_start(al, f);vprintf(f, al);va_end(al);}
/*------------------ head-------------------*/
const int maxn = 1e3 + 10;
const ll inf = 1e15;
const ll maxw = 1e9;
int n, m, L, s, t;

struct Edge {
    int from, to;
    ll w;
};

struct HeapNode {
    ll d;
    int u;
    bool operator < (const HeapNode& rhs) const {
        return d > rhs.d;
    }
};

struct Dijkstra {
    int n, m, p[maxn], s, t;
    bool done[maxn];
    ll d[maxn];
    vector<Edge> edges;
    vector<int> G[maxn], G1[maxn];
    vector<int> zeros; /*edges with zeros*/

    void init(int n, int s, int t) {
        this->n = n;
        rep(i, 0, n) G[i].clear();
        edges.clear();
        this->s = s;
        this->t = t;
    }

    void add_edge(int from, int to, ll w) {
        bool z = (w==0);
        w = max(1ll, w);
        edges.pb((Edge){from, to, w});
        edges.pb((Edge){to, from, w});
        m = edges.size();
        G[from].pb(m-2);
        G[to].pb(m-1);
        if (z) {
            zeros.pb(m-1); zeros.pb(m-2);
        }
    }

    ll dijkstra() {
        priority_queue<HeapNode> Q;
        rep(i, 0, n) d[i] = inf;
        d[s] = 0;
        memset(done, 0, sizeof(done));
        Q.push((HeapNode){0, s});
        while(!Q.empty()) {
            HeapNode x = Q.top(); Q.pop();
            int u = x.u;
            if (done[u]) continue;
            done[u] = true;
            rep(i, 0, G[u].size()) {
                Edge& e = edges[G[u][i]];
                if (d[e.to] > d[u] + e.w) {
                    d[e.to] = d[u] + e.w;
                    p[e.to] = G[u][i];
                    Q.push((HeapNode){d[e.to], e.to});
                }
            }
        }
        return d[t];
    }

    void ksprint() {
        printf("YES\n");
        for(int i=0; i<edges.size(); i+=2) {
            Edge& e = edges[i];
            printf("%d %d %lld\n", e.from, e.to, e.w);
        }
    }

    ll check(ll sum) {
        for(int i: zeros) {
            edges[i].w = min(maxw, sum);
            sum -= edges[i].w - 1;
        }
        return dijkstra();
    }
} sp;

int main() {
#ifdef ROACH_ONLINE_JUDGE
    freopen("B.txt", "r", stdin);
#endif
    scanf("%d%d%d%d%d", &n, &m, &L, &s, &t);
    sp.init(n, s, t);
    rep(i, 0, m) {
        int d1, d2, d3; scanf("%d%d%d", &d1, &d2, &d3);
        sp.add_edge(d1, d2, d3);
    }

    ll l = (ll)sp.zeros.size(), r = inf;
    if (sp.check(l) > L || sp.check(r) < L)
        return 0 * printf("NO\n");

    while(l<r) {
        ll md = (l+r)/2;
        ll now = sp.check(md);
        if (now == L) {
            sp.ksprint();
            return 0;
        }
        else if (now < L) l = md+1;
        else r = md;
    }

    return 0;
}


#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> pii;
typedef pair<pii, int> piipi;

vector<int> g[1005];
LL dp[10005];
vector<piipi> orders;
vector<int> aw;

int sol(int s, int t){
	memset(dp, -1, sizeof(dp));
	dp[s] = 0;
	queue<int> q;
	q.push(s);
	while(!q.empty()){
		int u = q.front();
		q.pop();
		for(int i=0;i<g[u].size();i++){
			int idx = g[u][i];
			int v = orders[idx].first.first;
			if(u == v) v = orders[idx].first.second;
			int w = orders[idx].second;
			if(w == 0) w = 1;
			if(dp[v] == -1 || dp[v] > dp[u] + w){
				dp[v] = dp[u] + w;
				q.push(v);
			}
		}
	}
	return dp[t];
}

void printans(){
	printf("YES\n");
	for(int i=0;i<orders.size();i++){
		int a = orders[i].first.first;
		int b = orders[i].first.second;
		int c = orders[i].second;
		if(c == 0) c = 1;
		printf("%d %d %d\n", a, b, c);
	}
}

int main(){
	ios_base::sync_with_stdio(false), cin.tie(NULL);

	int n, m, L, s, t;
	cin >> n >> m >> L >> s >> t;
	for(int i=0;i<m;i++){
		int a, b, c;
		cin >> a >> b >> c;
		g[a].push_back(i);
		g[b].push_back(i);
		orders.push_back(piipi(pii(a, b), c));
		if(c == 0) aw.push_back(i);
	}
	LL check = sol(s, t);
	if(check > L){
		printf("NO\n");
		return 0;
	}
	else if(L == check){
		printans();
		return 0;
	}
	LL rem = L - check + 1;
	for(int i=0;i<aw.size();i++){
		int idx = aw[i];
		orders[idx].second = rem;
		check = sol(s, t);
		if(L == check){
			printans();
			return 0;
		}
		orders[idx].second = 1;
	}
	printf("NO\n");
}


#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> pii;
typedef pair<pii, int> piipi;

vector<int> g[1005];
LL dp[10005];
vector<piipi> orders;
vector<int> aw;

int sol(int s, int t){
	memset(dp, -1, sizeof(dp));
	dp[s] = 0;
	priority_queue<pii> q;
	q.push(pii(-dp[s], s));
	while(!q.empty()){
		int u = q.top().second;
		q.pop();
		for(int i=0;i<g[u].size();i++){
			int idx = g[u][i];
			int v = orders[idx].first.first;
			if(u == v) v = orders[idx].first.second;
			int w = orders[idx].second;
			if(w == 0) w = 1;
			if(dp[v] == -1 || dp[v] > dp[u] + w){
				dp[v] = dp[u] + w;
				q.push(pii(-dp[v], v));
			}
		}
	}
	return dp[t];
}

void printans(){
	printf("YES\n");
	for(int i=0;i<orders.size();i++){
		int a = orders[i].first.first;
		int b = orders[i].first.second;
		int c = orders[i].second;
		if(c == 0) c = 1;
		printf("%d %d %d\n", a, b, c);
	}
}

int main(){
	ios_base::sync_with_stdio(false), cin.tie(NULL);

	int n, m, L, s, t;
	cin >> n >> m >> L >> s >> t;
	for(int i=0;i<m;i++){
		int a, b, c;
		cin >> a >> b >> c;
		g[a].push_back(i);
		g[b].push_back(i);
		orders.push_back(piipi(pii(a, b), c));
		if(c == 0) aw.push_back(i);
	}
	LL check = sol(s, t);
	if(check > L){
		printf("NO\n");
		return 0;
	}
	else if(L == check){
		printans();
		return 0;
	}
	LL rem = L - check + 1;
	for(int i=0;i<aw.size();i++){
		int idx = aw[i];
		orders[idx].second = rem;
		check = sol(s, t);
		rem = L - check + 1;
		if(L == check){
			printans();
			return 0;
		}
	}
	printf("NO\n");
}


#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> pii;
typedef pair<LL, int> pli;
typedef pair<pii, int> piipi;

vector<int> g[1005];
LL dp[10005];
vector<piipi> orders;
vector<int> aw;

LL sol(int s, int t){
	memset(dp, -1, sizeof(dp));
	dp[s] = 0;
	priority_queue<pli> q;
	q.push(pli(-dp[s], s));
	while(!q.empty()){
		int u = q.top().second;
		q.pop();
		for(int i=0;i<g[u].size();i++){
			int idx = g[u][i];
			int v = orders[idx].first.first;
			if(u == v) v = orders[idx].first.second;
			int w = orders[idx].second;
			if(w == 0) w = 1;
			if(dp[v] == -1 || dp[v] > dp[u] + w){
				dp[v] = dp[u] + w;
				q.push(pli(-dp[v], v));
			}
		}
	}
	return dp[t];
}

void printans(){
	printf("YES\n");
	for(int i=0;i<orders.size();i++){
		int a = orders[i].first.first;
		int b = orders[i].first.second;
		int c = orders[i].second;
		if(c == 0) c = 1;
		printf("%d %d %d\n", a, b, c);
	}
}

int main(){
	ios_base::sync_with_stdio(false), cin.tie(NULL);

	int n, m, L, s, t;
	cin >> n >> m >> L >> s >> t;
	for(int i=0;i<m;i++){
		int a, b, c;
		cin >> a >> b >> c;
		g[a].push_back(i);
		g[b].push_back(i);
		orders.push_back(piipi(pii(a, b), c));
		if(c == 0) aw.push_back(i);
	}
	LL check = sol(s, t);
	if(check > L){
		printf("NO\n");
		return 0;
	}
	else if(L == check){
		printans();
		return 0;
	}
	LL rem = L - check + 1;
	for(int i=0;i<aw.size();i++){
		int idx = aw[i];
		orders[idx].second = rem;
		check = sol(s, t);
		rem = L - check + 1;
		if(L == check){
			printans();
			return 0;
		}
	}
	printf("NO\n");
}


#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> pii;
typedef pair<LL, int> pli;
typedef pair<pii, int> piipi;

vector<int> g[1005];
LL dp[10005];
vector<piipi> orders;
vector<int> aw;

int sol(int s, int t){
	memset(dp, -1, sizeof(dp));
	dp[s] = 0;
	priority_queue<pli> q;
	q.push(pli(-dp[s], s));
	while(!q.empty()){
		int u = q.top().second;
		q.pop();
		for(int i=0;i<g[u].size();i++){
			int idx = g[u][i];
			int v = orders[idx].first.first;
			if(u == v) v = orders[idx].first.second;
			int w = orders[idx].second;
			if(w == 0) w = 1;
			if(dp[v] == -1 || dp[v] > dp[u] + w){
				dp[v] = dp[u] + w;
				q.push(pli(-dp[v], v));
			}
		}
	}
	return dp[t];
}

void printans(){
	printf("YES\n");
	for(int i=0;i<orders.size();i++){
		int a = orders[i].first.first;
		int b = orders[i].first.second;
		int c = orders[i].second;
		if(c == 0) c = 1;
		printf("%d %d %d\n", a, b, c);
	}
}

int main(){
	ios_base::sync_with_stdio(false), cin.tie(NULL);

	int n, m, L, s, t;
	cin >> n >> m >> L >> s >> t;
	for(int i=0;i<m;i++){
		int a, b, c;
		cin >> a >> b >> c;
		g[a].push_back(i);
		g[b].push_back(i);
		orders.push_back(piipi(pii(a, b), c));
		if(c == 0) aw.push_back(i);
	}
	LL check = sol(s, t);
	if(check > L){
		printf("NO\n");
		return 0;
	}
	else if(L == check){
		printans();
		return 0;
	}
	LL rem = L - check + 1;
	for(int i=0;i<aw.size();i++){
		int idx = aw[i];
		orders[idx].second = rem;
		check = sol(s, t);
		rem = L - check + 1;
		if(L == check){
			printans();
			return 0;
		}
	}
	printf("NO\n");
}


#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> pii;
typedef pair<LL, int> pli;
typedef pair<pii, int> piipi;

vector<int> g[1005];
LL dp[1005];
vector<piipi> orders;
vector<int> aw;

LL sol(int s, int t){
	memset(dp, -1, sizeof(dp));
	dp[s] = 0;
	priority_queue<pli> q;
	q.push(pli(-dp[s], s));
	while(!q.empty()){
		int u = q.top().second;
		q.pop();
		for(int i=0;i<g[u].size();i++){
			int idx = g[u][i];
			int v = orders[idx].first.first;
			if(u == v) v = orders[idx].first.second;
			int w = orders[idx].second;
			if(w == 0) w = 1;
			if(dp[v] == -1 || dp[v] > dp[u] + w){
				dp[v] = dp[u] + w;
				q.push(pli(-dp[v], v));
			}
		}
	}
	return dp[t];
}

void printans(){
	printf("YES\n");
	for(int i=0;i<orders.size();i++){
		int a = orders[i].first.first;
		int b = orders[i].first.second;
		int c = orders[i].second;
		if(c == 0) c = 1;
		printf("%d %d %d\n", a, b, c);
	}
}

int main(){
	ios_base::sync_with_stdio(false), cin.tie(NULL);

	int n, m, L, s, t;
	cin >> n >> m >> L >> s >> t;
	for(int i=0;i<m;i++){
		int a, b, c;
		cin >> a >> b >> c;
		g[a].push_back(i);
		g[b].push_back(i);
		orders.push_back(piipi(pii(a, b), c));
		if(c == 0) aw.push_back(i);
	}
	LL check = sol(s, t);
	if(check > L){
		printf("NO\n");
		return 0;
	}
	else if(L == check){
		printans();
		return 0;
	}
	LL rem = L - check + 1;
	for(int i=0;i<aw.size();i++){
		int idx = aw[i];
		orders[idx].second = rem;
		check = sol(s, t);
		rem = L - check + 1;
		if(L == check){
			printans();
			return 0;
		}
	}
	printf("NO\n");
}


#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> pii;
typedef pair<LL, int> pli;
typedef pair<pii, int> piipi;

vector<int> g[1005];
LL dp[1005];
vector<piipi> orders;
vector<int> aw;

LL sol(int s, int t){
	memset(dp, -1, sizeof(dp));
	dp[s] = 0;
	priority_queue<pli> q;
	q.push(pli(-dp[s], s));
	while(!q.empty()){
		int u = q.top().second;
		q.pop();
		for(int i=0;i<g[u].size();i++){
			int idx = g[u][i];
			int v = orders[idx].first.first;
			if(u == v) v = orders[idx].first.second;
			int w = orders[idx].second;
			if(w == 0) w = 1;
			if(dp[v] == -1 || dp[v] > dp[u] + w){
				dp[v] = dp[u] + w;
				q.push(pli(-dp[v], v));
			}
		}
	}
	return dp[t];
}

void printans(){
	printf("YES\n");
	for(int i=0;i<orders.size();i++){
		int a = orders[i].first.first;
		int b = orders[i].first.second;
		int c = orders[i].second;
		if(c == 0) c = 1;
		printf("%d %d %d\n", a, b, c);
	}
}

int main(){
	ios_base::sync_with_stdio(false), cin.tie(NULL);

	int n, m, L, s, t;
	cin >> n >> m >> L >> s >> t;
	for(int i=0;i<m;i++){
		int a, b, c;
		cin >> a >> b >> c;
		g[a].push_back(i);
		g[b].push_back(i);
		orders.push_back(piipi(pii(a, b), c));
		if(c == 0) aw.push_back(i);
	}
	LL check = sol(s, t);
	if(check > L){
		printf("NO\n");
		return 0;
	}
	else if(L == check){
		printans();
		return 0;
	}

	int lo = 0, hi = aw.size()-1, ans = -1;
	while(lo <= hi){
		int mid = (lo+hi)/2;
		for(int i=0;i<=mid;i++) orders[aw[i]].second = 1;
		for(int i=mid+1;i<aw.size();i++) orders[aw[i]].second = 1e9;
		check = sol(s, t);

		if(check <= L) ans = mid, hi = mid-1;
		else lo = mid+1;
	}
	if(ans == -1) printf("NO\n");
	else{
		for(int i=0;i<=ans;i++) orders[aw[i]].second = 1;
		for(int i=ans+1;i<aw.size();i++) orders[aw[i]].second = 1e9;
		check = sol(s, t);
		orders[aw[ans]].second = L-check+1;
		check = sol(s, t);
		if(check == L) printans();
		else printf("NO\n");
	}
}


#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> pii;
typedef pair<pii, int> piipi;

vector<int> g[1005];
LL dp[10005];
vector<piipi> orders;
vector<int> aw;

int sol(int s, int t){
	memset(dp, -1, sizeof(dp));
	dp[s] = 0;
	queue<int> q;
	q.push(s);
	while(!q.empty()){
		int u = q.front();
		q.pop();
		for(int i=0;i<g[u].size();i++){
			int idx = g[u][i];
			int v = orders[idx].first.first;
			if(u == v) v = orders[idx].first.second;
			int w = orders[idx].second;
			if(w == 0) w = 1;
			if(dp[v] == -1 || dp[v] > dp[u] + w){
				dp[v] = dp[u] + w;
				q.push(v);
			}
		}
	}
	return dp[t];
}

void printans(){
	printf("YES\n");
	for(int i=0;i<orders.size();i++){
		int a = orders[i].first.first;
		int b = orders[i].first.second;
		int c = orders[i].second;
		if(c == 0) c = 1;
		printf("%d %d %d\n", a, b, c);
	}
}

int main(){
	ios_base::sync_with_stdio(false), cin.tie(NULL);

	int n, m, L, s, t;
	cin >> n >> m >> L >> s >> t;
	for(int i=0;i<m;i++){
		int a, b, c;
		cin >> a >> b >> c;
		g[a].push_back(i);
		g[b].push_back(i);
		orders.push_back(piipi(pii(a, b), c));
		if(c == 0) aw.push_back(i);
	}
	LL check = sol(s, t);
	if(check > L){
		printf("NO\n");
		return 0;
	}
	else if(L == check){
		printans();
		return 0;
	}
	LL rem = L - check + 1;
	for(int i=0;i<aw.size();i++){
		int idx = aw[i];
		orders[idx].second = rem;
		check = sol(s, t);
		orders[idx].second = 1;
		if(L == check){
			printans();
			return 0;
		}
	}
	printf("NO\n");
}


#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> pii;
typedef pair<pii, int> piipi;

vector<int> g[1005];
LL dp[10005];
vector<piipi> orders;
vector<int> aw;

int sol(int s, int t){
	memset(dp, -1, sizeof(dp));
	dp[s] = 0;
	priority_queue<pii> q;
	q.push(pii(-dp[s], s));
	while(!q.empty()){
		int u = q.top().second;
		q.pop();
		for(int i=0;i<g[u].size();i++){
			int idx = g[u][i];
			int v = orders[idx].first.first;
			if(u == v) v = orders[idx].first.second;
			int w = orders[idx].second;
			if(w == 0) w = 1;
			if(dp[v] == -1 || dp[v] > dp[u] + w){
				dp[v] = dp[u] + w;
				q.push(pii(-dp[v], v));
			}
		}
	}
	return dp[t];
}

void printans(){
	printf("YES\n");
	for(int i=0;i<orders.size();i++){
		int a = orders[i].first.first;
		int b = orders[i].first.second;
		int c = orders[i].second;
		if(c == 0) c = 1;
		printf("%d %d %d\n", a, b, c);
	}
}

int main(){
	ios_base::sync_with_stdio(false), cin.tie(NULL);

	int n, m, L, s, t;
	cin >> n >> m >> L >> s >> t;
	for(int i=0;i<m;i++){
		int a, b, c;
		cin >> a >> b >> c;
		g[a].push_back(i);
		g[b].push_back(i);
		orders.push_back(piipi(pii(a, b), c));
		if(c == 0) aw.push_back(i);
	}
	LL check = sol(s, t);
	if(check > L){
		printf("NO\n");
		return 0;
	}
	else if(L == check){
		printans();
		return 0;
	}
	LL rem = L - check + 1;
	for(int i=0;i<aw.size();i++){
		int idx = aw[i];
		orders[idx].second = rem;
		check = sol(s, t);
		if(L == check){
			printans();
			return 0;
		}
	}
	printf("NO\n");
}


#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> pii;
typedef pair<LL, int> pli;
typedef pair<pii, int> piipi;

vector<int> g[1005];
LL dp[10005];
vector<piipi> orders;
vector<int> aw;

LL sol(int s, int t){
	memset(dp, -1, sizeof(dp));
	dp[s] = 0;
	queue<int> q;
	q.push(s);
	while(!q.empty()){
		int u = q.front();
		q.pop();
		for(int i=0;i<g[u].size();i++){
			int idx = g[u][i];
			int v = orders[idx].first.first;
			if(u == v) v = orders[idx].first.second;
			int w = orders[idx].second;
			if(w == 0) w = 1;
			if(dp[v] == -1 || dp[v] > dp[u] + w){
				dp[v] = dp[u] + w;
				q.push(v);
			}
		}
	}
	return dp[t];
}

void printans(){
	printf("YES\n");
	for(int i=0;i<orders.size();i++){
		int a = orders[i].first.first;
		int b = orders[i].first.second;
		int c = orders[i].second;
		if(c == 0) c = 1;
		printf("%d %d %d\n", a, b, c);
	}
}

int main(){
	ios_base::sync_with_stdio(false), cin.tie(NULL);

	int n, m, L, s, t;
	cin >> n >> m >> L >> s >> t;
	for(int i=0;i<m;i++){
		int a, b, c;
		cin >> a >> b >> c;
		g[a].push_back(i);
		g[b].push_back(i);
		orders.push_back(piipi(pii(a, b), c));
		if(c == 0) aw.push_back(i);
	}
	LL check = sol(s, t);
	if(check > L){
		printf("NO\n");
		return 0;
	}
	else if(L == check){
		printans();
		return 0;
	}
	LL rem = L - check + 1;
	for(int i=0;i<aw.size();i++){
		int idx = aw[i];
		orders[idx].second = rem;
		check = sol(s, t);
		rem = L - check + 1;
		if(L == check){
			printans();
			return 0;
		}
	}
	printf("NO\n");
}


#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> pii;
typedef pair<pii, int> piipi;

vector<int> g[1005];
LL dp[10005];
vector<piipi> orders;
vector<int> aw;

int sol(int s, int t){
	memset(dp, -1, sizeof(dp));
	dp[s] = 0;
	queue<int> q;
	q.push(s);
	while(!q.empty()){
		int u = q.front();
		q.pop();
		for(int i=0;i<g[u].size();i++){
			int idx = g[u][i];
			int v = orders[idx].first.first;
			if(u == v) v = orders[idx].first.second;
			int w = orders[idx].second;
			if(w == 0) w = 1;
			if(dp[v] == -1 || dp[v] > dp[u] + w){
				dp[v] = dp[u] + w;
				q.push(v);
			}
		}
	}
	return dp[t];
}

void printans(){
	printf("YES\n");
	for(int i=0;i<orders.size();i++){
		int a = orders[i].first.first;
		int b = orders[i].first.second;
		int c = orders[i].second;
		if(c == 0) c = 1;
		printf("%d %d %d\n", a, b, c);
	}
}

int main(){
	ios_base::sync_with_stdio(false), cin.tie(NULL);

	int n, m, L, s, t;
	cin >> n >> m >> L >> s >> t;
	for(int i=0;i<m;i++){
		int a, b, c;
		cin >> a >> b >> c;
		g[a].push_back(i);
		g[b].push_back(i);
		orders.push_back(piipi(pii(a, b), c));
		if(c == 0) aw.push_back(i);
	}
	LL check = sol(s, t);
	if(check > L){
		printf("NO\n");
		return 0;
	}
	else if(L == check){
		printans();
		return 0;
	}
	LL rem = L - check + 1;
	for(int i=0;i<aw.size();i++){
		int idx = aw[i];
		orders[idx].second = rem;
		check = sol(s, t);
		rem = L - check + 1;
		if(L == check){
			printans();
			return 0;
		}
	}
	printf("NO\n");
}


#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> pii;
typedef pair<pii, int> piipi;

vector<int> g[1005];
LL dp[10005];
vector<piipi> orders;
vector<int> aw;

int sol(int s, int t){
	memset(dp, -1, sizeof(dp));
	dp[s] = 0;
	queue<int> q;
	q.push(s);
	while(!q.empty()){
		int u = q.front();
		q.pop();
		for(int i=0;i<g[u].size();i++){
			int idx = g[u][i];
			int v = orders[idx].first.first;
			if(u == v) v = orders[idx].first.second;
			int w = orders[idx].second;
			if(w == 0) w = 1;
			if(dp[v] == -1 || dp[v] > dp[u] + w){
				dp[v] = dp[u] + w;
				q.push(v);
			}
		}
	}
	return dp[t];
}

void printans(){
	printf("YES\n");
	for(int i=0;i<orders.size();i++){
		int a = orders[i].first.first;
		int b = orders[i].first.second;
		int c = orders[i].second;
		if(c == 0) c = 1;
		printf("%d %d %d\n", a, b, c);
	}
}

int main(){
	ios_base::sync_with_stdio(false), cin.tie(NULL);

	int n, m, L, s, t;
	cin >> n >> m >> L >> s >> t;
	for(int i=0;i<m;i++){
		int a, b, c;
		cin >> a >> b >> c;
		g[a].push_back(i);
		g[b].push_back(i);
		orders.push_back(piipi(pii(a, b), c));
		if(c == 0) aw.push_back(i);
	}
	LL check = sol(s, t);
	if(check > L){
		printf("NO\n");
		return 0;
	}
	else if(L == check){
		printans();
		return 0;
	}
	LL rem = L - check + 1;
	for(int i=0;i<aw.size();i++){
		int idx = aw[i];
		orders[idx].second = rem;
		check = sol(s, t);
		rem = L - check + 1;
		if(L == check){
			printans();
			return 0;
		}
	}
}


#include <bits/stdc++.h>
using namespace std;

#define fo(i,s,t) for(int i = s; i <= t; ++ i)
#define fd(i,s,t) for(int i = s; i >= t; -- i)
#define bf(i,s) for(int i = head[s]; i; i = e[i].next)
#define mp make_pair
#define fi first
#define se second
#define pii pair<int,int>
#define pb push_back
#define VI vector<int>
#define sf scanf
#define pf printf
#define fp freopen
#define SZ(x) ((int)(x).size())
// #define MPS
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
const int inf = 1<<30;
const ll INF = 1000000000000000000ll;
const db Inf = 1e20;
const db eps = 1e-9;

void gmax(int &a,int b){a = (a > b ? a : b);}
void gmin(int &a,int b){a = (a < b ? a : b);}

const int maxn = 1005;
const int maxm = 20050;

struct edge{int next, to, id; ll w; bool pp; edge(){pp=false;}}e[maxm];
int n, m, L, s, t, head[maxn], cnt;
ll dis[maxn], val;
bool inq[maxn];
struct Input{int u, v; ll w;}In[maxm];
VI reserve;

void link(int u,int v,ll w,int id,bool pp)
{
	++ cnt; e[cnt].next = head[u];
	e[cnt].to = v; head[u] = cnt;
	e[cnt].w = w; e[cnt].id = id;
	e[cnt].pp = pp;
}
ll dijkstra(int s,int t)
{
	priority_queue<pair<ll,int> > pq;
	fo(i,1,n) dis[i] = INF;
	dis[s] = 0; pq.push(mp(0ll,s));
	while(!pq.empty())
	{
		pair<ll,int> h = pq.top(); pq.pop();
		inq[h.se] = false;
		if(dis[h.se] > L) break;
		for(int i = head[h.se]; i; i = e[i].next)
			if(dis[e[i].to] > dis[h.se] + e[i].w)
			{
				dis[e[i].to] = dis[h.se] + e[i].w;
				if(!inq[e[i].to])
				{
					inq[e[i].to] = true;
					pq.push(mp(-dis[e[i].to], e[i].to));
				}
			}
	}
	return dis[t];
}
void modify(int x)
{
	if(x == s) return;
	for(int i = head[x]; i; i = e[i].next)
		if(dis[x] == dis[e[i].to] + e[i].w)
		{
			if(e[i].pp == true)
			{
				reserve.pb(e[i].id);
				In[e[i].id].w = 1;
			}
			modify(e[i].to);
			break;
		}
}
int main()
{
	#ifdef MPS
		fp("cf714b.in","r",stdin);
		fp("cf714b.out","w",stdout);
	#endif
	sf("%d%d%d%d%d",&n,&m,&L,&s,&t); ++ s; ++ t;
	fo(i,1,m)
	{
		int u, v, w; sf("%d%d%d",&u,&v,&w);
		++ u; ++ v;
		link(u, v, (w == 0 ? 1 : w), i, (w == 0)); link(v, u, (w == 0 ? 1 : w), i, (w == 0));
		In[i] = (struct Input){u, v, w};
	}
	reserve.pb(0);
	val = dijkstra(s, t);
	modify(t);
	fo(i,1,m)
	{
		In[i].w = (In[i].w == 0 ? INF : In[i].w);
		e[i*2-1].w = e[i*2].w = In[i].w;
	}
	for(auto p : reserve)
	{
		if(L-(val-1) == 0) continue;
		In[p].w = L - (val - 1);
		if(p) e[p*2-1].w = In[p].w; e[p*2].w = In[p].w;
		val = dijkstra(s, t);
		if(val == L)
		{
			if(n == 1000 && m == 8315) pf("%lld\n",val);
			pf("YES\n");
			fo(i,1,m)
				pf("%d %d %lld\n", In[i].u - 1, In[i].v - 1, In[i].w);
			return 0;
		}
		In[p].w = INF;
		if(p) e[p*2-1].w = In[p].w; e[p*2].w = In[p].w;
	}
	pf("NO\n");
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define fo(i,s,t) for(int i = s; i <= t; ++ i)
#define fd(i,s,t) for(int i = s; i >= t; -- i)
#define bf(i,s) for(int i = head[s]; i; i = e[i].next)
#define mp make_pair
#define fi first
#define se second
#define pii pair<int,int>
#define pb push_back
#define VI vector<int>
#define sf scanf
#define pf printf
#define fp freopen
#define SZ(x) ((int)(x).size())
// #define MPS
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
const int inf = 1<<30;
const ll INF = 1ll<<60;
const db Inf = 1e20;
const db eps = 1e-9;

void gmax(int &a,int b){a = (a > b ? a : b);}
void gmin(int &a,int b){a = (a < b ? a : b);}

const int maxn = 1005;
const int maxm = 20050;

struct edge{int next, to, id; ll w; bool pp; edge(){pp=false;}}e[maxm];
int n, m, L, s, t, head[maxn], cnt;
ll dis[maxn], val;
priority_queue<pair<ll,int> > pq;
bool inq[maxn];
struct Input{int u, v; ll w;}In[maxm];

void link(int u,int v,ll w,int id,bool pp)
{
	++ cnt; e[cnt].next = head[u];
	e[cnt].to = v; head[u] = cnt;
	e[cnt].w = w; e[cnt].id = id;
	e[cnt].pp = pp;
}
ll dijkstra(int s,int t)
{
	fo(i,1,n) dis[i] = INF;
	dis[s] = 0; pq.push(mp(0ll,s));
	while(!pq.empty())
	{
		pair<ll,int> h = pq.top(); pq.pop();
		inq[h.se] = false;
		for(int i = head[h.se]; i; i = e[i].next)
			if(e[i].w != -1 && dis[e[i].to] > dis[h.se] + e[i].w)
			{
				dis[e[i].to] = dis[h.se] + e[i].w;
				if(!inq[e[i].to])
				{
					inq[e[i].to] = true;
					pq.push(mp(-dis[e[i].to], e[i].to));
				}
			}
	}
	return dis[t];
}
void modify(int x, bool g=true)
{
	if(x == s) return;
	for(int i = head[x]; i; i = e[i].next)
		if(dis[x] == dis[e[i].to] + e[i].w)
		{
			if(e[i].pp == true)
			{
				if(g) In[e[i].id].w = L - (val - 1);
				else In[e[i].id].w = 1;
				g = false;
			}
			modify(e[i].to, g);
			break;
		}
}
int main()
{
	#ifdef MPS
		fp("cf714b.in","r",stdin);
		fp("cf714b.out","w",stdout);
	#endif
	sf("%d%d%d%d%d",&n,&m,&L,&s,&t); ++ s; ++ t;
	fo(i,1,m)
	{
		int u, v, w; sf("%d%d%d",&u,&v,&w);
		++ u; ++ v; w = (w == 0 ? -1 : w);
		link(u, v, w, i, (w == -1)); link(v, u, w, i, (w == -1));
		In[i] = (struct Input){u, v, w};
	}
	val = dijkstra(s, t);
	if(val < L) return 0 * pf("NO\n");
	if(val == L)
	{
		pf("YES\n");
		fo(i,1,m)
		{
			pf("%d %d ", In[i].u - 1, In[i].v - 1);
			if(In[i].w == -1) pf("%lld\n", 10000000000000ll);
			else pf("%d\n", In[i].w);
		}
		return 0;
	}
	cnt = 0; memset(head,0,sizeof(head));
	fo(i,1,m)
	{
		link(In[i].u, In[i].v, (In[i].w == -1 ? 1 : In[i].w), i, (In[i].w == -1));
		link(In[i].v, In[i].u, (In[i].w == -1 ? 1 : In[i].w), i, (In[i].w == -1));
	}
	val = dijkstra(s, t);
	if(val <= L)
	{
		modify(t);
		pf("YES\n");
		fo(i,1,m) pf("%d %d %lld\n", In[i].u - 1, In[i].v - 1, (In[i].w == -1 ? 10000000000001ll: 1ll*In[i].w));
		return 0;
	}
	pf("NO\n");
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define fo(i,s,t) for(int i = s; i <= t; ++ i)
#define fd(i,s,t) for(int i = s; i >= t; -- i)
#define bf(i,s) for(int i = head[s]; i; i = e[i].next)
#define mp make_pair
#define fi first
#define se second
#define pii pair<int,int>
#define pb push_back
#define VI vector<int>
#define sf scanf
#define pf printf
#define fp freopen
#define SZ(x) ((int)(x).size())
// #define MPS
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
const int inf = 1<<30;
const ll INF = 1000000000000000000ll;
const db Inf = 1e20;
const db eps = 1e-9;

void gmax(int &a,int b){a = (a > b ? a : b);}
void gmin(int &a,int b){a = (a < b ? a : b);}

const int maxn = 1005;
const int maxm = 20050;

struct edge{int next, to, id; ll w; bool pp; edge(){pp=false;}}e[maxm];
int n, m, L, s, t, head[maxn], cnt;
ll dis[maxn], val;
bool inq[maxn];
struct Input{int u, v; ll w;}In[maxm];
VI reserve;

void link(int u,int v,ll w,int id,bool pp)
{
	++ cnt; e[cnt].next = head[u];
	e[cnt].to = v; head[u] = cnt;
	e[cnt].w = w; e[cnt].id = id;
	e[cnt].pp = pp;
}
ll dijkstra(int s,int t)
{
	priority_queue<pair<ll,int> > pq;
	fo(i,1,n) dis[i] = INF;
	dis[s] = 0; pq.push(mp(0ll,s));
	while(!pq.empty())
	{
		pair<ll,int> h = pq.top(); pq.pop();
		inq[h.se] = false;
		if(h.se == t) break;
		if(dis[h.se] > L) continue;
		for(int i = head[h.se]; i; i = e[i].next)
			if(dis[e[i].to] > dis[h.se] + e[i].w)
			{
				dis[e[i].to] = dis[h.se] + e[i].w;
				if(!inq[e[i].to])
				{
					inq[e[i].to] = true;
					pq.push(mp(-dis[e[i].to], e[i].to));
				}
			}
	}
	return dis[t];
}
void modify(int x)
{
	if(x == s) return;
	for(int i = head[x]; i; i = e[i].next)
		if(dis[x] == dis[e[i].to] + e[i].w)
		{
			if(e[i].pp == true)
			{
				reserve.pb(e[i].id);
				In[e[i].id].w = 1;
			}
			modify(e[i].to);
			break;
		}
}
int main()
{
	#ifdef MPS
		fp("cf714b.in","r",stdin);
		fp("cf714b.out","w",stdout);
	#endif
	sf("%d%d%d%d%d",&n,&m,&L,&s,&t); ++ s; ++ t;
	fo(i,1,m)
	{
		int u, v, w; sf("%d%d%d",&u,&v,&w);
		++ u; ++ v;
		link(u, v, (w == 0 ? 1 : w), i, (w == 0)); link(v, u, (w == 0 ? 1 : w), i, (w == 0));
		In[i] = (struct Input){u, v, w};
	}
	reserve.pb(0);
	val = dijkstra(s, t);
	modify(t);
	fo(i,1,m)
	{
		In[i].w = (In[i].w == 0 ? INF : In[i].w);
		e[i*2-1].w = e[i*2].w = In[i].w;
	}
	for(auto p : reserve)
	{
		if(L-(val-1) == 0) continue;
		In[p].w = L - (val - 1);
		if(p) e[p*2-1].w = In[p].w; e[p*2].w = In[p].w;
		val = dijkstra(s, t);
		if(val == L)
		{
			pf("YES\n");
			fo(i,1,m)
				pf("%d %d %lld\n", In[i].u - 1, In[i].v - 1, In[i].w);
			return 0;
		}
		In[p].w = INF;
		if(p) e[p*2-1].w = In[p].w; e[p*2].w = In[p].w;
	}
	pf("NO\n");
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define fo(i,s,t) for(int i = s; i <= t; ++ i)
#define fd(i,s,t) for(int i = s; i >= t; -- i)
#define bf(i,s) for(int i = head[s]; i; i = e[i].next)
#define mp make_pair
#define fi first
#define se second
#define pii pair<int,int>
#define pb push_back
#define VI vector<int>
#define sf scanf
#define pf printf
#define fp freopen
#define SZ(x) ((int)(x).size())
// #define MPS
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
const int inf = 1<<30;
const ll INF = 1000000000000000000ll;
const db Inf = 1e20;
const db eps = 1e-9;

void gmax(int &a,int b){a = (a > b ? a : b);}
void gmin(int &a,int b){a = (a < b ? a : b);}

const int maxn = 1005;
const int maxm = 20050;

struct edge{int next, to, id; ll w; bool pp; edge(){pp=false;}}e[maxm];
int n, m, L, s, t, head[maxn], cnt;
ll dis[maxn], val;
priority_queue<pair<ll,int> > pq;
bool inq[maxn];
struct Input{int u, v; ll w;}In[maxm];
VI reserve;

void link(int u,int v,ll w,int id,bool pp)
{
	++ cnt; e[cnt].next = head[u];
	e[cnt].to = v; head[u] = cnt;
	e[cnt].w = w; e[cnt].id = id;
	e[cnt].pp = pp;
}
ll dijkstra(int s,int t)
{
	fo(i,1,n) dis[i] = INF;
	dis[s] = 0; pq.push(mp(0ll,s));
	while(!pq.empty())
	{
		pair<ll,int> h = pq.top(); pq.pop();
		inq[h.se] = false;
		for(int i = head[h.se]; i; i = e[i].next)
			if(dis[e[i].to] > dis[h.se] + e[i].w)
			{
				dis[e[i].to] = dis[h.se] + e[i].w;
				if(!inq[e[i].to])
				{
					inq[e[i].to] = true;
					pq.push(mp(-dis[e[i].to], e[i].to));
				}
			}
	}
	return dis[t];
}
void modify(int x)
{
	if(x == s) return;
	for(int i = head[x]; i; i = e[i].next)
		if(dis[x] == dis[e[i].to] + e[i].w)
		{
			if(e[i].pp == true)
			{
				reserve.pb(e[i].id);
				In[e[i].id].w = 1;
			}
			modify(e[i].to);
			break;
		}
}
int main()
{
	#ifdef MPS
		fp("cf714b.in","r",stdin);
		fp("cf714b.out","w",stdout);
	#endif
	sf("%d%d%d%d%d",&n,&m,&L,&s,&t); ++ s; ++ t;
	fo(i,1,m)
	{
		int u, v, w; sf("%d%d%d",&u,&v,&w);
		++ u; ++ v;
		link(u, v, (w == 0 ? 1 : w), i, (w == 0)); link(v, u, (w == 0 ? 1 : w), i, (w == 0));
		In[i] = (struct Input){u, v, w};
	}
	reserve.pb(0);
	val = dijkstra(s, t);
	modify(t);
	fo(i,1,m)
	{
		In[i].w = (In[i].w == 0 ? INF : In[i].w);
		e[i*2-1].w = e[i*2].w = In[i].w;
	}
	for(auto p : reserve)
	{
		if(L-(val-1) == 0) continue;
		In[p].w = L - (val - 1);
		e[p*2-1].w = In[p].w; e[p*2].w = In[p].w;
		val = dijkstra(s, t);
		if(val == L)
		{
			pf("YES\n");
			fo(i,1,m) pf("%d %d %lld\n", In[i].u - 1, In[i].v - 1, In[i].w);
			return 0;
		}
		In[p].w = INF;
		e[p*2-1].w = In[p].w; e[p*2].w = In[p].w;
	}
	pf("NO\n");
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define fo(i,s,t) for(int i = s; i <= t; ++ i)
#define fd(i,s,t) for(int i = s; i >= t; -- i)
#define bf(i,s) for(int i = head[s]; i; i = e[i].next)
#define mp make_pair
#define fi first
#define se second
#define pii pair<int,int>
#define pb push_back
#define VI vector<int>
#define sf scanf
#define pf printf
#define fp freopen
#define SZ(x) ((int)(x).size())
// #define MPS
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
const int inf = 1<<30;
const ll INF = 1000000000000000000ll;
const db Inf = 1e20;
const db eps = 1e-9;

void gmax(int &a,int b){a = (a > b ? a : b);}
void gmin(int &a,int b){a = (a < b ? a : b);}

const int maxn = 1005;
const int maxm = 20050;

struct edge{int next, to, id; ll w; bool pp; edge(){pp=false;}}e[maxm];
int n, m, L, s, t, head[maxn], cnt;
ll dis[maxn], val;
bool inq[maxn];
struct Input{int u, v; ll w;}In[maxm];
VI reserve;

void link(int u,int v,ll w,int id,bool pp)
{
	++ cnt; e[cnt].next = head[u];
	e[cnt].to = v; head[u] = cnt;
	e[cnt].w = w; e[cnt].id = id;
	e[cnt].pp = pp;
}
ll dijkstra(int s,int t)
{
	priority_queue<pair<ll,int> > pq;
	fo(i,1,n) dis[i] = INF;
	dis[s] = 0; pq.push(mp(0ll,s));
	while(!pq.empty())
	{
		pair<ll,int> h = pq.top(); pq.pop();
		inq[h.se] = false;
		if(dis[h.se] > L) break;
		for(int i = head[h.se]; i; i = e[i].next)
			if(dis[e[i].to] > dis[h.se] + e[i].w)
			{
				dis[e[i].to] = dis[h.se] + e[i].w;
				if(!inq[e[i].to])
				{
					inq[e[i].to] = true;
					pq.push(mp(-dis[e[i].to], e[i].to));
				}
			}
	}
	return dis[t];
}
void modify(int x)
{
	if(x == s) return;
	for(int i = head[x]; i; i = e[i].next)
		if(dis[x] == dis[e[i].to] + e[i].w)
		{
			if(e[i].pp == true)
			{
				reserve.pb(e[i].id);
				In[e[i].id].w = 1;
			}
			modify(e[i].to);
			break;
		}
}
int main()
{
	#ifdef MPS
		fp("cf714b.in","r",stdin);
		fp("cf714b.out","w",stdout);
	#endif
	sf("%d%d%d%d%d",&n,&m,&L,&s,&t); ++ s; ++ t;
	fo(i,1,m)
	{
		int u, v, w; sf("%d%d%d",&u,&v,&w);
		++ u; ++ v;
		link(u, v, (w == 0 ? 1 : w), i, (w == 0)); link(v, u, (w == 0 ? 1 : w), i, (w == 0));
		In[i] = (struct Input){u, v, w};
	}
	reserve.pb(0);
	val = dijkstra(s, t);
	modify(t);
	fo(i,1,m)
	{
		In[i].w = (In[i].w == 0 ? INF : In[i].w);
		e[i*2-1].w = e[i*2].w = In[i].w;
	}
	for(auto p : reserve)
	{
		if(L-(val-1) == 0) continue;
		In[p].w = L - (val - 1);
		if(p) e[p*2-1].w = In[p].w; e[p*2].w = In[p].w;
		val = dijkstra(s, t);
		if(val == L)
		{
			pf("YES\n");
			fo(i,1,m)
				pf("%d %d %lld\n", In[i].u - 1, In[i].v - 1, In[i].w);
			return 0;
		}
		In[p].w = INF;
		if(p) e[p*2-1].w = In[p].w; e[p*2].w = In[p].w;
	}
	pf("NO\n");
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define fo(i,s,t) for(int i = s; i <= t; ++ i)
#define fd(i,s,t) for(int i = s; i >= t; -- i)
#define bf(i,s) for(int i = head[s]; i; i = e[i].next)
#define mp make_pair
#define fi first
#define se second
#define pii pair<int,int>
#define pb push_back
#define VI vector<int>
#define sf scanf
#define pf printf
#define fp freopen
#define SZ(x) ((int)(x).size())
// #define MPS
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
const int inf = 1<<30;
const ll INF = 1000000000000000000ll;
const db Inf = 1e20;
const db eps = 1e-9;

void gmax(int &a,int b){a = (a > b ? a : b);}
void gmin(int &a,int b){a = (a < b ? a : b);}

const int maxn = 1005;
const int maxm = 20050;

struct edge{int next, to, id; ll w; bool pp; edge(){pp=false;}}e[maxm];
int n, m, L, s, t, head[maxn], cnt;
ll dis[maxn], val;
bool inq[maxn];
struct Input{int u, v; ll w;}In[maxm];
VI reserve;

void link(int u,int v,ll w,int id,bool pp)
{
	++ cnt; e[cnt].next = head[u];
	e[cnt].to = v; head[u] = cnt;
	e[cnt].w = w; e[cnt].id = id;
	e[cnt].pp = pp;
}
ll dijkstra(int s,int t)
{
	priority_queue<pair<ll,int> > pq;
	fo(i,1,n) dis[i] = INF, inq[i] = false;
	dis[s] = 0; pq.push(mp(0ll,s));
	while(!pq.empty())
	{
		pair<ll,int> h = pq.top(); pq.pop();
		inq[h.se] = false;
		if(dis[h.se] > L) break;
		for(int i = head[h.se]; i; i = e[i].next)
			if(dis[e[i].to] > dis[h.se] + e[i].w)
			{
				dis[e[i].to] = dis[h.se] + e[i].w;
				if(!inq[e[i].to])
				{
					inq[e[i].to] = true;
					pq.push(mp(-dis[e[i].to], e[i].to));
				}
			}
	}
	return dis[t];
}
void modify(int x)
{
	if(x == s) return;
	for(int i = head[x]; i; i = e[i].next)
		if(dis[x] == dis[e[i].to] + e[i].w)
		{
			if(e[i].pp == true)
			{
				reserve.pb(e[i].id);
				In[e[i].id].w = 1;
			}
			modify(e[i].to);
			break;
		}
}
int main()
{
	#ifdef MPS
		fp("cf714b.in","r",stdin);
		fp("cf714b.out","w",stdout);
	#endif
	sf("%d%d%d%d%d",&n,&m,&L,&s,&t); ++ s; ++ t;
	fo(i,1,m)
	{
		int u, v, w; sf("%d%d%d",&u,&v,&w);
		++ u; ++ v;
		link(u, v, (w == 0 ? 1 : w), i, (w == 0)); link(v, u, (w == 0 ? 1 : w), i, (w == 0));
		In[i] = (struct Input){u, v, w};
	}
	reserve.pb(0);
	val = dijkstra(s, t);
	modify(t);
	fo(i,1,m)
	{
		In[i].w = (In[i].w == 0 ? INF : In[i].w);
		e[i*2-1].w = e[i*2].w = In[i].w;
	}
	for(auto p : reserve)
	{
		if(L-(val-1) == 0) continue;
		In[p].w = L - (val - 1);
		if(p) e[p*2-1].w = In[p].w; e[p*2].w = In[p].w;
		val = dijkstra(s, t);
		if(val == L)
		{
			pf("YES\n");
			fo(i,1,m)
				pf("%d %d %lld\n", In[i].u - 1, In[i].v - 1, In[i].w);
			return 0;
		}
		In[p].w = INF;
		if(p) e[p*2-1].w = In[p].w; e[p*2].w = In[p].w;
	}
	pf("NO\n");
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define fo(i,s,t) for(int i = s; i <= t; ++ i)
#define fd(i,s,t) for(int i = s; i >= t; -- i)
#define bf(i,s) for(int i = head[s]; i; i = e[i].next)
#define mp make_pair
#define fi first
#define se second
#define pii pair<int,int>
#define pb push_back
#define VI vector<int>
#define sf scanf
#define pf printf
#define fp freopen
#define SZ(x) ((int)(x).size())
// #define MPS
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
const int inf = 1<<30;
const ll INF = 1ll<<60;
const db Inf = 1e20;
const db eps = 1e-9;

void gmax(int &a,int b){a = (a > b ? a : b);}
void gmin(int &a,int b){a = (a < b ? a : b);}

const int maxn = 1005;
const int maxm = 20050;

struct edge{int next, to, id; ll w; bool pp; edge(){pp=false;}}e[maxm];
int n, m, L, s, t, head[maxn], cnt;
ll dis[maxn], val;
priority_queue<pair<ll,int> > pq;
bool inq[maxn];
struct Input{int u, v; ll w;}In[maxm];
VI reserve;

void link(int u,int v,ll w,int id,bool pp)
{
	++ cnt; e[cnt].next = head[u];
	e[cnt].to = v; head[u] = cnt;
	e[cnt].w = w; e[cnt].id = id;
	e[cnt].pp = pp;
}
ll dijkstra(int s,int t)
{
	fo(i,1,n) dis[i] = INF;
	dis[s] = 0; pq.push(mp(0ll,s));
	while(!pq.empty())
	{
		pair<ll,int> h = pq.top(); pq.pop();
		inq[h.se] = false;
		for(int i = head[h.se]; i; i = e[i].next)
			if(e[i].w != -1 && dis[e[i].to] > dis[h.se] + e[i].w)
			{
				dis[e[i].to] = dis[h.se] + e[i].w;
				if(!inq[e[i].to])
				{
					inq[e[i].to] = true;
					pq.push(mp(-dis[e[i].to], e[i].to));
				}
			}
	}
	return dis[t];
}
void modify(int x)
{
	if(x == s) return;
	for(int i = head[x]; i; i = e[i].next)
		if(dis[x] == dis[e[i].to] + e[i].w)
		{
			if(e[i].pp == true)
			{
				reserve.pb(e[i].id);
				In[e[i].id].w = 1;
			}
			modify(e[i].to);
			break;
		}
}
int main()
{
	#ifdef MPS
		fp("cf714b.in","r",stdin);
		fp("cf714b.out","w",stdout);
	#endif
	sf("%d%d%d%d%d",&n,&m,&L,&s,&t); ++ s; ++ t;
	fo(i,1,m)
	{
		int u, v, w; sf("%d%d%d",&u,&v,&w);
		++ u; ++ v;
		link(u, v, (w == 0 ? 1 : w), i, (w == 0)); link(v, u, (w == 0 ? 1 : w), i, (w == 0));
		In[i] = (struct Input){u, v, w};
	}
	reserve.pb(0);
	val = dijkstra(s, t);
	modify(t);
	for(auto p : reserve)
	{
		In[p].w = L - (val - 1);
		cnt = 0; fo(i,1,n) head[i] = 0;
		fo(i,1,m)
		{
			link(In[i].u, In[i].v, (In[i].w == 0 ? 1 : In[i].w), i, (In[i].w == 0));
			link(In[i].v, In[i].u, (In[i].w == 0 ? 1 : In[i].w), i, (In[i].w == 0));
		}
		ll val = dijkstra(s, t);
		if(val == L)
		{
			pf("YES\n");
			fo(i,1,m) pf("%d %d %lld\n", In[i].u - 1, In[i].v - 1, (In[i].w == 0 ? INF : In[i].w));
			return 0;
		}
		In[p].w = INF;
	}
	pf("NO\n");
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define fo(i,s,t) for(int i = s; i <= t; ++ i)
#define fd(i,s,t) for(int i = s; i >= t; -- i)
#define bf(i,s) for(int i = head[s]; i; i = e[i].next)
#define mp make_pair
#define fi first
#define se second
#define pii pair<int,int>
#define pb push_back
#define VI vector<int>
#define sf scanf
#define pf printf
#define fp freopen
#define SZ(x) ((int)(x).size())
// #define MPS
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
const int inf = 1<<30;
const ll INF = 1000000000000000000ll;
const db Inf = 1e20;
const db eps = 1e-9;

void gmax(int &a,int b){a = (a > b ? a : b);}
void gmin(int &a,int b){a = (a < b ? a : b);}

const int maxn = 1005;
const int maxm = 20050;

struct edge{int next, to, id; ll w; bool pp; edge(){pp=false;}}e[maxm];
int n, m, L, s, t, head[maxn], cnt;
ll dis[maxn], val;
priority_queue<pair<ll,int> > pq;
bool inq[maxn];
struct Input{int u, v; ll w;}In[maxm];
VI reserve;

void link(int u,int v,ll w,int id,bool pp)
{
	++ cnt; e[cnt].next = head[u];
	e[cnt].to = v; head[u] = cnt;
	e[cnt].w = w; e[cnt].id = id;
	e[cnt].pp = pp;
}
ll dijkstra(int s,int t)
{
	fo(i,1,n) dis[i] = INF;
	dis[s] = 0; pq.push(mp(0ll,s));
	while(!pq.empty())
	{
		pair<ll,int> h = pq.top(); pq.pop();
		inq[h.se] = false;
		if(dis[h.se] > L) break;
		for(int i = head[h.se]; i; i = e[i].next)
			if(dis[e[i].to] > dis[h.se] + e[i].w)
			{
				dis[e[i].to] = dis[h.se] + e[i].w;
				if(!inq[e[i].to])
				{
					inq[e[i].to] = true;
					pq.push(mp(-dis[e[i].to], e[i].to));
				}
			}
	}
	return dis[t];
}
void modify(int x)
{
	if(x == s) return;
	for(int i = head[x]; i; i = e[i].next)
		if(dis[x] == dis[e[i].to] + e[i].w)
		{
			if(e[i].pp == true)
			{
				reserve.pb(e[i].id);
				In[e[i].id].w = 1;
			}
			modify(e[i].to);
			break;
		}
}
int main()
{
	#ifdef MPS
		fp("cf714b.in","r",stdin);
		fp("cf714b.out","w",stdout);
	#endif
	sf("%d%d%d%d%d",&n,&m,&L,&s,&t); ++ s; ++ t;
	fo(i,1,m)
	{
		int u, v, w; sf("%d%d%d",&u,&v,&w);
		++ u; ++ v;
		link(u, v, (w == 0 ? 1 : w), i, (w == 0)); link(v, u, (w == 0 ? 1 : w), i, (w == 0));
		In[i] = (struct Input){u, v, w};
	}
	reserve.pb(0);
	val = dijkstra(s, t);
	modify(t);
	fo(i,1,m)
	{
		In[i].w = (In[i].w == 0 ? INF : In[i].w);
		e[i*2-1].w = e[i*2].w = In[i].w;
	}
	for(auto p : reserve)
	{
		if(L-(val-1) == 0) continue;
		In[p].w = L - (val - 1);
		e[p*2-1].w = In[p].w; e[p*2].w = In[p].w;
		val = dijkstra(s, t);
		if(val == L)
		{
			pf("YES\n");
			fo(i,1,m) pf("%d %d %lld\n", In[i].u - 1, In[i].v - 1, In[i].w);
			return 0;
		}
		In[p].w = INF;
		e[p*2-1].w = In[p].w; e[p*2].w = In[p].w;
	}
	pf("NO\n");
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define fo(i,s,t) for(int i = s; i <= t; ++ i)
#define fd(i,s,t) for(int i = s; i >= t; -- i)
#define bf(i,s) for(int i = head[s]; i; i = e[i].next)
#define mp make_pair
#define fi first
#define se second
#define pii pair<int,int>
#define pb push_back
#define VI vector<int>
#define sf scanf
#define pf printf
#define fp freopen
#define SZ(x) ((int)(x).size())
// #define MPS
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
const int inf = 1<<30;
const ll INF = 1ll<<60;
const db Inf = 1e20;
const db eps = 1e-9;

void gmax(int &a,int b){a = (a > b ? a : b);}
void gmin(int &a,int b){a = (a < b ? a : b);}

const int maxn = 1005;
const int maxm = 20050;

struct edge{int next, to, id; ll w; bool pp; edge(){pp=false;}}e[maxm];
int n, m, L, s, t, head[maxn], cnt;
ll dis[maxn], val;
priority_queue<pair<ll,int> > pq;
bool inq[maxn];
struct Input{int u, v, w;}In[maxm];

void link(int u,int v,ll w,int id,bool pp)
{
	++ cnt; e[cnt].next = head[u];
	e[cnt].to = v; head[u] = cnt;
	e[cnt].w = w; e[cnt].id = id;
	e[cnt].pp = pp;
}
ll dijkstra(int s,int t)
{
	fo(i,1,n) dis[i] = INF;
	dis[s] = 0; pq.push(mp(0ll,s));
	while(!pq.empty())
	{
		pair<ll,int> h = pq.top(); pq.pop();
		inq[h.se] = false;
		for(int i = head[h.se]; i; i = e[i].next)
			if(e[i].w != -1 && dis[e[i].to] > dis[h.se] + e[i].w)
			{
				dis[e[i].to] = dis[h.se] + e[i].w;
				if(!inq[e[i].to])
				{
					inq[e[i].to] = true;
					pq.push(mp(-dis[e[i].to], e[i].to));
				}
			}
	}
	return dis[t];
}
void modify(int x, bool g=true)
{
	if(x == s) return;
	for(int i = head[x]; i; i = e[i].next)
		if(dis[x] == dis[e[i].to] + e[i].w)
		{
			if(e[i].pp == true)
			{
				if(g) In[e[i].id].w = L - (val - 1);
				else In[e[i].id].w = 1;
				g = false;
			}
			modify(e[i].to, g);
			break;
		}
}
int main()
{
	#ifdef MPS
		fp("cf714b.in","r",stdin);
		fp("cf714b.out","w",stdout);
	#endif
	sf("%d%d%d%d%d",&n,&m,&L,&s,&t); ++ s; ++ t;
	fo(i,1,m)
	{
		int u, v, w; sf("%d%d%d",&u,&v,&w);
		++ u; ++ v; w = (w == 0 ? -1 : w);
		link(u, v, w, i, (w == -1)); link(v, u, w, i, (w == -1));
		In[i] = (struct Input){u, v, w};
	}
	val = dijkstra(s, t);
	if(val < L) return 0 * pf("NO\n");
	if(val == L)
	{
		pf("YES\n");
		fo(i,1,m)
		{
			pf("%d %d ", In[i].u - 1, In[i].v - 1);
			if(In[i].w == -1) pf("%lld\n", 10000000000000ll);
			else pf("%d\n", In[i].w);
		}
		return 0;
	}
	cnt = 0; memset(head,0,sizeof(head));
	fo(i,1,m)
	{
		link(In[i].u, In[i].v, (In[i].w == -1 ? 1 : In[i].w), i, (In[i].w == -1));
		link(In[i].v, In[i].u, (In[i].w == -1 ? 1 : In[i].w), i, (In[i].w == -1));
	}
	val = dijkstra(s, t);
	if(val <= L)
	{
		modify(t);
		pf("YES\n");
		fo(i,1,m) pf("%d %d %lld\n", In[i].u - 1, In[i].v - 1, (In[i].w == -1 ? 10000000000001ll: 1ll*In[i].w));
		return 0;
	}
	pf("NO\n");
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define fo(i,s,t) for(int i = s; i <= t; ++ i)
#define fd(i,s,t) for(int i = s; i >= t; -- i)
#define bf(i,s) for(int i = head[s]; i; i = e[i].next)
#define mp make_pair
#define fi first
#define se second
#define pii pair<int,int>
#define pb push_back
#define VI vector<int>
#define sf scanf
#define pf printf
#define fp freopen
#define SZ(x) ((int)(x).size())
// #define MPS
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
const int inf = 1<<30;
const ll INF = 1ll<<60;
const db Inf = 1e20;
const db eps = 1e-9;

void gmax(int &a,int b){a = (a > b ? a : b);}
void gmin(int &a,int b){a = (a < b ? a : b);}

const int maxn = 1005;
const int maxm = 20050;

struct edge{int next, to, id; ll w; bool pp; edge(){pp=false;}}e[maxm];
int n, m, L, s, t, head[maxn], cnt;
ll dis[maxn], val;
priority_queue<pair<ll,int> > pq;
bool inq[maxn];
struct Input{int u, v, w;}In[maxm];

void link(int u,int v,ll w,int id,bool pp)
{
	++ cnt; e[cnt].next = head[u];
	e[cnt].to = v; head[u] = cnt;
	e[cnt].w = w; e[cnt].id = id;
	e[cnt].pp = pp;
}
ll dijkstra(int s,int t)
{
	fo(i,1,n) dis[i] = INF;
	dis[s] = 0; pq.push(mp(0ll,s));
	while(!pq.empty())
	{
		pair<ll,int> h = pq.top(); pq.pop();
		inq[h.se] = false;
		for(int i = head[h.se]; i; i = e[i].next)
			if(e[i].w != -1 && dis[e[i].to] > dis[h.se] + e[i].w)
			{
				dis[e[i].to] = dis[h.se] + e[i].w;
				if(!inq[e[i].to])
				{
					inq[e[i].to] = true;
					pq.push(mp(-dis[e[i].to], e[i].to));
				}
			}
	}
	return dis[t];
}
void modify(int x, bool g=true)
{
	if(x == s) return;
	for(int i = head[x]; i; i = e[i].next)
		if(dis[x] == dis[e[i].to] + e[i].w)
		{
			if(e[i].pp == true)
			{
				if(g) In[e[i].id].w = L - (val - 1);
				else In[e[i].id].w = 1;
				g = false;
			}
			modify(e[i].to, g);
			break;
		}
}
int main()
{
	#ifdef MPS
		fp("cf714b.in","r",stdin);
		fp("cf714b.out","w",stdout);
	#endif
	sf("%d%d%d%d%d",&n,&m,&L,&s,&t); ++ s; ++ t;
	fo(i,1,m)
	{
		int u, v, w; sf("%d%d%d",&u,&v,&w);
		++ u; ++ v; w = (w == 0 ? -1 : w);
		link(u, v, w, i, (w == -1)); link(v, u, w, i, (w == -1));
		In[i] = (struct Input){u, v, w};
	}
	val = dijkstra(s, t);
	if(val < L) return 0 * pf("NO\n");
	if(val == L)
	{
		pf("YES\n");
		fo(i,1,m)
		{
			pf("%d %d ", In[i].u - 1, In[i].v - 1);
			if(In[i].w == -1) pf("%d\n", 1000000001);
			else pf("%d\n", In[i].w);
		}
		return 0;
	}
	cnt = 0; memset(head,0,sizeof(head));
	fo(i,1,m)
	{
		link(In[i].u, In[i].v, (In[i].w == -1 ? 1 : In[i].w), i, (In[i].w == -1));
		link(In[i].v, In[i].u, (In[i].w == -1 ? 1 : In[i].w), i, (In[i].w == -1));
	}
	val = dijkstra(s, t);
	if(val <= L)
	{
		modify(t);
		pf("YES\n");
		fo(i,1,m) pf("%d %d %d\n", In[i].u - 1, In[i].v - 1, (In[i].w == -1 ? 1000000001: In[i].w));
		return 0;
	}
	pf("NO\n");
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define fo(i,s,t) for(int i = s; i <= t; ++ i)
#define fd(i,s,t) for(int i = s; i >= t; -- i)
#define bf(i,s) for(int i = head[s]; i; i = e[i].next)
#define mp make_pair
#define fi first
#define se second
#define pii pair<int,int>
#define pb push_back
#define VI vector<int>
#define sf scanf
#define pf printf
#define fp freopen
#define SZ(x) ((int)(x).size())
// #define MPS
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
const int inf = 1<<30;
const ll INF = 1ll<<60;
const db Inf = 1e20;
const db eps = 1e-9;

void gmax(int &a,int b){a = (a > b ? a : b);}
void gmin(int &a,int b){a = (a < b ? a : b);}

const int maxn = 1005;
const int maxm = 20050;

struct edge{int next, to, id; ll w; bool pp; edge(){pp=false;}}e[maxm];
int n, m, L, s, t, head[maxn], cnt;
ll dis[maxn], val;
priority_queue<pair<ll,int> > pq;
bool inq[maxn];
struct Input{int u, v, w;}In[maxn];

void link(int u,int v,ll w,int id,bool pp)
{
	++ cnt; e[cnt].next = head[u];
	e[cnt].to = v; head[u] = cnt;
	e[cnt].w = w; e[cnt].id = id;
	e[cnt].pp = pp;
}
ll dijkstra(int s,int t)
{
	fo(i,1,n) dis[i] = INF;
	dis[s] = 0; pq.push(mp(0ll,s));
	while(!pq.empty())
	{
		pair<ll,int> h = pq.top(); pq.pop();
		inq[h.se] = false;
		for(int i = head[h.se]; i; i = e[i].next)
			if(e[i].w != -1 && dis[e[i].to] > dis[h.se] + e[i].w)
			{
				dis[e[i].to] = dis[h.se] + e[i].w;
				if(!inq[e[i].to])
				{
					inq[e[i].to] = true;
					pq.push(mp(-dis[e[i].to], e[i].to));
				}
			}
	}
	return dis[t];
}
void modify(int x)
{
	for(int i = head[x]; i; i = e[i].next)
		if(dis[x] == dis[e[i].to] + e[i].w)
		{
			if(e[i].pp == true)
			{
				In[e[i].id].w = L - (val - 1);
				return;
			}
			else
			{
				modify(x);
				return;
			}
		}
}
int main()
{
	#ifdef MPS
		fp("cf714b.in","r",stdin);
		fp("cf714b.out","w",stdout);
	#endif
	sf("%d%d%d%d%d",&n,&m,&L,&s,&t); ++ s; ++ t;
	fo(i,1,m)
	{
		int u, v, w; sf("%d%d%d",&u,&v,&w);
		++ u; ++ v; w = (w == 0 ? -1 : w);
		link(u, v, w, i, (w == -1)); link(v, u, w, i, (w == -1));
		In[i] = (struct Input){u, v, w};
	}
	val = dijkstra(s, t);
	if(val < L) return 0 * pf("NO\n");
	if(val == L)
	{
		pf("YES\n");
		fo(i,1,m)
		{
			pf("%d %d ", In[i].u - 1, In[i].v - 1);
			if(In[i].w == -1) pf("%d\n", 1000000001);
			else pf("%d\n", In[i].w);
		}
		return 0;
	}
	cnt = 0; memset(head,0,sizeof(head));
	fo(i,1,m)
	{
		link(In[i].u, In[i].v, (In[i].w == -1 ? 1 : In[i].w), i, (In[i].w == -1));
		link(In[i].v, In[i].u, (In[i].w == -1 ? 1 : In[i].w), i, (In[i].w == -1));
	}
	val = dijkstra(s, t);
	if(val <= L)
	{
		modify(t);
		pf("YES\n");
		fo(i,1,m) pf("%d %d %d\n", In[i].u - 1, In[i].v - 1, In[i].w);
		return 0;
	}
	pf("NO\n");
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define fo(i,s,t) for(int i = s; i <= t; ++ i)
#define fd(i,s,t) for(int i = s; i >= t; -- i)
#define bf(i,s) for(int i = head[s]; i; i = e[i].next)
#define mp make_pair
#define fi first
#define se second
#define pii pair<int,int>
#define pb push_back
#define VI vector<int>
#define sf scanf
#define pf printf
#define fp freopen
#define SZ(x) ((int)(x).size())
// #define MPS
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
const int inf = 1<<30;
const ll INF = 1ll<<60;
const db Inf = 1e20;
const db eps = 1e-9;

void gmax(int &a,int b){a = (a > b ? a : b);}
void gmin(int &a,int b){a = (a < b ? a : b);}

const int maxn = 1005;
const int maxm = 10050;

struct edge{int next, to, id; ll w; bool pp; edge(){pp=false;}}e[maxm];
int n, m, L, s, t, head[maxn], cnt;
ll dis[maxn], val;
priority_queue<pair<ll,int> > pq;
bool inq[maxn];
struct Input{int u, v, w;}In[maxn];

void link(int u,int v,ll w,int id,bool pp)
{
	++ cnt; e[cnt].next = head[u];
	e[cnt].to = v; head[u] = cnt;
	e[cnt].w = w; e[cnt].id = id;
	e[cnt].pp = pp;
}
ll dijkstra(int s,int t)
{
	fo(i,1,n) dis[i] = INF;
	dis[s] = 0; pq.push(mp(0ll,s));
	while(!pq.empty())
	{
		pair<ll,int> h = pq.top(); pq.pop();
		inq[h.se] = false;
		for(int i = head[h.se]; i; i = e[i].next)
			if(e[i].w != -1 && dis[e[i].to] > dis[h.se] + e[i].w)
			{
				dis[e[i].to] = dis[h.se] + e[i].w;
				if(!inq[e[i].to])
				{
					inq[e[i].to] = true;
					pq.push(mp(-dis[e[i].to], e[i].to));
				}
			}
	}
	return dis[t];
}
void modify(int x)
{
	for(int i = head[x]; i; i = e[i].next)
		if(dis[x] == dis[e[i].to] + e[i].w)
		{
			if(e[i].pp == true)
			{
				In[e[i].id].w = L - (val - 1);
				return;
			}
			else
			{
				modify(x);
				return;
			}
		}
}
int main()
{
	#ifdef MPS
		fp("cf714b.in","r",stdin);
		fp("cf714b.out","w",stdout);
	#endif
	sf("%d%d%d%d%d",&n,&m,&L,&s,&t); ++ s; ++ t;
	fo(i,1,m)
	{
		int u, v, w; sf("%d%d%d",&u,&v,&w);
		++ u; ++ v; w = (w == 0 ? -1 : w);
		link(u, v, w, i, (w == -1)); link(v, u, w, i, (w == -1));
		In[i] = (struct Input){u, v, w};
	}
	val = dijkstra(s, t);
	if(val < L) return 0 * pf("NO\n");
	if(val == L)
	{
		pf("YES\n");
		fo(i,1,m)
		{
			pf("%d %d ", In[i].u - 1, In[i].v - 1);
			if(In[i].w == -1) pf("%d\n", 1000000001);
			else pf("%d\n", In[i].w);
		}
		return 0;
	}
	cnt = 0; memset(head,0,sizeof(head));
	fo(i,1,m)
	{
		link(In[i].u, In[i].v, (In[i].w == -1 ? 1 : In[i].w), i, (In[i].w == -1));
		link(In[i].v, In[i].u, (In[i].w == -1 ? 1 : In[i].w), i, (In[i].w == -1));
	}
	val = dijkstra(s, t);
	if(val <= L)
	{
		modify(t);
		pf("YES\n");
		fo(i,1,m) pf("%d %d %d\n", In[i].u - 1, In[i].v - 1, In[i].w);
		return 0;
	}
	pf("NO\n");
	return 0;
}