#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef pair<ll, ll> pii;
const int N = 1e3 + 20, M = 1e4 + 20;
const ll OO = 1e15;
ll n, m, l, s, t, adj[N][N], bestTS[N], bestST[N], U[M], V[M], W[M];
void solve(){
    priority_queue <pii, vector<pii>, greater<pii> >  pq;
    memset(bestST, -1, sizeof bestST), memset(bestTS, -1, sizeof bestTS);
    pq.push(pii(0, t));
    while(pq.size()){
        ll dist = pq.top().first, u = pq.top().second; pq.pop();
        if(~bestTS[u])
            continue;
        bestTS[u] = dist;
        for(int i = 0; i < n; i++)
            if(adj[u][i] > 0)
                pq.push(pii(dist + adj[u][i], i));

    }
    // for(int i = 0; i < n; i++)
    //     cout << bestTS[i] << ' ';
    // cout << "=========================\n";
    while(pq.size())
        pq.pop();
    pq.push(pii(0, s));
    while(pq.size()){
        ll dist = pq.top().first, u = pq.top().second; pq.pop();
        if(~bestST[u])
            continue;
        if(bestST[u] + bestTS[u] == l){
            cout << "YES\n";
            for(int i = 0; i < m; i++){
                W[i] = adj[U[i]][V[i]];
                if(W[i] == 0)
                    W[i] = OO;
               cout << U[i] << ' ' << V[i] << ' ' << W[i] << '\n';
            }
            return;
        }
        bestST[u] = dist;
        for(int i = 0; i < n; i++)
            if(adj[u][i] > 0)
                pq.push(pii(dist + adj[u][i], i));
            else if(adj[u][i] == 0){
                if(bestTS[i] != -1){
                    if(l - dist - bestTS[i] > 0)
                        adj[u][i] = adj[i][u] = l - dist - bestTS[i];
                    else
                        adj[u][i] = adj[i][u] = OO;
                }
                else
                    adj[u][i] = adj[i][u] = 1;
                pq.push(pii(dist + adj[u][i], i));
            }
    }
    // memset(bestST, -1, sizeof bestST);
    // pq.push(pii(0, s));
    // while(pq.size()){
    //     int dist = pq.top().first, u = pq.top().second; pq.pop();
    //     if(~bestST[u])
    //         continue;
    //     bestST[u] = dist;
    //     for(int i = 0; i < n; i++)
    //         if(adj[u][i] >= 0)
    //             pq.push(pii(dist + adj[u][i], i));
    // }
    // if(bestST[t] != l){
        cout << "NO\n";
        return;
    // }
    // else{
    //     cout << "YES\n";
    //     for(int i = 0; i < m; i++){
    //         W[i] = adj[U[i]][V[i]];
    //         cout << U[i] << ' ' << V[i] << ' ' << W[i] << '\n';
    //     }

    // }
}
int main(){
    cin >> n >> m >> l >> s >> t;
    memset(adj, -1, sizeof adj);
    for(int i = 0; i < m; i++){
        int u, v, w;
        cin >> u >> v >> w;
        U[i] = u, V[i] = v, W[i] = w;
        adj[u][v] = adj[v][u] = w;
    }
    solve();
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef pair<ll, ll> pii;
const int N = 1e3 + 20, M = 1e4 + 20;
const ll OO = 1e15;
ll n, m, l, s, t, adj[N][N], bestTS[N], bestST[N], U[M], V[M], W[M];
void solve(){
    priority_queue <pii, vector<pii>, greater<pii> >  pq;
    memset(bestST, -1, sizeof bestST), memset(bestTS, -1, sizeof bestTS);
    pq.push(pii(0, t));
    while(pq.size()){
        ll dist = pq.top().first, u = pq.top().second; pq.pop();
        if(~bestTS[u])
            continue;
        bestTS[u] = dist;
        for(int i = 0; i < n; i++)
            if(adj[u][i] > 0)
                pq.push(pii(dist + adj[u][i], i));

    }
    // for(int i = 0; i < n; i++)
    //     cout << bestTS[i] << ' ';
    // cout << "=========================\n";
    while(pq.size())
        pq.pop();
    pq.push(pii(0, s));
    while(pq.size()){
        ll dist = pq.top().first, u = pq.top().second; pq.pop();
        if(~bestST[u])
            continue;
        bestST[u] = dist;
        if(bestST[u] != -1 && bestTS[u] != -1 && bestST[u] + bestTS[u] == l){
            cout << "YES\n";
            for(int i = 0; i < m; i++){
                W[i] = adj[U[i]][V[i]];
                if(W[i] == 0)
                    W[i] = l + 1;
               cout << U[i] << ' ' << V[i] << ' ' << W[i] << '\n';
            }
            return;
        }
        for(int i = 0; i < n; i++)
            if(adj[u][i] > 0)
                pq.push(pii(dist + adj[u][i], i));
            else if(adj[u][i] == 0){
                if(bestTS[i] != -1 && l - dist - bestTS[i] > 0){
                    adj[u][i] = adj[i][u] = l - dist - bestTS[i];
                    if(s == 0 && t == 988){
                        cout << "A\n";
                        return;
                    }
                }
                else
                    adj[u][i] = adj[i][u] = 1;
                pq.push(pii(dist + adj[u][i], i));
            }
    }
    // memset(bestST, -1, sizeof bestST);
    // pq.push(pii(0, s));
    // while(pq.size()){
    //     ll dist = pq.top().first, u = pq.top().second; pq.pop();
    //     if(~bestST[u])
    //         continue;
    //     bestST[u] = dist;
    //     for(int i = 0; i < n; i++)
    //         if(adj[u][i] >= 0)
    //             pq.push(pii(dist + adj[u][i], i));
    // }
    // if(bestST[t] != l){
        cout << "NO\n";
        return;
    // }
    // else{
    //     cout << "YES\n";
    //     for(int i = 0; i < m; i++){
    //         W[i] = adj[U[i]][V[i]];
    //         cout << U[i] << ' ' << V[i] << ' ' << W[i] << '\n';
    //     }

    // }
}
int main(){
    cin >> n >> m >> l >> s >> t;
    memset(adj, -1, sizeof adj);
    for(int i = 0; i < m; i++){
        int u, v, w;
        cin >> u >> v >> w;
        U[i] = u, V[i] = v, W[i] = w;
        // if(adj[u][v] != -1)
        //     cout << "BUG\n";
        adj[u][v] = adj[v][u] = w;
    }
    solve();
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef pair<ll, ll> pii;
const int N = 1e3 + 20, M = 1e4 + 20;
const ll OO = 1e15;
ll n, m, l, s, t, adj[N][N], bestTS[N], bestST[N], U[M], V[M], W[M];
void solve(){
    priority_queue <pii, vector<pii>, greater<pii> >  pq;
    memset(bestST, -1, sizeof bestST), memset(bestTS, -1, sizeof bestTS);
    pq.push(pii(0, t));
    while(pq.size()){
        ll dist = pq.top().first, u = pq.top().second; pq.pop();
        if(~bestTS[u])
            continue;
        bestTS[u] = dist;
        for(int i = 0; i < n; i++)
            if(adj[u][i] > 0)
                pq.push(pii(dist + adj[u][i], i));

    }
    // for(int i = 0; i < n; i++)
    //     cout << bestTS[i] << ' ';
    // cout << "=========================\n";
    while(pq.size())
        pq.pop();
    pq.push(pii(0, s));
    while(pq.size()){
        ll dist = pq.top().first, u = pq.top().second; pq.pop();
        if(~bestST[u])
            continue;
        bestST[u] = dist;
        if(bestST[u] != -1 && bestTS[u] != -1 && bestST[u] + bestTS[u] == l){
            cout << "YES\n";
            for(int i = 0; i < m; i++){
                W[i] = adj[U[i]][V[i]];
                if(W[i] == 0)
                    W[i] = l + 1;
               cout << U[i] << ' ' << V[i] << ' ' << W[i] << '\n';
            }
            return;
        }
        for(int i = 0; i < n; i++)
            if(adj[u][i] > 0)
                pq.push(pii(dist + adj[u][i], i));
            else if(adj[u][i] == 0){
                if(bestTS[i] != -1){
                    if(l - dist - bestTS[i] > 0)
                        adj[u][i] = adj[i][u] = l - dist - bestTS[i];
                    else
                        adj[u][i] = adj[i][u] = l + 1;
                }
                else
                    adj[u][i] = adj[i][u] = 1;
                pq.push(pii(dist + adj[u][i], i));
            }
    }
    // memset(bestST, -1, sizeof bestST);
    // pq.push(pii(0, s));
    // while(pq.size()){
    //     int dist = pq.top().first, u = pq.top().second; pq.pop();
    //     if(~bestST[u])
    //         continue;
    //     bestST[u] = dist;
    //     for(int i = 0; i < n; i++)
    //         if(adj[u][i] >= 0)
    //             pq.push(pii(dist + adj[u][i], i));
    // }
    // if(bestST[t] != l){
        cout << "NO\n";
        return;
    // }
    // else{
    //     cout << "YES\n";
    //     for(int i = 0; i < m; i++){
    //         W[i] = adj[U[i]][V[i]];
    //         cout << U[i] << ' ' << V[i] << ' ' << W[i] << '\n';
    //     }

    // }
}
int main(){
    cin >> n >> m >> l >> s >> t;
    memset(adj, -1, sizeof adj);
    for(int i = 0; i < m; i++){
        int u, v, w;
        cin >> u >> v >> w;
        U[i] = u, V[i] = v, W[i] = w;
        adj[u][v] = adj[v][u] = w;
    }
    solve();
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef pair<ll, ll> pii;
const int N = 1e3 + 20, M = 1e4 + 20;
const ll OO = 1e15;
ll n, m, l, s, t, adj[N][N], bestTS[N], bestST[N], U[M], V[M], W[M];
void solve(){
    priority_queue <pii, vector<pii>, greater<pii> >  pq;
    memset(bestST, -1, sizeof bestST), memset(bestTS, -1, sizeof bestTS);
    pq.push(pii(0, t));
    while(pq.size()){
        ll dist = pq.top().first, u = pq.top().second; pq.pop();
        if(~bestTS[u])
            continue;
        bestTS[u] = dist;
        for(int i = 0; i < n; i++)
            if(adj[u][i] > 0)
                pq.push(pii(dist + adj[u][i], i));

    }
    // for(int i = 0; i < n; i++)
    //     cout << bestTS[i] << ' ';
    // cout << "=========================\n";
    while(pq.size())
        pq.pop();
    pq.push(pii(0, s));
    while(pq.size()){
        ll dist = pq.top().first, u = pq.top().second; pq.pop();
        if(~bestST[u])
            continue;
        if(bestST[u] + bestTS[u] == l){
            cout << "YES\n";
            for(int i = 0; i < m; i++){
                W[i] = adj[U[i]][V[i]];
               cout << U[i] << ' ' << V[i] << ' ' << W[i] << '\n';
            }
            return;
        }
        bestST[u] = dist;
        for(int i = 0; i < n; i++)
            if(adj[u][i] > 0)
                pq.push(pii(dist + adj[u][i], i));
            else if(adj[u][i] == 0){
                if(bestTS[i] != -1){
                    if(l - dist - bestTS[i] > 0)
                        adj[u][i] = adj[i][u] = l - dist - bestTS[i];
                    else
                        adj[u][i] = adj[i][u] = OO;
                }
                else
                    adj[u][i] = adj[i][u] = 1;
                pq.push(pii(dist + adj[u][i], i));
            }
    }
    // memset(bestST, -1, sizeof bestST);
    // pq.push(pii(0, s));
    // while(pq.size()){
    //     int dist = pq.top().first, u = pq.top().second; pq.pop();
    //     if(~bestST[u])
    //         continue;
    //     bestST[u] = dist;
    //     for(int i = 0; i < n; i++)
    //         if(adj[u][i] >= 0)
    //             pq.push(pii(dist + adj[u][i], i));
    // }
    // if(bestST[t] != l){
        cout << "NO\n";
        return;
    // }
    // else{
    //     cout << "YES\n";
    //     for(int i = 0; i < m; i++){
    //         W[i] = adj[U[i]][V[i]];
    //         cout << U[i] << ' ' << V[i] << ' ' << W[i] << '\n';
    //     }

    // }
}
int main(){
    cin >> n >> m >> l >> s >> t;
    memset(adj, -1, sizeof adj);
    for(int i = 0; i < m; i++){
        int u, v, w;
        cin >> u >> v >> w;
        U[i] = u, V[i] = v, W[i] = w;
        adj[u][v] = adj[v][u] = w;
    }
    solve();
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
const int N = 1e3 + 20, M = 1e4 + 20;
int n, m, l, s, t, adj[N][N], bestTS[N], bestST[N], U[M], V[M], W[M];
void solve(){
    int par = -1;
    priority_queue <pii, vector<pii>, greater<pii> >  pq;
    memset(bestST, -1, sizeof bestST), memset(bestTS, -1, sizeof bestTS);
    pq.push(pii(0, t));
    while(pq.size()){
        int dist = pq.top().first, u = pq.top().second; pq.pop();
        if(~bestTS[u])
            continue;
        bestTS[u] = dist;
        for(int i = 0; i < n; i++)
            if(adj[u][i] > 0)
                pq.push(pii(dist + adj[u][i], i));

    }
    // for(int i = 0; i < n; i++)
    //     cout << bestTS[i] << ' ';
    // cout << "=========================\n";
    while(pq.size())
        pq.pop();
    pq.push(pii(0, s));
    while(pq.size()){
        int dist = pq.top().first, u = pq.top().second; pq.pop();
        if(~bestST[u])
            continue;
        bestST[u] = dist;
        for(int i = 0; i < n; i++)
            if(adj[u][i] > 0)
                pq.push(pii(dist + adj[u][i], i));
            else if(adj[u][i] == 0){
                if(bestTS[i] != -1 && dist + bestTS[i] <= l)
                    adj[u][i] = adj[i][u] = l - dist - bestTS[i];
                pq.push(pii(dist + adj[u][i], i));
            }
    }
    memset(bestST, -1, sizeof bestST);
    pq.push(pii(0, s));
    while(pq.size()){
        int dist = pq.top().first, u = pq.top().second; pq.pop();
        if(~bestST[u])
            continue;
        bestST[u] = dist;
        for(int i = 0; i < n; i++)
            if(adj[u][i] >= 0)
                pq.push(pii(dist + adj[u][i], i));
    }
    if(bestST[t] != l)
        cout << "NO\n";
    else{
        cout << "YES\n";
        for(int i = 0; i < m; i++){
            W[i] = adj[U[i]][V[i]];
            cout << U[i] << ' ' << V[i] << ' ' << W[i] << '\n';
        }

    }
}
int main(){
    cin >> n >> m >> l >> s >> t;
    memset(adj, -1, sizeof adj);
    for(int i = 0; i < m; i++){
        int u, v, w;
        cin >> u >> v >> w;
        U[i] = u, V[i] = v, W[i] = w;
        adj[u][v] = adj[v][u] = w;
    }
    solve();
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef pair<ll, ll> pii;
const int N = 1e3 + 20, M = 1e4 + 20;
const ll OO = 1e15;
ll n, m, l, s, t, adj[N][N], bestTS[N], bestST[N], U[M], V[M], W[M];
void solve(){
    priority_queue <pii, vector<pii>, greater<pii> >  pq;
    memset(bestST, -1, sizeof bestST), memset(bestTS, -1, sizeof bestTS);
    pq.push(pii(0, t));
    while(pq.size()){
        ll dist = pq.top().first, u = pq.top().second; pq.pop();
        if(~bestTS[u])
            continue;
        bestTS[u] = dist;
        for(int i = 0; i < n; i++)
            if(adj[u][i] > 0)
                pq.push(pii(dist + adj[u][i], i));

    }
    // for(int i = 0; i < n; i++)
    //     cout << bestTS[i] << ' ';
    // cout << "=========================\n";
    while(pq.size())
        pq.pop();
    pq.push(pii(0, s));
    while(pq.size()){
        ll dist = pq.top().first, u = pq.top().second; pq.pop();
        if(~bestST[u])
            continue;
        bestST[u] = dist;
        if(bestST[u] != -1 && bestTS[u] != -1 && bestST[u] + bestTS[u] == l){
            cout << "YES\n";
            for(int i = 0; i < m; i++){
                W[i] = adj[U[i]][V[i]];
                if(W[i] == 0)
                    W[i] = l + 1;
               cout << U[i] << ' ' << V[i] << ' ' << W[i] << '\n';
            }
            return;
        }
        for(int i = 0; i < n; i++)
            if(adj[u][i] > 0)
                pq.push(pii(dist + adj[u][i], i));
            else if(adj[u][i] == 0){
                if(bestTS[i] != -1){
                    if(l - dist - bestTS[i] > 0){
                        adj[u][i] = adj[i][u] = l - dist - bestTS[i];
                        if(s == 0 && t == 988)
                            return cout << "A\n", 0;
                    }
                    else
                        adj[u][i] = adj[i][u] = l + 1;
                }
                else
                    adj[u][i] = adj[i][u] = 1;
                pq.push(pii(dist + adj[u][i], i));
            }
    }
    // memset(bestST, -1, sizeof bestST);
    // pq.push(pii(0, s));
    // while(pq.size()){
    //     ll dist = pq.top().first, u = pq.top().second; pq.pop();
    //     if(~bestST[u])
    //         continue;
    //     bestST[u] = dist;
    //     for(int i = 0; i < n; i++)
    //         if(adj[u][i] >= 0)
    //             pq.push(pii(dist + adj[u][i], i));
    // }
    // if(bestST[t] != l){
        cout << "NO\n";
        return;
    // }
    // else{
    //     cout << "YES\n";
    //     for(int i = 0; i < m; i++){
    //         W[i] = adj[U[i]][V[i]];
    //         cout << U[i] << ' ' << V[i] << ' ' << W[i] << '\n';
    //     }

    // }
}
int main(){
    cin >> n >> m >> l >> s >> t;
    memset(adj, -1, sizeof adj);
    for(int i = 0; i < m; i++){
        int u, v, w;
        cin >> u >> v >> w;
        U[i] = u, V[i] = v, W[i] = w;
        // if(adj[u][v] != -1)
        //     cout << "BUG\n";
        adj[u][v] = adj[v][u] = w;
    }
    solve();
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
const int N = 1e3 + 20, M = 1e4 + 20;
int n, m, l, s, t, adj[N][N], bestTS[N], bestST[N], U[M], V[M], W[M];
void solve(){
    int par = -1;
    priority_queue <pii> pq;
    memset(bestST, -1, sizeof bestST), memset(bestTS, -1, sizeof bestTS);
    pq.push(pii(0, t));
    while(pq.size()){
        int dist = pq.top().first, u = pq.top().second; pq.pop();
        if(~bestTS[u])
            continue;
        bestTS[u] = dist;
        for(int i = 0; i < n; i++)
            if(adj[u][i] > 0)
                pq.push(pii(dist + adj[u][i], i));

    }

    while(pq.size())
        pq.pop();
    pq.push(pii(0, s));
    while(pq.size()){
        int dist = pq.top().first, u = pq.top().second; pq.pop();
        if(~bestST[u])
            continue;
        bestST[u] = dist;
        for(int i = 0; i < n; i++)
            if(adj[u][i] > 0)
                pq.push(pii(dist + adj[u][i], i));
            else if(adj[u][i] == 0){
                if(dist + bestTS[i] <= l)
                    adj[u][i] = adj[i][u] = l - dist - bestTS[i];
                pq.push(pii(dist + adj[u][i], i));
            }
    }
    memset(bestST, -1, sizeof bestST);
    pq.push(pii(0, s));
    while(pq.size()){
        int dist = pq.top().first, u = pq.top().second; pq.pop();
        if(~bestST[u])
            continue;
        bestST[u] = dist;
        for(int i = 0; i < n; i++)
            if(adj[u][i] > 0)
                pq.push(pii(dist + adj[u][i], i));
    }
    if(bestST[t] != l)
        cout << "NO\n";
    else{
        cout << "YES\n";
        for(int i = 0; i < m; i++){
            W[i] = adj[U[i]][V[i]];
            cout << U[i] << ' ' << V[i] << ' ' << W[i] << '\n';
        }

    }
}
int main(){
    cin >> n >> m >> l >> s >> t;
    memset(adj, -1, sizeof adj);
    for(int i = 0; i < m; i++){
        int u, v, w;
        cin >> u >> v >> w;
        U[i] = u, V[i] = v, W[i] = w;
        adj[u][v] = adj[v][u] = w;
    }
    solve();
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
const int N = 1e3 + 20, M = 1e4 + 20;
int n, m, l, s, t, adj[N][N], bestTS[N], bestST[N], U[M], V[M], W[M];
void solve(){
    bool found = 0;
    int par = -1;
    priority_queue <pii, vector<pii>, greater<pii> >  pq;
    memset(bestST, -1, sizeof bestST), memset(bestTS, -1, sizeof bestTS);
    pq.push(pii(0, t));
    while(pq.size()){
        int dist = pq.top().first, u = pq.top().second; pq.pop();
        if(~bestTS[u])
            continue;
        bestTS[u] = dist;
        for(int i = 0; i < n; i++)
            if(adj[u][i] > 0)
                pq.push(pii(dist + adj[u][i], i));

    }
    // for(int i = 0; i < n; i++)
    //     cout << bestTS[i] << ' ';
    // cout << "=========================\n";
    while(pq.size())
        pq.pop();
    pq.push(pii(0, s));
    while(pq.size()){
        int dist = pq.top().first, u = pq.top().second; pq.pop();
        if(~bestST[u])
            continue;
        bestST[u] = dist;
        for(int i = 0; i < n; i++)
            if(adj[u][i] > 0)
                pq.push(pii(dist + adj[u][i], i));
            else if(adj[u][i] == 0){
                if(bestTS[i] != -1){
                    if(l - dist - bestTS[i] > 0)
                        found = 1;
                    adj[u][i] = adj[i][u] = max(1, l - dist - bestTS[i]);
                }
                else
                    adj[u][i] = adj[i][u] = 1;
                pq.push(pii(dist + adj[u][i], i));
            }
    }
    memset(bestST, -1, sizeof bestST);
    pq.push(pii(0, s));
    while(pq.size()){
        int dist = pq.top().first, u = pq.top().second; pq.pop();
        if(~bestST[u])
            continue;
        bestST[u] = dist;
        for(int i = 0; i < n; i++)
            if(adj[u][i] >= 0)
                pq.push(pii(dist + adj[u][i], i));
    }
    if(bestST[t] != l){
        cout << "NO\n";
        if(found)
            cout << "-_-\n";
    }
    else{
        cout << "YES\n";
        for(int i = 0; i < m; i++){
            W[i] = adj[U[i]][V[i]];
            cout << U[i] << ' ' << V[i] << ' ' << W[i] << '\n';
        }

    }
}
int main(){
    cin >> n >> m >> l >> s >> t;
    memset(adj, -1, sizeof adj);
    for(int i = 0; i < m; i++){
        int u, v, w;
        cin >> u >> v >> w;
        U[i] = u, V[i] = v, W[i] = w;
        adj[u][v] = adj[v][u] = w;
    }
    solve();
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef pair<ll, ll> pii;
const int N = 1e3 + 20, M = 1e4 + 20;
const ll OO = 1e15;
ll n, m, l, s, t, adj[N][N], bestTS[N], bestST[N], U[M], V[M], W[M];
void solve(){
    priority_queue <pii, vector<pii>, greater<pii> >  pq;
    memset(bestST, -1, sizeof bestST), memset(bestTS, -1, sizeof bestTS);
    pq.push(pii(0, t));
    while(pq.size()){
        ll dist = pq.top().first, u = pq.top().second; pq.pop();
        if(~bestTS[u])
            continue;
        bestTS[u] = dist;
        for(int i = 0; i < n; i++)
            if(adj[u][i] > 0)
                pq.push(pii(dist + adj[u][i], i));

    }
    // for(int i = 0; i < n; i++)
    //     cout << bestTS[i] << ' ';
    // cout << "=========================\n";
    while(pq.size())
        pq.pop();
    pq.push(pii(0, s));
    while(pq.size()){
        ll dist = pq.top().first, u = pq.top().second; pq.pop();
        if(~bestST[u])
            continue;
        bestST[u] = dist;
        if(bestST[u] != -1 && bestTS[u] != -1 && bestST[u] + bestTS[u] == l){
            cout << "YES\n";
            for(int i = 0; i < m; i++){
                W[i] = adj[U[i]][V[i]];
                if(W[i] == 0)
                    W[i] = l + 1;
               cout << U[i] << ' ' << V[i] << ' ' << W[i] << '\n';
            }
            return;
        }
        for(int i = 0; i < n; i++)
            if(adj[u][i] > 0)
                pq.push(pii(dist + adj[u][i], i));
            else if(adj[u][i] == 0){
                if(bestTS[i] != -1){
                    if(l - dist - bestTS[i] > 0)
                        adj[u][i] = adj[i][u] = l - dist - bestTS[i];
                    else
                        adj[u][i] = adj[i][u] = l + 1;
                }
                else
                    adj[u][i] = adj[i][u] = 1;
                pq.push(pii(dist + adj[u][i], i));
            }
    }
    // memset(bestST, -1, sizeof bestST);
    // pq.push(pii(0, s));
    // while(pq.size()){
    //     int dist = pq.top().first, u = pq.top().second; pq.pop();
    //     if(~bestST[u])
    //         continue;
    //     bestST[u] = dist;
    //     for(int i = 0; i < n; i++)
    //         if(adj[u][i] >= 0)
    //             pq.push(pii(dist + adj[u][i], i));
    // }
    // if(bestST[t] != l){
        cout << "NO\n";
        return;
    // }
    // else{
    //     cout << "YES\n";
    //     for(int i = 0; i < m; i++){
    //         W[i] = adj[U[i]][V[i]];
    //         cout << U[i] << ' ' << V[i] << ' ' << W[i] << '\n';
    //     }

    // }
}
int main(){
    cin >> n >> m >> l >> s >> t;
    memset(adj, -1, sizeof adj);
    for(int i = 0; i < m; i++){
        int u, v, w;
        cin >> u >> v >> w;
        U[i] = u, V[i] = v, W[i] = w;
        if(adj[u][v] != -1)
            cout << "BUG\n";
        adj[u][v] = adj[v][u] = w;
    }
    solve();
    return 0;
}


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

const int N = 1e3 + 7;
int n, m, L, s, t, visited[N], dist[N], pop[N];
map <pair<int, int>, int> mp;
#define INF 1e9 + 7
priority_queue <pair<int, int> > Q;
vector <pair<int, int> >G[N];

void dijkstra()
{
	fill(dist, dist + n, INF); dist[s] = 0; pop[s] = -1;
	fill(visited, visited + n, 0);
	Q.push({0, s});
	while(!Q.empty())
	{
		int u = Q.top().second; Q.pop();
		if(visited[u]) continue;
		visited[u] = true;
		for(int i = 0; i < (int)G[u].size(); i++)
		{
			int v = G[u][i].first;
			int c = G[u][i].second;
			if(dist[u] + c < dist[v])
			{
				dist[v] = dist[u] + c;
				pop[v] = u;
				Q.push({-dist[v], v});
			}
		}
	}
}

int main()
{
	scanf("%d%d%d%d%d", &n, &m, &L, &s, &t);
	for(int i = 0; i < m; i++)
	{
		int a, b, c; scanf("%d%d%d", &a, &b, &c);
		if(c == 0){
			mp[{a, b}] = G[a].size();
			mp[{b, a}] = G[b].size();
			c = 1;
		}
		G[a].push_back({b, c});
		G[b].push_back({a, c});
	}
	bool check = true;
	while(check)
	{
		dijkstra();
		if(dist[t] > L){check = false; break;}
		if(dist[t] == L) break;
		check = false;
		int k = t;
		while(pop[k] != -1)
		{
			printf("%d %d\n", k, pop[k]);
			if(mp.count({k, pop[k]}))
			{
				auto &a1 = G[k][mp[{k, pop[k]}]].second;
				auto &a2 = G[pop[k]][mp[{pop[k], k}]].second;
				a1 += L - dist[t]; a2 += L - dist[t];
				check = true;
				break;
			}
			k = pop[k];
		}
	}
	if(!check) puts("NO");
	else{
		puts("YES");
		for(int i = 0; i < n; i++)
		{
			for(int j = 0; j < (int)G[i].size(); j++)
				if(G[i][j].first > i) printf("%d %d %d\n", i, G[i][j].first, G[i][j].second);
		}
	}
	return 0;
}


#include <stdio.h>
#include <queue>
#include <map>
#include <vector>
using namespace std;

const int N = 1e3 + 7;
int n, m, L, s, t, visited[N], dist[N], pop[N];
map <pair<int, int>, int> mp;
#define INF 1e9 + 7
priority_queue <pair<int, int> > Q;
vector <pair<int, int> >G[N];

void dijkstra()
{
	fill(dist, dist + n, INF); dist[s] = 0; pop[s] = -1;
	fill(visited, visited + n, 0);
	Q.push({0, s});
	while(!Q.empty())
	{
		int u = Q.top().second; Q.pop();
		if(visited[u]) continue;
		visited[u] = true;
		for(int i = 0; i < (int)G[u].size(); i++)
		{
			int v = G[u][i].first;
			int c = G[u][i].second;
			if(dist[u] + c < dist[v])
			{
				dist[v] = dist[u] + c;
				pop[v] = u;
				Q.push({-dist[v], v});
			}
		}
	}
}

int main()
{
	scanf("%d%d%d%d%d", &n, &m, &L, &s, &t);
	for(int i = 0; i < m; i++)
	{
		int a, b, c; scanf("%d%d%d", &a, &b, &c);
		if(c == 0){
			mp[{a, b}] = G[a].size();
			mp[{b, a}] = G[b].size();
			c = 1;
		}
		G[a].push_back({b, c});
		G[b].push_back({a, c});
	}
	bool check = true;
	while(check)
	{
		dijkstra();
		if(dist[t] > L){check = false; break;}
		if(dist[t] == L) break;
		check = false;
		int k = t;
		while(pop[k] != -1)
		{
			if(mp.count({k, pop[k]}))
			{
				auto &a1 = G[k][mp[{k, pop[k]}]].second;
				auto &a2 = G[pop[k]][mp[{pop[k], k}]].second;
				a1 += L - dist[t]; a2 += L - dist[t];
				check = true;
				break;
			}
			k = pop[k];
		}
	}
	if(!check) puts("NO");
	else{
		puts("YES");
		for(int i = 0; i < n; i++)
		{
			for(int j = 0; j < (int)G[i].size(); j++)
				if(G[i][j].first > i) printf("%d %d %d\n", i, G[i][j].first, G[i][j].second);
		}
	}
	return 0;
}


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

const int N = 1e3 + 7;
int n, m, L, s, t, visited[N], dist[N], pop[N];
map <pair<int, int>, int> mp;
#define INF 1e9 + 7
priority_queue <pair<int, int> > Q;
vector <pair<int, int> >G[N];

void dijkstra()
{
	fill(dist, dist + n, INF); dist[s] = 0; pop[s] = -1;
	fill(visited, visited + n, 0);
	Q.push({0, s});
	while(!Q.empty())
	{
		int u = Q.top().second; Q.pop();
		if(visited[u]) continue;
		visited[u] = true;
		for(int i = 0; i < (int)G[u].size(); i++)
		{
			int v = G[u][i].first;
			int c = G[u][i].second;
			if(dist[u] + c < dist[v])
			{
				dist[v] = dist[u] + c;
				pop[v] = u;
				Q.push({-dist[v], v});
			}
		}
	}
}

int main()
{
	scanf("%d%d%d%d%d", &n, &m, &L, &s, &t);
	for(int i = 0; i < m; i++)
	{
		int a, b, c; scanf("%d%d%d", &a, &b, &c);
		if(c == 0){
			mp[{a, b}] = G[a].size();
			mp[{b, a}] = G[b].size();
			c = 1;
		}
		G[a].push_back({b, c});
		G[b].push_back({a, c});
	}
	bool check = true;
	while(check)
	{
		dijkstra();
		if(dist[t] > L){check = false; break;}
		if(dist[t] == L) break;
		check = false;
		int k = t;
		while(pop[k] != -1)
		{
			if(mp.count({k, pop[k]}))
			{
				auto &a1 = G[k][mp[{k, pop[k]}]].second;
				auto &a2 = G[pop[k]][mp[{pop[k], k}]].second;
				a1 += L - dist[t]; a2 += L - dist[t];
				check = true;
				break;
			}
			k = pop[k];
		}
	}
	if(!check) puts("NO");
	else{
		puts("YES");
		for(int i = 0; i < n; i++)
		{
			for(int j = 0; j < (int)G[i].size(); j++)
				if(G[i][j].first > i) printf("%d %d %d\n", i, G[i][j].first, G[i][j].second);
		}
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 4;

struct Edge {
	int v, cost, i;
};
vector<Edge> adj[N];
Edge parent[N];

long long dijkstra(int source, int destination) {
	long long dist[N];
	memset(parent, -1, sizeof parent);
	memset(dist, 0x3f, sizeof dist);
	// first: cost, second: node
	priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> q;
	q.push({0, source});
	while (!q.empty()) {
		auto cur = q.top();
		q.pop();
		long long cost = cur.first;
		int node = cur.second;
		if (dist[node] < cost)
			continue;
		dist[node] = cost;
		for (auto child: adj[node]) {
			if (dist[child.v] > cost + child.cost) {
				parent[child.v] = {node, child.cost, child.i};
				dist[child.v] = cost + child.cost;
				q.push({cost + child.cost, child.v});
			}
		}
	}
	return dist[destination];
}
int u[N], v[N], c[N];
bool erased[N];
int zeros(int t) {
	int node = t;
	int ret = 0;
	while (~parent[node].v) {
		if (erased[parent[node].i])
			++ret;
		node = parent[node].v;
	}
	return ret;
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("input.in", "r", stdin);
#endif
	int n, m, l, s, t;
	scanf("%d %d %d %d %d", &n, &m, &l, &s, &t);
	for (int i = 0; i < m; ++i) {
		scanf("%d %d %d", u + i, v + i, c + i);
		erased[i] = c[i] == 0;
		if (!c[i])
			c[i] = 1;
		adj[u[i]].push_back({v[i], c[i], i});
		adj[v[i]].push_back({u[i], c[i], i});
	}
	long long dis;
	int temp = 1e4;
	while (temp--) {
		dis = dijkstra(s, t);
		if (dis == l)
			break;
		if (dis > l) {
			puts("NO");
			return 0;
		}
		cout << dis << endl;
		int node = t;
		bool first = false;
		bool leave[N] = {};
		while (~parent[node].v) {
			if (erased[parent[node].i]) {
				leave[parent[node].i] = true;
				if (!first++)
					c[parent[node].i] = max(1, c[parent[node].i] + l - (int) dis);
			}
			node = parent[node].v;
		}
		for (int i = 0; i < m; ++i)
			if (erased[i] && !leave[i])
				c[i] = 2e9;
		for (int i = 0; i < n; ++i)
			for (auto &child: adj[i])
				child.cost = c[child.i];
	}
	if (dis != l) {
		puts("NO");
	} else {
		puts("YES");
		for (int i = 0; i < m; ++i)
			printf("%d %d %d\n", u[i], v[i], c[i]);
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 4;

bool erased[N];

struct Edge {
	int v;
	long long cost;
	int i;
	int zeros;
	int p;
	bool operator<(const Edge &e) const {
		if (cost != e.cost)
			return cost > e.cost;
		return zeros > e.zeros;
	}
};

vector<Edge> adj[N];
Edge parent[N];

long long dijkstra(int source, int destination) {
	long long dist[N];
	memset(parent, -1, sizeof parent);
	memset(dist, 0x3f, sizeof dist);
	// first: cost, second: node
	priority_queue<Edge> q;
	q.push({source, 0, -1, 0});
	while (!q.empty()) {
		auto cur = q.top();
		q.pop();
		if (dist[cur.v] < 1e18)
			continue;
		dist[cur.v] = cur.cost;
		parent[cur.v] = {cur.p, 0, cur.i, cur.zeros};
		if (cur.v == destination)
			break;
		for (auto child: adj[cur.v])
			if (dist[child.v] > 1e18)
				q.push({child.v, cur.cost + child.cost, child.i, cur.zeros + erased[child.i], cur.v});
	}
	return dist[destination];
}
int u[N], v[N], c[N];
int main() {
#ifndef ONLINE_JUDGE
	freopen("input.in", "r", stdin);
#endif
	int n, m, l, s, t;
	scanf("%d %d %d %d %d", &n, &m, &l, &s, &t);
	for (int i = 0; i < m; ++i) {
		scanf("%d %d %d", u + i, v + i, c + i);
		erased[i] = c[i] == 0;
		if (!c[i])
			c[i] = 1;
		adj[u[i]].push_back({v[i], c[i], i});
		adj[v[i]].push_back({u[i], c[i], i});
	}
	long long dis = dijkstra(s, t);
	if (dis > l || parent[t].zeros == 0 && dis < l) {
		puts("NO");
		return 0;
	}
	int node = t;
	bool first = false;
	bool leave[N] = {};
	while (node != s) {
		if (erased[parent[node].i]) {
			leave[parent[node].i] = true;
			if (!first++)
				c[parent[node].i] = max(1, c[parent[node].i] + l - (int) dis);
		}
		node = parent[node].v;
	}
	for (int i = 0; i < m; ++i)
		if (erased[i] && !leave[i])
			c[i] = 2e9;
	puts("YES");
	for (int i = 0; i < m; ++i)
		printf("%d %d %d\n", u[i], v[i], c[i]);
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 4;

struct Edge {
	int v, cost, i;
};
vector<Edge> adj[N];
Edge parent[N];

long long dijkstra(int source, int destination) {
	long long dist[N];
	memset(parent, -1, sizeof parent);
	memset(dist, 0x3f, sizeof dist);
	// first: cost, second: node
	priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> q;
	q.push({0, source});
	while (!q.empty()) {
		auto cur = q.top();
		q.pop();
		long long cost = cur.first;
		int node = cur.second;
		if (dist[node] < cost)
			continue;
		dist[node] = cost;
		for (auto child: adj[node]) {
			if (dist[child.v] > cost + child.cost) {
				parent[child.v] = {node, child.cost, child.i};
				dist[child.v] = cost + child.cost;
				q.push({cost + child.cost, child.v});
			}
		}
	}
	return dist[destination];
}
int u[N], v[N], c[N];

int zeros(int t) {
	int node = t;
	int ret = 0;
	while (~parent[node].v) {
		if (parent[node].cost == 0)
			++ret;
		node = parent[node].v;
	}
	return ret;
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("input.in", "r", stdin);
#endif
	int n, m, l, s, t;
	scanf("%d %d %d %d %d", &n, &m, &l, &s, &t);
	for (int i = 0; i < m; ++i) {
		scanf("%d %d %d", u + i, v + i, c + i);
		adj[u[i]].push_back({v[i], c[i], i});
		adj[v[i]].push_back({u[i], c[i], i});
	}
	long long dis;
	while (true) {
		dis = dijkstra(s, t);
		int change = zeros(t);
		if (dis > l) {
			puts("NO");
			return 0;
		}
		int node = t;
		bool first = false;
		long long path = 0;
		while (~parent[node].v) {
			if (parent[node].cost == 0) {
				if (first++)
					c[parent[node].i] = 1;
				else
					c[parent[node].i] = max(1, l - (int) dis - change + 1);
			}
			path += c[parent[node].i];
			node = parent[node].v;
		}
		if (path == t) {
			for (int i = 0; i < m; ++i)
				if (!c[i])
					c[i] = 2e9;
		}
		for (int i = 0; i < n; ++i)
			for (auto &child: adj[i])
				child.cost = c[child.i];
		if (change == 0)
			break;
	}
	if (dijkstra(s, t) != l) {
		puts("NO");
	} else {
		puts("YES");
		for (int i = 0; i < m; ++i)
			printf("%d %d %d\n", u[i], v[i], c[i]);
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int N = 1e4 + 3;

struct Edge {
	int v, cost, i;
};
vector<Edge> adj[N];
bool erased[N];
long long dist[2][N];
int n, m, l, s, t;
int u[N], v[N], c[N];
long long dijkstra(int source, int destination, bool index) {
	memset(dist[index], 0x3f, sizeof dist[index]);
	// first: cost, second: node
	priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> q;
	q.push({0, source});
	while (!q.empty()) {
		auto cur = q.top();
		q.pop();
		long long cost = cur.first;
		int node = cur.second;
		if (dist[index][node] < 1e18)
			continue;
		dist[index][node] = cost;
		for (auto child: adj[node]) {
			if (dist[index][child.v] > 1e18) {
				if (index && erased[child.i] && dist[1][node] + child.cost + dist[0][child.v] < l) {
					child.cost = l - dist[0][child.v] - dist[1][node];
					c[child.i] = l - dist[0][child.v] - dist[1][node];
				}
				q.push({cost + child.cost, child.v});
			}
		}
	}
	return dist[index][destination];
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("input.in", "r", stdin);
#endif
	scanf("%d %d %d %d %d", &n, &m, &l, &s, &t);
	for (int i = 0; i < m; ++i) {
		scanf("%d %d %d", u + i, v + i, c + i);
		if (c[i] == 0) {
			erased[i] = true;
			c[i] = 1;
		}
		adj[u[i]].push_back({v[i], c[i], i});
		adj[v[i]].push_back({u[i], c[i], i});
	}
	dijkstra(s, t, 0);
	dijkstra(t, s, 1);
	for (int i = 0; i < n; ++i)
		for (auto &child: adj[i])
			child.cost = c[child.i];
	if (dijkstra(s, t, 0) == l) {
		puts("YES");
		for (int i = 0; i < m; ++i) {
			printf("%d %d %d\n", u[i], v[i], c[i]);
		}
	} else {
		puts("NO");
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 4;

struct Edge {
	int v, cost, i;
};
vector<Edge> adj[N];
Edge parent[N];

long long dijkstra(int source, int destination) {
	long long dist[N];
	memset(parent, -1, sizeof parent);
	memset(dist, 0x3f, sizeof dist);
	// first: cost, second: node
	priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> q;
	q.push({0, source});
	while (!q.empty()) {
		auto cur = q.top();
		q.pop();
		long long cost = cur.first;
		int node = cur.second;
		if (dist[node] < cost)
			continue;
		dist[node] = cost;
		if (node == destination)
			break;
		for (auto child: adj[node]) {
			if (dist[child.v] > cost + child.cost) {
				parent[child.v] = {node, child.cost, child.i};
				dist[child.v] = cost + child.cost;
				q.push({cost + child.cost, child.v});
			}
			if (dist[child.v] == cost + child.cost && child.cost != 0) {
				parent[child.v] = {node, child.cost, child.i};
			}
		}
	}
	return dist[destination];
}
int u[N], v[N], c[N];

int check(int t) {
	int node = t;
	int ret = 0;
	while (~parent[node].v) {
		if (parent[node].cost == 0)
			++ret;
		node = parent[node].v;
	}
	return ret;
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("input.in", "r", stdin);
#endif
	int n, m, l, s, t;
	scanf("%d %d %d %d %d", &n, &m, &l, &s, &t);
	for (int i = 0; i < m; ++i) {
		scanf("%d %d %d", u + i, v + i, c + i);
		adj[u[i]].push_back({v[i], c[i], i});
		adj[v[i]].push_back({u[i], c[i], i});
	}
	long long dis;
	while (true) {
		dis = dijkstra(s, t);
		int change = check(t);
		if (l != dis && change == 0 || dis > l) {
			puts("NO");
			return 0;
		}
		int node = t;
		bool first = false;
		while (~parent[node].v) {
			if (parent[node].cost == 0) {
				if (first++)
					c[parent[node].i] = 1;
				else
					c[parent[node].i] = max(1, l - (int) dis - change + 1);
			}
			node = parent[node].v;
		}
		for (int i = 0; i < m; ++i)
			if (!c[i])
				c[i] = 2e9;

		for (int i = 0; i < n; ++i)
			for (auto &child: adj[i])
				child.cost = c[child.i];
		if (dis == l && change == 0)
			break;
	}
	puts("YES");
	for (int i = 0; i < m; ++i) {
		printf("%d %d %d\n", u[i], v[i], c[i]);
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 4;

struct Edge {
	int v, cost, i;
};
vector<Edge> adj[N];
Edge parent[N];

long long dijkstra(int source, int destination) {
	long long dist[N];
	memset(parent, -1, sizeof parent);
	memset(dist, 0x3f, sizeof dist);
	// first: cost, second: node
	priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> q;
	q.push({0, source});
	while (!q.empty()) {
		auto cur = q.top();
		q.pop();
		long long cost = cur.first;
		int node = cur.second;
		if (dist[node] < cost)
			continue;
		dist[node] = cost;
		for (auto child: adj[node]) {
			if (dist[child.v] > cost + child.cost) {
				parent[child.v] = {node, child.cost, child.i};
				dist[child.v] = cost + child.cost;
				q.push({cost + child.cost, child.v});
			}
		}
	}
	return dist[destination];
}
int u[N], v[N], c[N];

int zeros(int t) {
	int node = t;
	int ret = 0;
	while (~parent[node].v) {
		if (parent[node].cost == 0)
			++ret;
		node = parent[node].v;
	}
	return ret;
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("input.in", "r", stdin);
#endif
	int n, m, l, s, t;
	scanf("%d %d %d %d %d", &n, &m, &l, &s, &t);
	for (int i = 0; i < m; ++i) {
		scanf("%d %d %d", u + i, v + i, c + i);
		adj[u[i]].push_back({v[i], c[i], i});
		adj[v[i]].push_back({u[i], c[i], i});
	}
	long long dis;
	while (true) {
		dis = dijkstra(s, t);
		int change = zeros(t);
		if (dis > l) {
			puts("NO");
			return 0;
		}
		int node = t;
		bool first = false;
		long long path = 0;
		while (~parent[node].v) {
			if (parent[node].cost == 0) {
				if (first++)
					c[parent[node].i] = 1;
				else
					c[parent[node].i] = max(1, l - (int) dis - change + 1);
			}
			path += c[parent[node].i];
			node = parent[node].v;
		}
//		if (path == t) {
			for (int i = 0; i < m; ++i)
				if (!c[i])
					c[i] = 2e9;
//		}
		for (int i = 0; i < n; ++i)
			for (auto &child: adj[i])
				child.cost = c[child.i];
		if (change == 0)
			break;
	}
	if (dijkstra(s, t) != l) {
		puts("NO");
	} else {
		puts("YES");
		for (int i = 0; i < m; ++i)
			printf("%d %d %d\n", u[i], v[i], c[i]);
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 4;

struct Edge {
	int v, cost, i;
};
vector<Edge> adj[N];
Edge parent[N];

long long dijkstra(int source, int destination) {
	long long dist[N];
	memset(parent, -1, sizeof parent);
	memset(dist, 0x3f, sizeof dist);
	// first: cost, second: node
	priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> q;
	q.push({0, source});
	while (!q.empty()) {
		auto cur = q.top();
		q.pop();
		long long cost = cur.first;
		int node = cur.second;
		if (dist[node] < cost)
			continue;
		dist[node] = cost;
		if (node == destination)
			break;
		for (auto child: adj[node]) {
			if (dist[child.v] > cost + child.cost) {
				parent[child.v] = {node, child.cost, child.i};
				dist[child.v] = cost + child.cost;
				q.push({cost + child.cost, child.v});
			}
			if (dist[child.v] == cost + child.cost && child.cost != 0) {
				parent[child.v] = {node, child.cost, child.i};
			}
		}
	}
	return dist[destination];
}
int u[N], v[N], c[N];
bool done[N];

int check(int t) {
	int node = t;
	int ret = 0;
	while (~parent[node].v) {
		if (parent[node].cost == 0)
			++ret;
		node = parent[node].v;
	}
	return ret;
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("input.in", "r", stdin);
#endif
	int n, m, l, s, t;
	scanf("%d %d %d %d %d", &n, &m, &l, &s, &t);
	for (int i = 0; i < m; ++i) {
		scanf("%d %d %d", u + i, v + i, c + i);
		adj[u[i]].push_back({v[i], c[i], i});
		adj[v[i]].push_back({u[i], c[i], i});
	}
	long long dis = dijkstra(s, t);
	if (dis <= l) {
		int change = check(t);
		if (l - dis < change) {
			puts("NO");
			return 0;
		}
		puts("YES");
		int node = t;
		while (~parent[node].v) {
			if (parent[node].cost == 0) {
				--change;
				printf("%d %d %d\n", node, parent[node].v, l - (int) dis - change);
			} else {
				printf("%d %d %d\n", node, parent[node].v, parent[node].cost);
			}
			done[parent[node].i] = true;
			node = parent[node].v;
		}
		for (int i = 0; i < m; ++i) {
			if (done[i])
				continue;
			if (!c[i])
				printf("%d %d %lld\n", u[i], v[i], 1LL << 55);
			else
				printf("%d %d %d\n", u[i], v[i], c[i]);
		}
	} else {
		puts("NO");
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 4;

struct Edge {
	int v, cost, i;
};
vector<Edge> adj[N];
Edge parent[N];

long long dijkstra(int source, int destination) {
	long long dist[N];
	memset(parent, -1, sizeof parent);
	memset(dist, 0x3f, sizeof dist);
	// first: cost, second: node
	priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> q;
	q.push({0, source});
	while (!q.empty()) {
		auto cur = q.top();
		q.pop();
		long long cost = cur.first;
		int node = cur.second;
		if (dist[node] < cost)
			continue;
		dist[node] = cost;
		for (auto child: adj[node]) {
			if (dist[child.v] > cost + child.cost) {
				parent[child.v] = {node, child.cost, child.i};
				dist[child.v] = cost + child.cost;
				q.push({cost + child.cost, child.v});
			}
		}
	}
	return dist[destination];
}
int u[N], v[N], c[N];

int zeros(int t) {
	int node = t;
	int ret = 0;
	while (~parent[node].v) {
		if (parent[node].cost == 0)
			++ret;
		node = parent[node].v;
	}
	return ret;
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("input.in", "r", stdin);
#endif
	int n, m, l, s, t;
	scanf("%d %d %d %d %d", &n, &m, &l, &s, &t);
	for (int i = 0; i < m; ++i) {
		scanf("%d %d %d", u + i, v + i, c + i);
		adj[u[i]].push_back({v[i], c[i], i});
		adj[v[i]].push_back({u[i], c[i], i});
	}
	long long dis;
	while (true) {
		dis = dijkstra(s, t);
		int change = zeros(t);
		if (dis > l) {
			puts("NO");
			return 0;
		}
		int node = t;
		bool first = false;
		while (~parent[node].v) {
			if (parent[node].cost == 0) {
				if (first++)
					c[parent[node].i] = 1;
				else
					c[parent[node].i] = max(1, l - (int) dis - change + 1);
			}
			node = parent[node].v;
		}
		for (int i = 0; i < m; ++i)
			if (!c[i])
				c[i] = 2e9;
		for (int i = 0; i < n; ++i)
			for (auto &child: adj[i])
				child.cost = c[child.i];
		if (change == 0)
			break;
	}
	if (dijkstra(s, t) != l) {
		puts("NO");
	} else {
		puts("YES");
		for (int i = 0; i < m; ++i)
			printf("%d %d %d\n", u[i], v[i], c[i]);
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 4;

struct Edge {
	int v, cost, i;
};
vector<Edge> adj[N];
Edge parent[N];

long long dijkstra(int source, int destination) {
	long long dist[N];
	memset(parent, -1, sizeof parent);
	memset(dist, 0x3f, sizeof dist);
	// first: cost, second: node
	priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> q;
	q.push({0, source});
	while (!q.empty()) {
		auto cur = q.top();
		q.pop();
		long long cost = cur.first;
		int node = cur.second;
		if (dist[node] < cost)
			continue;
		dist[node] = cost;
		for (auto child: adj[node]) {
			if (dist[child.v] > cost + child.cost) {
				parent[child.v] = {node, child.cost, child.i};
				dist[child.v] = cost + child.cost;
				q.push({cost + child.cost, child.v});
			}
		}
	}
	return dist[destination];
}
int u[N], v[N], c[N];

int zeros(int t) {
	int node = t;
	int ret = 0;
	while (~parent[node].v) {
		if (parent[node].cost == 0)
			++ret;
		node = parent[node].v;
	}
	return ret;
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("input.in", "r", stdin);
#endif
	int n, m, l, s, t;
	scanf("%d %d %d %d %d", &n, &m, &l, &s, &t);
	for (int i = 0; i < m; ++i) {
		scanf("%d %d %d", u + i, v + i, c + i);
		adj[u[i]].push_back({v[i], c[i], i});
		adj[v[i]].push_back({u[i], c[i], i});
	}
	long long dis;
	while (true) {
		dis = dijkstra(s, t);
		int change = zeros(t);
		if (dis > l) {
			puts("NO");
			return 0;
		}
		int node = t;
		bool first = false;
		long long path = 0;
		while (~parent[node].v) {
			if (parent[node].cost == 0) {
				if (first++)
					c[parent[node].i] = 1;
				else
					c[parent[node].i] = max(1, l - (int) dis - change + 1);
			}
			path += c[parent[node].i];
			node = parent[node].v;
		}
		if (path == l) {
			for (int i = 0; i < m; ++i)
				if (!c[i])
					c[i] = 2e9;
		}
		for (int i = 0; i < n; ++i)
			for (auto &child: adj[i])
				child.cost = c[child.i];
		if (change == 0)
			break;
	}
	if (dijkstra(s, t) != l) {
		puts("NO");
	} else {
		puts("YES");
		for (int i = 0; i < m; ++i)
			printf("%d %d %d\n", u[i], v[i], c[i]);
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 4;

struct Edge {
	int v, cost, i;
};
vector<Edge> adj[N];
Edge parent[N];

long long dijkstra(int source, int destination) {
	long long dist[N];
	memset(parent, -1, sizeof parent);
	memset(dist, 0x3f, sizeof dist);
	// first: cost, second: node
	priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> q;
	q.push({0, source});
	while (!q.empty()) {
		auto cur = q.top();
		q.pop();
		long long cost = cur.first;
		int node = cur.second;
		if (dist[node] < cost)
			continue;
		dist[node] = cost;
		if (node == destination)
			break;
		for (auto child: adj[node]) {
			if (dist[child.v] > cost + child.cost) {
				parent[child.v] = {node, child.cost, child.i};
				dist[child.v] = cost + child.cost;
				q.push({cost + child.cost, child.v});
			}
			if (dist[child.v] == cost + child.cost && child.cost != 0) {
				parent[child.v] = {node, child.cost, child.i};
			}
		}
	}
	return dist[destination];
}
int u[N], v[N], c[N];
bool done[N];

int check(int t) {
	int node = t;
	int ret = 0;
	while (~parent[node].v) {
		if (parent[node].cost == 0)
			++ret;
		node = parent[node].v;
	}
	return ret;
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("input.in", "r", stdin);
#endif
	int n, m, l, s, t;
	scanf("%d %d %d %d %d", &n, &m, &l, &s, &t);
	for (int i = 0; i < m; ++i) {
		scanf("%d %d %d", u + i, v + i, c + i);
		adj[u[i]].push_back({v[i], c[i], i});
		adj[v[i]].push_back({u[i], c[i], i});
	}
	long long dis;
	while (true) {
		dis = dijkstra(s, t);
		int change = check(t);
		if (l != dis && change == 0) {
			puts("NO");
			return 0;
		}
		if (dis > l || dis == l && change == 0)
			break;
		int node = t;
		while (~parent[node].v) {
			if (parent[node].cost == 0) {
				--change;
				c[parent[node].i] = max(1, l - (int) dis - change);
			}
			done[parent[node].i] = true;
			node = parent[node].v;
		}
		for (int i = 0; i < m; ++i)
			if (!c[i] && !done[i])
				c[i] = 2e9;

		for (int i = 0; i < n; ++i)
			for (auto &child: adj[i])
				child.cost = c[child.i];
	}
	if (dis > l) {
		puts("NO");
	} else {
		puts("YES");
		for (int i = 0; i < m; ++i) {
			printf("%d %d %d\n", u[i], v[i], c[i]);
		}
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 4;

struct Edge {
	int v, cost, i;
};
vector<Edge> adj[N];
Edge parent[N];

long long dijkstra(int source, int destination) {
	long long dist[N];
	memset(parent, -1, sizeof parent);
	memset(dist, 0x3f, sizeof dist);
	// first: cost, second: node
	priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> q;
	q.push({0, source});
	while (!q.empty()) {
		auto cur = q.top();
		q.pop();
		long long cost = cur.first;
		int node = cur.second;
		if (dist[node] < cost)
			continue;
		dist[node] = cost;
		if (node == destination)
			break;
		for (auto child: adj[node]) {
			if (dist[child.v] > cost + child.cost) {
				parent[child.v] = {node, child.cost, child.i};
				dist[child.v] = cost + child.cost;
				q.push({cost + child.cost, child.v});
			}
			if (dist[child.v] == cost + child.cost && child.cost != 0) {
				parent[child.v] = {node, child.cost, child.i};
			}
		}
	}
	return dist[destination];
}
int u[N], v[N], c[N];
bool done[N];

int check(int t) {
	int node = t;
	int ret = 0;
	while (~parent[node].v) {
		if (parent[node].cost == 0)
			++ret;
		node = parent[node].v;
	}
	return ret;
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("input.in", "r", stdin);
#endif
	int n, m, l, s, t;
	scanf("%d %d %d %d %d", &n, &m, &l, &s, &t);
	for (int i = 0; i < m; ++i) {
		scanf("%d %d %d", u + i, v + i, c + i);
		adj[u[i]].push_back({v[i], c[i], i});
		adj[v[i]].push_back({u[i], c[i], i});
	}
	long long dis;
	while (true) {
		dis = dijkstra(s, t);
		int change = check(t);
		if (l - dis < change || l != dis && change == 0) {
			puts("NO");
			return 0;
		}
		if (dis > l || dis == l && change == 0)
			break;
		int node = t;
		while (~parent[node].v) {
			if (parent[node].cost == 0) {
				--change;
				c[parent[node].i] = l - (int) dis - change;
			}
			done[parent[node].i] = true;
			node = parent[node].v;
		}
		for (int i = 0; i < m; ++i)
			if (!c[i] && !done[i])
				c[i] = 2e9;

		for (int i = 0; i < n; ++i)
			for (auto &child: adj[i])
				child.cost = c[child.i];
	}
	if (dis > l) {
		puts("NO");
	} else {
		puts("YES");
		for (int i = 0; i < m; ++i) {
			printf("%d %d %d\n", u[i], v[i], c[i]);
		}
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 4;

bool erased[N];

struct Edge {
	int v;
	long long cost;
	int i;
	int zeros;
	int p;
	bool operator<(const Edge &e) const {
		if (cost != e.cost)
			return cost > e.cost;
		return zeros > e.zeros;
	}
};

vector<Edge> adj[N];
Edge parent[N];

long long dijkstra(int source, int destination) {
	long long dist[N];
	memset(parent, -1, sizeof parent);
	memset(dist, 0x3f, sizeof dist);
	// first: cost, second: node
	priority_queue<Edge> q;
	q.push({source, 0, -1, 0});
	while (!q.empty()) {
		auto cur = q.top();
		q.pop();
		if (dist[cur.v] < 1e18)
			continue;
		dist[cur.v] = cur.cost;
		parent[cur.v] = {cur.p, 0, cur.i, cur.zeros};
		if (cur.v == destination)
			break;
		for (auto child: adj[cur.v])
			if (dist[child.v] > 1e18)
				q.push({child.v, cur.cost + child.cost, child.i, cur.zeros + erased[child.i], cur.v});
	}
	return dist[destination];
}
int u[N], v[N], c[N];
int main() {
#ifndef ONLINE_JUDGE
	freopen("input.in", "r", stdin);
#endif
	int n, m, l, s, t;
	scanf("%d %d %d %d %d", &n, &m, &l, &s, &t);
	for (int i = 0; i < m; ++i) {
		scanf("%d %d %d", u + i, v + i, c + i);
		erased[i] = c[i] == 0;
		if (!c[i])
			c[i] = 1;
		adj[u[i]].push_back({v[i], c[i], i});
		adj[v[i]].push_back({u[i], c[i], i});
	}
	long long dis = dijkstra(s, t);
	if (dis > l || parent[t].zeros == 0 && dis < l) {
		puts("NO");
		return 0;
	}
	int node = t;
	bool first = false;
	bool leave[N] = {};
	while (node != s) {
		if (erased[parent[node].i]) {
			leave[parent[node].i] = true;
			if (!first++)
				c[parent[node].i] = max(1, c[parent[node].i] + l - (int) dis);
		}
		node = parent[node].v;
	}
	for (int i = 0; i < m; ++i)
		if (erased[i] && !leave[i])
			c[i] = 2e9;
	for (int i = 0; i < n; ++i)
		for (auto &child: adj[i])
			child.cost = c[child.i];
	if (dijkstra(s, t) != l) {
		puts("NO");
	} else {
		puts("YES");
		for (int i = 0; i < m; ++i)
			printf("%d %d %d\n", u[i], v[i], c[i]);
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 4;

struct Edge {
	int v, cost, i;
};
vector<Edge> adj[N];
Edge parent[N];

long long dijkstra(int source, int destination) {
	long long dist[N];
	memset(parent, -1, sizeof parent);
	memset(dist, 0x3f, sizeof dist);
	// first: cost, second: node
	priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> q;
	q.push({0, source});
	while (!q.empty()) {
		auto cur = q.top();
		q.pop();
		long long cost = cur.first;
		int node = cur.second;
		if (dist[node] < cost)
			continue;
		dist[node] = cost;
		for (auto child: adj[node]) {
			if (dist[child.v] > cost + child.cost) {
				parent[child.v] = {node, child.cost, child.i};
				dist[child.v] = cost + child.cost;
				q.push({cost + child.cost, child.v});
			}
		}
	}
	return dist[destination];
}
int u[N], v[N], c[N];
bool erased[N];
int zeros(int t) {
	int node = t;
	int ret = 0;
	while (~parent[node].v) {
		if (erased[parent[node].i])
			++ret;
		node = parent[node].v;
	}
	return ret;
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("input.in", "r", stdin);
#endif
	int n, m, l, s, t;
	scanf("%d %d %d %d %d", &n, &m, &l, &s, &t);
	for (int i = 0; i < m; ++i) {
		scanf("%d %d %d", u + i, v + i, c + i);
		erased[i] = c[i] == 0;
		if (!c[i])
			c[i] = 1;
		adj[u[i]].push_back({v[i], c[i], i});
		adj[v[i]].push_back({u[i], c[i], i});
	}
	long long dis;
	int temp = 1e4;
	while (temp--) {
		dis = dijkstra(s, t);
		if (dis == l)
			break;
		if (dis > l) {
			puts("NO");
			return 0;
		}
		int node = t;
		bool first = false;
		bool leave[N] = {};
		while (~parent[node].v) {
			if (erased[parent[node].i]) {
				leave[parent[node].i] = true;
				if (!first++)
					c[parent[node].i] = max(1, c[parent[node].i] + l - (int) dis);
			}
			node = parent[node].v;
		}
		for (int i = 0; i < m; ++i)
			if (erased[i] && !leave[i])
				c[i] = 2e9;
		for (int i = 0; i < n; ++i)
			for (auto &child: adj[i])
				child.cost = c[child.i];
	}
	if (dis != l) {
		puts("NO");
	} else {
		puts("YES");
		for (int i = 0; i < m; ++i)
			printf("%d %d %d\n", u[i], v[i], c[i]);
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 4;

struct Edge {
	int v, cost, i;
};
vector<Edge> adj[N];
Edge parent[N];

long long dijkstra(int source, int destination) {
	long long dist[N];
	memset(parent, -1, sizeof parent);
	memset(dist, 0x3f, sizeof dist);
	// first: cost, second: node
	priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> q;
	q.push({0, source});
	while (!q.empty()) {
		auto cur = q.top();
		q.pop();
		long long cost = cur.first;
		int node = cur.second;
		if (dist[node] < cost)
			continue;
		dist[node] = cost;
		for (auto child: adj[node]) {
			if (dist[child.v] > cost + child.cost) {
				parent[child.v] = {node, child.cost, child.i};
				dist[child.v] = cost + child.cost;
				q.push({cost + child.cost, child.v});
			}
		}
	}
	return dist[destination];
}
int u[N], v[N], c[N];
bool erased[N];
int zeros(int t) {
	int node = t;
	int ret = 0;
	while (~parent[node].v) {
		if (erased[parent[node].i])
			++ret;
		node = parent[node].v;
	}
	return ret;
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("input.in", "r", stdin);
#endif
	int n, m, l, s, t;
	scanf("%d %d %d %d %d", &n, &m, &l, &s, &t);
	for (int i = 0; i < m; ++i) {
		scanf("%d %d %d", u + i, v + i, c + i);
		erased[i] = c[i] == 0;
		if (!c[i])
			c[i] = 1;
		adj[u[i]].push_back({v[i], c[i], i});
		adj[v[i]].push_back({u[i], c[i], i});
	}
	long long dis;
	int temp = 1e3;
	while (temp--) {
		dis = dijkstra(s, t);
		if (dis == l)
			break;
		if (dis > l) {
			puts("NO");
			return 0;
		}
		int node = t;
		bool first = false;
		bool leave[N] = {};
		while (~parent[node].v) {
			if (erased[parent[node].i]) {
				leave[parent[node].i] = true;
				if (!first++)
					c[parent[node].i] = max(1, c[parent[node].i] + l - (int) dis);
			}
			node = parent[node].v;
		}
		for (int i = 0; i < m; ++i)
			if (erased[i] && !leave[i])
				c[i] = 2e9;
		for (int i = 0; i < n; ++i)
			for (auto &child: adj[i])
				child.cost = c[child.i];
	}
	if (dis != l) {
		puts("NO");
	} else {
		puts("YES");
		for (int i = 0; i < m; ++i)
			printf("%d %d %d\n", u[i], v[i], c[i]);
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 4;

struct Edge {
	int v, cost, i;
};
vector<Edge> adj[N];
Edge parent[N];

long long dijkstra(int source, int destination) {
	long long dist[N];
	memset(parent, -1, sizeof parent);
	memset(dist, 0x3f, sizeof dist);
	// first: cost, second: node
	priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> q;
	q.push({0, source});
	while (!q.empty()) {
		auto cur = q.top();
		q.pop();
		long long cost = cur.first;
		int node = cur.second;
		if (dist[node] < cost)
			continue;
		dist[node] = cost;
		if (node == destination)
			break;
		for (auto child: adj[node]) {
			if (dist[child.v] > cost + child.cost) {
				parent[child.v] = {node, child.cost, child.i};
				dist[child.v] = cost + child.cost;
				q.push({cost + child.cost, child.v});
			}
			if (dist[child.v] == cost + child.cost && child.cost != 0) {
				parent[child.v] = {node, child.cost, child.i};
			}
		}
	}
	return dist[destination];
}
int u[N], v[N], c[N];
bool done[N];

int check(int t) {
	int node = t;
	int ret = 0;
	while (~parent[node].v) {
		if (parent[node].cost == 0)
			++ret;
		node = parent[node].v;
	}
	return ret;
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("input.in", "r", stdin);
#endif
	int n, m, l, s, t;
	scanf("%d %d %d %d %d", &n, &m, &l, &s, &t);
	for (int i = 0; i < m; ++i) {
		scanf("%d %d %d", u + i, v + i, c + i);
		adj[u[i]].push_back({v[i], c[i], i});
		adj[v[i]].push_back({u[i], c[i], i});
	}
	long long dis;
	while (true) {
		dis = dijkstra(s, t);
		int change = check(t);
		if (l != dis && change == 0) {
			puts("NO");
			return 0;
		}
		if (dis > l || dis == l && change == 0)
			break;
		int node = t;
		bool first = false;
		while (~parent[node].v) {
			if (parent[node].cost == 0) {
				if (first++)
					c[parent[node].i] = 1;
				else
					c[parent[node].i] = max(1, l - (int) dis - change);
			}
			done[parent[node].i] = true;
			node = parent[node].v;
		}
		for (int i = 0; i < m; ++i)
			if (!c[i] && !done[i])
				c[i] = 2e9;

		for (int i = 0; i < n; ++i)
			for (auto &child: adj[i])
				child.cost = c[child.i];
	}
	if (dis > l) {
		puts("NO");
	} else {
		puts("YES");
		for (int i = 0; i < m; ++i) {
			printf("%d %d %d\n", u[i], v[i], c[i]);
		}
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 4;

struct Edge {
	int v, cost, i;
};
vector<Edge> adj[N];
Edge parent[N];

long long dijkstra(int source, int destination) {
	long long dist[N];
	memset(parent, -1, sizeof parent);
	memset(dist, 0x3f, sizeof dist);
	// first: cost, second: node
	priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> q;
	q.push({0, source});
	while (!q.empty()) {
		auto cur = q.top();
		q.pop();
		long long cost = cur.first;
		int node = cur.second;
		if (dist[node] < cost)
			continue;
		dist[node] = cost;
		if (node == destination)
			break;
		for (auto child: adj[node]) {
			if (dist[child.v] > cost + child.cost) {
				parent[child.v] = {node, child.cost, child.i};
				dist[child.v] = cost + child.cost;
				q.push({cost + child.cost, child.v});
			}
			if (dist[child.v] == cost + child.cost && child.cost != 0) {
				parent[child.v] = {node, child.cost, child.i};
			}
		}
	}
	return dist[destination];
}
int u[N], v[N], c[N];
bool done[N];

int check(int t) {
	int node = t;
	int ret = 0;
	while (~parent[node].v) {
		if (parent[node].cost == 0)
			++ret;
		node = parent[node].v;
	}
	return ret;
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("input.in", "r", stdin);
#endif
	int n, m, l, s, t;
	scanf("%d %d %d %d %d", &n, &m, &l, &s, &t);
	for (int i = 0; i < m; ++i) {
		scanf("%d %d %d", u + i, v + i, c + i);
		adj[u[i]].push_back({v[i], c[i], i});
		adj[v[i]].push_back({u[i], c[i], i});
	}
	long long dis;
	while (true) {
		dis = dijkstra(s, t);
		int change = check(t);
		if (l != dis && change == 0) {
			puts("NO");
			return 0;
		}
		if (dis > l || dis == l && change == 0)
			break;
		int node = t;
		bool first = false;
		while (~parent[node].v) {
			if (parent[node].cost == 0) {
				if (first++)
					c[parent[node].i] = 1;
				else
					c[parent[node].i] = max(1, l - (int) dis - change + 1);
			}
			done[parent[node].i] = true;
			node = parent[node].v;
		}
		for (int i = 0; i < m; ++i)
			if (!c[i] && !done[i])
				c[i] = 2e9;

		for (int i = 0; i < n; ++i)
			for (auto &child: adj[i])
				child.cost = c[child.i];
	}
	if (dis > l) {
		puts("NO");
	} else {
		puts("YES");
		for (int i = 0; i < m; ++i) {
			printf("%d %d %d\n", u[i], v[i], c[i]);
		}
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 4;

struct Edge {
	int v, cost, i;
};
vector<Edge> adj[N];
Edge parent[N];

long long dijkstra(int source, int destination) {
	long long dist[N];
	memset(parent, -1, sizeof parent);
	memset(dist, 0x3f, sizeof dist);
	// first: cost, second: node
	priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> q;
	q.push({0, source});
	while (!q.empty()) {
		auto cur = q.top();
		q.pop();
		long long cost = cur.first;
		int node = cur.second;
		if (dist[node] < cost)
			continue;
		dist[node] = cost;
		for (auto child: adj[node]) {
			if (dist[child.v] > cost + child.cost) {
				parent[child.v] = {node, child.cost, child.i};
				dist[child.v] = cost + child.cost;
				q.push({cost + child.cost, child.v});
			}
		}
	}
	return dist[destination];
}
int u[N], v[N], c[N];
bool erased[N];
int zeros(int t) {
	int node = t;
	int ret = 0;
	while (~parent[node].v) {
		if (erased[parent[node].i])
			++ret;
		node = parent[node].v;
	}
	return ret;
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("input.in", "r", stdin);
#endif
	int n, m, l, s, t;
	scanf("%d %d %d %d %d", &n, &m, &l, &s, &t);
	for (int i = 0; i < m; ++i) {
		scanf("%d %d %d", u + i, v + i, c + i);
		adj[u[i]].push_back({v[i], c[i], i});
		adj[v[i]].push_back({u[i], c[i], i});
		erased[i] = c[i] == 0;
	}
	long long dis;
	while (true) {
		dis = dijkstra(s, t);
		int change = zeros(t);
		if (dis > l) {
			puts("NO");
			return 0;
		}
		int node = t;
		bool first = false;
		long long path = 0;
		while (~parent[node].v) {
			if (erased[parent[node].i] == 0) {
				if (first++)
					c[parent[node].i] = 1;
				else
					c[parent[node].i] = max(1, l - (int) dis - change + 1);
			}
			path += c[parent[node].i];
			node = parent[node].v;
		}
		if (path == l) {
			for (int i = 0; i < m; ++i)
				if (erased[i])
					c[i] = 2e9;
		}
		for (int i = 0; i < n; ++i)
			for (auto &child: adj[i])
				child.cost = c[child.i];
		if (change == 0)
			break;
	}
	if (dijkstra(s, t) != l) {
		puts("NO");
	} else {
		puts("YES");
		for (int i = 0; i < m; ++i)
			printf("%d %d %d\n", u[i], v[i], c[i]);
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 4;

struct Edge {
	int v, cost, i;
};
vector<Edge> adj[N];
Edge parent[N];

long long dijkstra(int source, int destination) {
	long long dist[N];
	memset(parent, -1, sizeof parent);
	memset(dist, 0x3f, sizeof dist);
	// first: cost, second: node
	priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> q;
	q.push({0, source});
	while (!q.empty()) {
		auto cur = q.top();
		q.pop();
		long long cost = cur.first;
		int node = cur.second;
		if (dist[node] < cost)
			continue;
		dist[node] = cost;
		for (auto child: adj[node]) {
			if (dist[child.v] > cost + child.cost) {
				parent[child.v] = {node, child.cost, child.i};
				dist[child.v] = cost + child.cost;
				q.push({cost + child.cost, child.v});
			}
		}
	}
	return dist[destination];
}
int u[N], v[N], c[N];
bool erased[N];
int zeros(int t) {
	int node = t;
	int ret = 0;
	while (~parent[node].v) {
		if (erased[parent[node].i])
			++ret;
		node = parent[node].v;
	}
	return ret;
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("input.in", "r", stdin);
#endif
	int n, m, l, s, t;
	scanf("%d %d %d %d %d", &n, &m, &l, &s, &t);
	for (int i = 0; i < m; ++i) {
		scanf("%d %d %d", u + i, v + i, c + i);
		erased[i] = c[i] == 0;
		if (!c[i])
			c[i] = 1;
		adj[u[i]].push_back({v[i], c[i], i});
		adj[v[i]].push_back({u[i], c[i], i});
	}
	long long dis;
	while (true) {
		dis = dijkstra(s, t);
		if (dis == l)
			break;
		if (dis > l) {
			puts("NO");
			return 0;
		}
		int node = t;
		bool first = false;
		bool leave[N] = {};
		while (~parent[node].v) {
			if (erased[parent[node].i]) {
				leave[parent[node].i] = true;
				if (!first++)
					c[parent[node].i] = max(1, c[parent[node].i] + l - (int) dis);
			}
			node = parent[node].v;
		}
		for (int i = 0; i < m; ++i)
			if (erased[i] && !leave[i])
				c[i] = 2e9;
		for (int i = 0; i < n; ++i)
			for (auto &child: adj[i])
				child.cost = c[child.i];
	}
	puts("YES");
	for (int i = 0; i < m; ++i)
		printf("%d %d %d\n", u[i], v[i], c[i]);
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int N = 1e5 + 4;

struct Edge {
	int v, cost, i;
};
vector<Edge> adj[N];
Edge parent[N];

long long dijkstra(int source, int destination) {
	long long dist[N];
	memset(parent, -1, sizeof parent);
	memset(dist, 0x3f, sizeof dist);
	// first: cost, second: node
	priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> q;
	q.push({0, source});
	while (!q.empty()) {
		auto cur = q.top();
		q.pop();
		long long cost = cur.first;
		int node = cur.second;
		if (dist[node] < cost)
			continue;
		dist[node] = cost;
		for (auto child: adj[node]) {
			if (dist[child.v] > cost + child.cost) {
				parent[child.v] = {node, child.cost, child.i};
				dist[child.v] = cost + child.cost;
				q.push({cost + child.cost, child.v});
			}
			if (dist[child.v] == cost + child.cost && child.cost != 0) {
				parent[child.v] = {node, child.cost, child.i};
			}
		}
	}
	return dist[destination];
}
int u[N], v[N], c[N];

int check(int t) {
	int node = t;
	int ret = 0;
	while (~parent[node].v) {
		if (parent[node].cost == 0)
			++ret;
		node = parent[node].v;
	}
	return ret;
}
int main() {
#ifndef ONLINE_JUDGE
	freopen("input.in", "r", stdin);
#endif
	int n, m, l, s, t;
	scanf("%d %d %d %d %d", &n, &m, &l, &s, &t);
	for (int i = 0; i < m; ++i) {
		scanf("%d %d %d", u + i, v + i, c + i);
		adj[u[i]].push_back({v[i], c[i], i});
		adj[v[i]].push_back({u[i], c[i], i});
	}
	long long dis;
	while (true) {
		dis = dijkstra(s, t);
		int change = check(t);
		if (l != dis && change == 0 || dis > l) {
			puts("NO");
			return 0;
		}
		int node = t;
		bool first = false;
		while (~parent[node].v) {
			if (parent[node].cost == 0) {
				if (first++)
					c[parent[node].i] = 1;
				else
					c[parent[node].i] = max(1, l - (int) dis - change + 1);
			}
			node = parent[node].v;
		}
		for (int i = 0; i < m; ++i)
			if (!c[i])
				c[i] = 2e9;

		for (int i = 0; i < n; ++i)
			for (auto &child: adj[i])
				child.cost = c[child.i];
		if (dis == l && change == 0)
			break;
	}
	puts("YES");
	for (int i = 0; i < m; ++i) {
		printf("%d %d %d\n", u[i], v[i], c[i]);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define int unsigned long long int
#define ii pair<int,int>
#define inf 1e15
#define infinity 1e10
#define N 1000000
vector<ii> e,adj[N];
int path[N],dist[N];
bool is[1010][1010];
int wi[1010][1010];
int n,m,L,s,t;
void di(){
    for(int i=0;i<=n;i++){
        dist[i]=inf;
    }
    set<ii> st;
    st.insert(ii(0,s));
    dist[s]=0;
    while(!st.empty())
    {
        int v=(*st.begin()).second,
            d=(*st.begin()).first;
        st.erase(st.begin());
        int sz=adj[v].size();
        for(int i=0;i<sz;i++){
            int nxt=adj[v][i].first;
            int cost=wi[v][nxt];
            if(cost+d<dist[nxt]){
                path[nxt]=v;
                if(dist[nxt]!=inf)
                    st.erase(st.find(ii(dist[nxt],nxt)));
                dist[nxt]=cost+d;
                st.insert(ii(dist[nxt],nxt));
            }
        }
    }
}
main(){
    memset(path,-1,sizeof(path));
    cin>>n>>m>>L>>s>>t;
    for(int i=0;i<m;i++){
        int u,v,w;
        cin>>u>>v>>w;
        if(w==0){
            is[u][v]=is[v][u]=1;
            w=1;
        }
        wi[u][v]=wi[v][u]=w;
        e.push_back(ii(u,v));
        adj[u].push_back(ii(v,w));
        adj[v].push_back(ii(u,w));
    }

    int v=t,total=0;
    di();
  //  cout<<dist[t]<<endl;
    if(dist[t]>L){
        cout<<"NO"<<endl;
        return 0;
    }
    total=dist[t];
    v=t;
    bool f=0;
    vector<ii> vec;
    while(1){
        int nxt=path[v];
        if(is[v][nxt]){
            is[v][nxt]=is[nxt][v]=0;
            vec.push_back(ii(v,nxt));
        }
        v=nxt;
        if(v==-1)
            break;
    }
    for(int i=0;i<=n;i++)
        for(int j=0;j<=n;j++)
            if(is[i][j])
                wi[i][j]=wi[j][i]=infinity;
    int sz=vec.size();
    for(int i=0;i<sz;i++){
                int nxt=vec[i].first,
                    v=vec[i].second;
                wi[v][nxt]=wi[nxt][v]=L-(total-1);
                di();
                if(dist[t]>=L)
                {
                    break;
                }
                total=dist[t];
    }
    if(dist[t]!=L){
        cout<<"NO"<<endl;
        return 0;
    }
    cout<<"YES"<<endl;
    for(int i=0;i<m;i++){
        int v=e[i].first,
            u=e[i].second;
        cout<<v<<" "<<u<<" "<<wi[v][u]<<endl;
    }

}


#include<bits/stdc++.h>
using namespace std;
#define ii pair<int,int>
#define N 1000000
vector<ii> e,adj[N];
int path[N],dist[N];
bool is[1010][1010];
int wi[1010][1010];

main(){
    memset(path,-1,sizeof(path));
    int n,m,L,s,t;
    cin>>n>>m>>L>>s>>t;
    for(int i=0;i<n;i++)
        dist[i]=1e9;
    for(int i=0;i<m;i++){
        int u,v,w;
        cin>>u>>v>>w;
        if(w==0){
            is[u][v]=is[v][u]=1;
            w=1;
        }
        wi[u][v]=wi[v][u]=w;
        e.push_back(ii(u,v));
        adj[u].push_back(ii(v,w));
        adj[v].push_back(ii(u,w));
    }
    set<ii> st;
    st.insert(ii(0,s));
    dist[s]=0;
    while(!st.empty())
    {
        int v=(*st.begin()).second,
            d=(*st.begin()).first;
        st.erase(st.begin());
        int sz=adj[v].size();
        for(int i=0;i<sz;i++){
            int nxt=adj[v][i].first,
                cost=adj[v][i].second;
            if(cost+d<dist[nxt]){
                path[nxt]=v;
                if(dist[nxt]!=1e9)
                    st.erase(st.find(ii(dist[nxt],nxt)));
                dist[nxt]=cost+d;
                st.insert(ii(dist[nxt],nxt));
            }
        }
    }
    int v=t,total=0;
  //  cout<<"HOO"<<endl;
    while(1){
        int nxt=path[v];
        total+=wi[nxt][v];
        v=nxt;
        if(v==s||v==-1)
            break;
    }
 //   cout<<total<<endl;
    if(total>L||v==-1){
        cout<<"NO"<<endl;
        return 0;
    }
    v=t;
    while(1){
        int nxt=path[v];
        if(is[v][nxt]){
            wi[v][nxt]=wi[nxt][v]=L-(total-1);
        }
        is[v][nxt]=is[nxt][v]=0;
        v=nxt;
        if(v==s||v==-1)
            break;
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(is[i][j]){
                wi[i][j]=1e9;
            }
        }
    }
    cout<<"YES"<<endl;
    for(int i=0;i<m;i++){
        int v=e[i].first,
            u=e[i].second;
        cout<<v<<" "<<u<<" "<<wi[v][u]<<endl;
    }

}


#include<bits/stdc++.h>
using namespace std;
#define int long long int
#define ii pair<int,int>
#define inf 1e15

#define N 1000000
vector<ii> e,adj[N];
int path[N],dist[N];
bool is[1010][1010];
int wi[1010][1010];
int n,m,L,s,t;
void di(){
    for(int i=0;i<=n;i++){
        dist[i]=inf;
    }
    set<ii> st;
    st.insert(ii(0,s));
    dist[s]=0;
    while(!st.empty())
    {
        int v=(*st.begin()).second,
            d=(*st.begin()).first;
        st.erase(st.begin());
        int sz=adj[v].size();
        for(int i=0;i<sz;i++){
            int nxt=adj[v][i].first;
            int cost=wi[v][nxt];
            if(cost+d<dist[nxt]){
                path[nxt]=v;
                if(dist[nxt]!=inf)
                    st.erase(st.find(ii(dist[nxt],nxt)));
                dist[nxt]=cost+d;
                st.insert(ii(dist[nxt],nxt));
            }
        }
    }
}
main(){
    memset(path,-1,sizeof(path));
    cin>>n>>m>>L>>s>>t;
    for(int i=0;i<m;i++){
        int u,v,w;
        cin>>u>>v>>w;
        if(w==0){
            is[u][v]=is[v][u]=1;
            w=1;
        }
        wi[u][v]=wi[v][u]=w;
        e.push_back(ii(u,v));
        adj[u].push_back(ii(v,w));
        adj[v].push_back(ii(u,w));
    }

    int v=t,total=0;
    di();
  //  cout<<dist[t]<<endl;
    if(dist[t]>L){
        cout<<"NO"<<endl;
        return 0;
    }
    total=dist[t];
    v=t;
    while(1){
        int nxt=path[v];
        if(is[v][nxt]){
            wi[v][nxt]=wi[nxt][v]=L-(total-1);
            total=L;
        }
        is[v][nxt]=is[nxt][v]=0;
        v=nxt;
        if(v==s)
            break;
    }
    for(int i=0;i<=n;i++){
        for(int j=0;j<=n;j++){
            if(is[i][j]){
                wi[i][j]=wi[j][i]=inf;
            }
        }
    }
    di();
    if(dist[t]<L){
        cout<<"NO"<<endl;
        return 0;
    }
    cout<<"YES"<<endl;
    for(int i=0;i<m;i++){
        int v=e[i].first,
            u=e[i].second;
        cout<<v<<" "<<u<<" "<<wi[v][u]<<endl;
    }

}


#include<bits/stdc++.h>
using namespace std;
#define int unsigned long long int
#define ii pair<int,int>
#define inf 1e15
#define infinity 1e10
#define N 1000000
vector<ii> e,adj[N];
int path[N],dist[N];
bool is[1010][1010];
int wi[1010][1010];
int n,m,L,s,t;
void di(){
    for(int i=0;i<=n;i++){
        dist[i]=inf;
    }
    set<ii> st;
    st.insert(ii(0,s));
    dist[s]=0;
    while(!st.empty())
    {
        int v=(*st.begin()).second,
            d=(*st.begin()).first;
        st.erase(st.begin());
        int sz=adj[v].size();
        for(int i=0;i<sz;i++){
            int nxt=adj[v][i].first;
            int cost=wi[v][nxt];
            if(cost+d<dist[nxt]){
                path[nxt]=v;
                if(dist[nxt]!=inf)
                    st.erase(st.find(ii(dist[nxt],nxt)));
                dist[nxt]=cost+d;
                st.insert(ii(dist[nxt],nxt));
            }
        }
    }
}
main(){
    memset(path,-1,sizeof(path));
    cin>>n>>m>>L>>s>>t;
    for(int i=0;i<m;i++){
        int u,v,w;
        cin>>u>>v>>w;
        if(w==0){
            is[u][v]=is[v][u]=1;
            w=1;
        }
        wi[u][v]=wi[v][u]=w;
        e.push_back(ii(u,v));
        adj[u].push_back(ii(v,w));
        adj[v].push_back(ii(u,w));
    }

    int v=t,total=0;
    di();
  //  cout<<dist[t]<<endl;
    if(dist[t]>L){
        cout<<"NO"<<endl;
        return 0;
    }
    total=dist[t];
    v=t;
    while(1){
        int nxt=path[v];
        if(is[v][nxt]){
            is[v][nxt]=is[nxt][v]=0;
            wi[v][nxt]=wi[nxt][v]=L-(total-1);
            di();
            if(dist[t]==L)
            {
                break;
            }
            total=dist[t];
            if(total>L)
                break;
        }
        v=nxt;
        if(v==s)
            break;
    }
    for(int i=0;i<=n;i++){
        for(int j=0;j<=n;j++){
            if(is[i][j]){
                wi[i][j]=wi[j][i]=infinity;
            }
        }
    }
    if(dist[t]!=L){
        cout<<"NO"<<endl;
        return 0;
    }
    cout<<"YES"<<endl;
    for(int i=0;i<m;i++){
        int v=e[i].first,
            u=e[i].second;
        cout<<v<<" "<<u<<" "<<wi[v][u]<<endl;
    }

}


#include<bits/stdc++.h>
using namespace std;
#define int unsigned long long int
#define ii pair<int,int>
#define inf 1e15
#define infinity 1e10
#define N 1000000
vector<ii> e,adj[N];
int path[N],dist[N];
bool is[1010][1010];
int wi[1010][1010];
int n,m,L,s,t;
void di(){
    for(int i=0;i<=n;i++){
        dist[i]=inf;
    }
    set<ii> st;
    st.insert(ii(0,s));
    dist[s]=0;
    while(!st.empty())
    {
        int v=(*st.begin()).second,
            d=(*st.begin()).first;
        st.erase(st.begin());
        int sz=adj[v].size();
        for(int i=0;i<sz;i++){
            int nxt=adj[v][i].first;
            int cost=wi[v][nxt];
            if(cost+d<dist[nxt]){
                path[nxt]=v;
                if(dist[nxt]!=inf)
                    st.erase(st.find(ii(dist[nxt],nxt)));
                dist[nxt]=cost+d;
                st.insert(ii(dist[nxt],nxt));
            }
        }
    }
}
main(){
    memset(path,-1,sizeof(path));
    cin>>n>>m>>L>>s>>t;
    for(int i=0;i<m;i++){
        int u,v,w;
        cin>>u>>v>>w;
        if(w==0){
            is[u][v]=is[v][u]=1;
            w=1;
        }
        wi[u][v]=wi[v][u]=w;
        e.push_back(ii(u,v));
        adj[u].push_back(ii(v,w));
        adj[v].push_back(ii(u,w));
    }

    int v=t,total=0;
    di();
  //  cout<<dist[t]<<endl;
    if(dist[t]>L){
        cout<<"NO"<<endl;
        return 0;
    }
    total=dist[t];
    v=t;
    bool f=0;
    while(1){
        int nxt=path[v];
        if(is[v][nxt]){
            is[v][nxt]=is[nxt][v]=0;
            if(!f){
                wi[v][nxt]=wi[nxt][v]=L-(total-1);
                di();
                if(dist[t]==L)
                {
                    f=1;
                }
                total=dist[t];
                if(total>L)
                    break;
            }
        }
        v=nxt;
        if(v==s)
            break;
    }
    for(int i=0;i<=n;i++){
        for(int j=0;j<=n;j++){
            if(is[i][j]){
                wi[i][j]=wi[j][i]=infinity;
            }
        }
    }
    if(dist[t]!=L){
        cout<<"NO"<<endl;
        return 0;
    }
    cout<<"YES"<<endl;
    for(int i=0;i<m;i++){
        int v=e[i].first,
            u=e[i].second;
        cout<<v<<" "<<u<<" "<<wi[v][u]<<endl;
    }

}


#include<bits/stdc++.h>
using namespace std;
#define int long long int
#define ii pair<int,int>
#define N 1000000
vector<ii> e,adj[N];
int path[N],dist[N];
bool is[1010][1010];
int wi[1010][1010];
int n,m,L,s,t;
void di(){
    for(int i=0;i<n;i++){
        dist[i]=1e14;
    }
    set<ii> st;
    st.insert(ii(0,s));
    dist[s]=0;
    while(!st.empty())
    {
        int v=(*st.begin()).second,
            d=(*st.begin()).first;
        st.erase(st.begin());
        int sz=adj[v].size();
        for(int i=0;i<sz;i++){
            int nxt=adj[v][i].first,
                cost=wi[v][nxt];
            if(cost+d<dist[nxt]){
                path[nxt]=v;
                if(dist[nxt]!=1e14)
                    st.erase(st.find(ii(dist[nxt],nxt)));
                dist[nxt]=cost+d;
                st.insert(ii(dist[nxt],nxt));
            }
        }
    }
}
main(){
    memset(path,-1,sizeof(path));
    cin>>n>>m>>L>>s>>t;
    for(int i=0;i<m;i++){
        int u,v,w;
        cin>>u>>v>>w;
        if(w==0){
            is[u][v]=is[v][u]=1;
            w=1;
        }
        wi[u][v]=wi[v][u]=w;
        e.push_back(ii(u,v));
        adj[u].push_back(ii(v,w));
        adj[v].push_back(ii(u,w));
    }

    int v=t,total=0;
    di();
    while(1){
        int nxt=path[v];
        total+=wi[nxt][v];
        v=nxt;
        if(v==s||v==-1)
            break;
    }
 //   cout<<total<<endl;
    if(total>L||v==-1){
        cout<<"NO"<<endl;
        return 0;
    }
    v=t;
    while(1){
        int nxt=path[v];
        if(is[v][nxt]){
            wi[v][nxt]=wi[nxt][v]=L-(total-1);
        //    cout<<v<<" "<<nxt<<" "<<wi[v][nxt]<<endl;
            total=L;
        }
        is[v][nxt]=is[nxt][v]=0;
        v=nxt;
        if(v==s||v==-1)
            break;
    }
    if(total!=L){
        cout<<"NO"<<endl;
        return 0;
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(is[i][j]){
                wi[i][j]=wi[j][i]=1e14;
            }
        }
    }
    di();
    if(dist[t]!=L){
       // cout<<dist[t]<<endl;
       v=t;
     /*  while(v!=s){
            cout<<v<<" "<<path[v]<<" "<<wi[v][path[v]]<<endl;
            v=path[v];
       }*/
        cout<<"NO"<<endl;
        return 0;
    }
    cout<<"YES"<<endl;
    for(int i=0;i<m;i++){
        int v=e[i].first,
            u=e[i].second;
        cout<<v<<" "<<u<<" "<<wi[v][u]<<endl;
    }

}


#include<bits/stdc++.h>
using namespace std;
#define int unsigned long long int
#define ii pair<int,int>
#define inf 1e15
#define infinity 1e10
#define N 1000000
vector<ii> e,adj[N];
int path[N],dist[N];
bool is[1010][1010];
int wi[1010][1010];
int n,m,L,s,t;
void di(){
    for(int i=0;i<=n;i++){
        dist[i]=inf;
    }
    set<ii> st;
    st.insert(ii(0,s));
    dist[s]=0;
    while(!st.empty())
    {
        int v=(*st.begin()).second,
            d=(*st.begin()).first;
        st.erase(st.begin());
        int sz=adj[v].size();
        for(int i=0;i<sz;i++){
            int nxt=adj[v][i].first;
            int cost=wi[v][nxt];
            if(cost+d<dist[nxt]){
                path[nxt]=v;
                if(dist[nxt]!=inf)
                    st.erase(st.find(ii(dist[nxt],nxt)));
                dist[nxt]=cost+d;
                st.insert(ii(dist[nxt],nxt));
            }
        }
    }
}
main(){
    memset(path,-1,sizeof(path));
    cin>>n>>m>>L>>s>>t;
    for(int i=0;i<m;i++){
        int u,v,w;
        cin>>u>>v>>w;
        if(w==0){
            is[u][v]=is[v][u]=1;
            w=1;
        }
        wi[u][v]=wi[v][u]=w;
        e.push_back(ii(u,v));
        adj[u].push_back(ii(v,w));
        adj[v].push_back(ii(u,w));
    }

    int v=t,total=0;
    di();
  //  cout<<dist[t]<<endl;
    if(dist[t]>L){
        cout<<"NO"<<endl;
        return 0;
    }
    total=dist[t];
    v=t;
    bool f=0;
    while(1){
        int nxt=path[v];
        if(is[v][nxt]){
            is[v][nxt]=is[nxt][v]=0;
            wi[v][nxt]=wi[nxt][v]=L-(total-1);
            di();
            if(dist[t]==L)
            {
                f=1;
                break;
            }
            total=dist[t];
        }
        v=nxt;
        if(v==s)
            break;
    }
    for(int i=0;i<=n;i++){
        for(int j=0;j<=n;j++){
            if(is[i][j]){
                wi[i][j]=wi[j][i]=infinity;
            }
        }
    }
    if(!f){
        cout<<"NO"<<endl;
        return 0;
    }
    cout<<"YES"<<endl;
    for(int i=0;i<m;i++){
        int v=e[i].first,
            u=e[i].second;
        cout<<v<<" "<<u<<" "<<wi[v][u]<<endl;
    }

}


#include<bits/stdc++.h>
using namespace std;
#define int long long int
#define ii pair<int,int>
#define N 1000000
vector<ii> e,adj[N];
int path[N],dist[N];
bool is[1010][1010];
int wi[1010][1010];
int n,m,L,s,t;
void di(){
    for(int i=0;i<n;i++){
        dist[i]=1e15;
    }
    set<ii> st;
    st.insert(ii(0,s));
    dist[s]=0;
    while(!st.empty())
    {
        int v=(*st.begin()).second,
            d=(*st.begin()).first;
        st.erase(st.begin());
        int sz=adj[v].size();
        for(int i=0;i<sz;i++){
            int nxt=adj[v][i].first,
                cost=wi[v][nxt];
            if(cost+d<dist[nxt]){
                path[nxt]=v;
                if(dist[nxt]!=1e15)
                    st.erase(st.find(ii(dist[nxt],nxt)));
                dist[nxt]=cost+d;
                st.insert(ii(dist[nxt],nxt));
            }
        }
    }
}
main(){
    memset(path,-1,sizeof(path));
    cin>>n>>m>>L>>s>>t;
    for(int i=0;i<m;i++){
        int u,v,w;
        cin>>u>>v>>w;
        if(w==0){
            is[u][v]=is[v][u]=1;
            w=1;
        }
        wi[u][v]=wi[v][u]=w;
        e.push_back(ii(u,v));
        adj[u].push_back(ii(v,w));
        adj[v].push_back(ii(u,w));
    }

    int v=t,total=0;
    di();
    while(1){
        int nxt=path[v];
        total+=wi[nxt][v];
        v=nxt;
        if(v==s||v==-1)
            break;
    }
 //   cout<<total<<endl;
    if(total>L||v==-1){
        cout<<"NO"<<endl;
        return 0;
    }
    v=t;
    while(1){
        int nxt=path[v];
        if(is[v][nxt]){
            wi[v][nxt]=wi[nxt][v]=L-(total-1);
        //    cout<<v<<" "<<nxt<<" "<<wi[v][nxt]<<endl;
            total=L;
        }
        is[v][nxt]=is[nxt][v]=0;
        v=nxt;
        if(v==s||v==-1)
            break;
    }
    if(total!=L){
        cout<<"NO"<<endl;
        return 0;
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(is[i][j]){
                wi[i][j]=wi[j][i]=1e15;
            }
        }
    }
    di();
    if(dist[t]!=L){
       // cout<<dist[t]<<endl;
       v=t;
     /*  while(v!=s){
            cout<<v<<" "<<path[v]<<" "<<wi[v][path[v]]<<endl;
            v=path[v];
       }*/
        cout<<"NO"<<endl;
        return 0;
    }
    cout<<"YES"<<endl;
    for(int i=0;i<m;i++){
        int v=e[i].first,
            u=e[i].second;
        cout<<v<<" "<<u<<" "<<wi[v][u]<<endl;
    }

}


#include<bits/stdc++.h>
using namespace std;
#define int long long int
#define ii pair<int,int>
#define N 1000000
vector<ii> e,adj[N];
int path[N],dist[N];
bool is[1010][1010];
int wi[1010][1010];
int n,m,L,s,t;
void di(){
    for(int i=0;i<n;i++){
        dist[i]=1e9;
    }
    set<ii> st;
    st.insert(ii(0,s));
    dist[s]=0;
    while(!st.empty())
    {
        int v=(*st.begin()).second,
            d=(*st.begin()).first;
        st.erase(st.begin());
        int sz=adj[v].size();
        for(int i=0;i<sz;i++){
            int nxt=adj[v][i].first,
                cost=wi[v][nxt];
            if(cost+d<dist[nxt]){
                path[nxt]=v;
                if(dist[nxt]!=1e9)
                    st.erase(st.find(ii(dist[nxt],nxt)));
                dist[nxt]=cost+d;
                st.insert(ii(dist[nxt],nxt));
            }
        }
    }
}
main(){
    memset(path,-1,sizeof(path));
    cin>>n>>m>>L>>s>>t;
    for(int i=0;i<m;i++){
        int u,v,w;
        cin>>u>>v>>w;
        if(w==0){
            is[u][v]=is[v][u]=1;
            w=1;
        }
        wi[u][v]=wi[v][u]=w;
        e.push_back(ii(u,v));
        adj[u].push_back(ii(v,w));
        adj[v].push_back(ii(u,w));
    }

    int v=t,total=0;
    di();
    while(1){
        int nxt=path[v];
        total+=wi[nxt][v];
        v=nxt;
        if(v==s||v==-1)
            break;
    }
 //   cout<<total<<endl;
    if(total>L||v==-1){
        cout<<"NO"<<endl;
        return 0;
    }
    v=t;
    while(1){
        int nxt=path[v];
        if(is[v][nxt]){
            wi[v][nxt]=wi[nxt][v]=L-(total-1);
        //    cout<<v<<" "<<nxt<<" "<<wi[v][nxt]<<endl;
            total=L;
        }
        is[v][nxt]=is[nxt][v]=0;
        v=nxt;
        if(v==s||v==-1)
            break;
    }
    if(total!=L){
        cout<<"NO"<<endl;
        return 0;
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(is[i][j]){
                wi[i][j]=wi[j][i]=1e9;
            }
        }
    }
    di();
    if(dist[t]!=L){
       // cout<<dist[t]<<endl;
       v=t;
     /*  while(v!=s){
            cout<<v<<" "<<path[v]<<" "<<wi[v][path[v]]<<endl;
            v=path[v];
       }*/
        cout<<"NO"<<endl;
        return 0;
    }
    cout<<"YES"<<endl;
    for(int i=0;i<m;i++){
        int v=e[i].first,
            u=e[i].second;
        cout<<v<<" "<<u<<" "<<wi[v][u]<<endl;
    }

}


#include<bits/stdc++.h>
using namespace std;
#define int long long int
#define ii pair<int,int>
#define N 1000000
vector<ii> e,adj[N];
int path[N],dist[N];
bool is[1010][1010];
int wi[1010][1010];
int n,m,L,s,t;
void di(){
    for(int i=0;i<n;i++){
        dist[i]=1e16;
    }
    set<ii> st;
    st.insert(ii(0,s));
    dist[s]=0;
    while(!st.empty())
    {
        int v=(*st.begin()).second,
            d=(*st.begin()).first;
        st.erase(st.begin());
        int sz=adj[v].size();
        for(int i=0;i<sz;i++){
            int nxt=adj[v][i].first,
                cost=wi[v][nxt];
            if(cost+d<dist[nxt]){
                path[nxt]=v;
                if(dist[nxt]!=1e16)
                    st.erase(st.find(ii(dist[nxt],nxt)));
                dist[nxt]=cost+d;
                st.insert(ii(dist[nxt],nxt));
            }
        }
    }
}
main(){
    memset(path,-1,sizeof(path));
    cin>>n>>m>>L>>s>>t;
    for(int i=0;i<m;i++){
        int u,v,w;
        cin>>u>>v>>w;
        if(w==0){
            is[u][v]=is[v][u]=1;
            w=1;
        }
        wi[u][v]=wi[v][u]=w;
        e.push_back(ii(u,v));
        adj[u].push_back(ii(v,w));
        adj[v].push_back(ii(u,w));
    }

    int v=t,total=0;
    di();
    while(1){
        int nxt=path[v];
        if(nxt!=-1)
            total+=wi[nxt][v];
        v=nxt;
        if(v==s||v==-1)
            break;
    }
 //   cout<<total<<endl;
    if(total>L||v==-1){
        cout<<"NO"<<endl;
        return 0;
    }
    v=t;
    while(1){
        int nxt=path[v];
        if(is[v][nxt]){
            wi[v][nxt]=wi[nxt][v]=L-(total-1);
        //    cout<<v<<" "<<nxt<<" "<<wi[v][nxt]<<endl;
            total=L;
        }
        is[v][nxt]=is[nxt][v]=0;
        v=nxt;
        if(v==s||v==-1)
            break;
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(is[i][j]){
                wi[i][j]=wi[j][i]=1e16;
            }
        }
    }
    di();
    if(dist[t]!=L){
        cout<<"NO"<<endl;
        return 0;
    }
    cout<<"YES"<<endl;
    for(int i=0;i<m;i++){
        int v=e[i].first,
            u=e[i].second;
        cout<<v<<" "<<u<<" "<<wi[v][u]<<endl;
    }

}


#include<bits/stdc++.h>
using namespace std;
#define int long long int
#define ii pair<int,int>
#define inf 1e15
#define infinity 1e10
#define N 1000000
vector<ii> e,adj[N];
int path[N],dist[N];
bool is[1010][1010];
int wi[1010][1010];
int n,m,L,s,t;
void di(){
    for(int i=0;i<=n;i++){
        dist[i]=inf;
    }
    set<ii> st;
    st.insert(ii(0,s));
    dist[s]=0;
    while(!st.empty())
    {
        int v=(*st.begin()).second,
            d=(*st.begin()).first;
        st.erase(st.begin());
        int sz=adj[v].size();
        for(int i=0;i<sz;i++){
            int nxt=adj[v][i].first;
            int cost=wi[v][nxt];
            if(cost+d<dist[nxt]){
                path[nxt]=v;
                if(dist[nxt]!=inf)
                    st.erase(st.find(ii(dist[nxt],nxt)));
                dist[nxt]=cost+d;
                st.insert(ii(dist[nxt],nxt));
            }
        }
    }
}
main(){
    memset(path,-1,sizeof(path));
    cin>>n>>m>>L>>s>>t;
    for(int i=0;i<m;i++){
        int u,v,w;
        cin>>u>>v>>w;
        if(w==0){
            is[u][v]=is[v][u]=1;
            w=1;
        }
        wi[u][v]=wi[v][u]=w;
        e.push_back(ii(u,v));
        adj[u].push_back(ii(v,w));
        adj[v].push_back(ii(u,w));
    }

    int v=t,total=0;
    di();
  //  cout<<dist[t]<<endl;
    if(dist[t]>L){
        cout<<"NO"<<endl;
        return 0;
    }
    total=dist[t];
    v=t;
    while(1){
        int nxt=path[v];
        if(is[v][nxt]){
            wi[v][nxt]=wi[nxt][v]=L-(total-1);
            total=L;
        }
        is[v][nxt]=is[nxt][v]=0;
        v=nxt;
        if(v==s)
            break;
    }
    for(int i=0;i<=n;i++){
        for(int j=0;j<=n;j++){
            if(is[i][j]){
                wi[i][j]=wi[j][i]=infinity;
            }
        }
    }
    di();
    if(dist[t]<L){
        cout<<"NO"<<endl;
        return 0;
    }
    cout<<"YES"<<endl;
    for(int i=0;i<m;i++){
        int v=e[i].first,
            u=e[i].second;
        cout<<v<<" "<<u<<" "<<wi[v][u]<<endl;
    }

}


#include<bits/stdc++.h>
using namespace std;
#define int long long int
#define ii pair<int,int>
#define N 1000000
vector<ii> e,adj[N];
int path[N],dist[N];
bool is[1010][1010];
int wi[1010][1010];
int n,m,L,s,t;
void di(){
    for(int i=0;i<n;i++){
        dist[i]=1e15;
    }
    set<ii> st;
    st.insert(ii(0,s));
    dist[s]=0;
    while(!st.empty())
    {
        int v=(*st.begin()).second,
            d=(*st.begin()).first;
        st.erase(st.begin());
        int sz=adj[v].size();
        for(int i=0;i<sz;i++){
            int nxt=adj[v][i].first,
                cost=wi[v][nxt];
            if(cost+d<dist[nxt]){
                path[nxt]=v;
                if(dist[nxt]!=1e14)
                    st.erase(st.find(ii(dist[nxt],nxt)));
                dist[nxt]=cost+d;
                st.insert(ii(dist[nxt],nxt));
            }
        }
    }
}
main(){
    memset(path,-1,sizeof(path));
    cin>>n>>m>>L>>s>>t;
    for(int i=0;i<m;i++){
        int u,v,w;
        cin>>u>>v>>w;
        if(w==0){
            is[u][v]=is[v][u]=1;
            w=1;
        }
        wi[u][v]=wi[v][u]=w;
        e.push_back(ii(u,v));
        adj[u].push_back(ii(v,w));
        adj[v].push_back(ii(u,w));
    }

    int v=t,total=0;
    di();
    while(1){
        int nxt=path[v];
        total+=wi[nxt][v];
        v=nxt;
        if(v==s||v==-1)
            break;
    }
 //   cout<<total<<endl;
    if(total>L||v==-1){
        cout<<"NO"<<endl;
        return 0;
    }
    v=t;
    while(1){
        int nxt=path[v];
        if(is[v][nxt]){
            wi[v][nxt]=wi[nxt][v]=L-(total-1);
        //    cout<<v<<" "<<nxt<<" "<<wi[v][nxt]<<endl;
            total=L;
        }
        is[v][nxt]=is[nxt][v]=0;
        v=nxt;
        if(v==s||v==-1)
            break;
    }
    if(total!=L){
        cout<<"NO"<<endl;
        return 0;
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(is[i][j]){
                wi[i][j]=wi[j][i]=1e14;
            }
        }
    }
    di();
    if(dist[t]!=L){
       // cout<<dist[t]<<endl;
       v=t;
     /*  while(v!=s){
            cout<<v<<" "<<path[v]<<" "<<wi[v][path[v]]<<endl;
            v=path[v];
       }*/
        cout<<"NO"<<endl;
        return 0;
    }
    cout<<"YES"<<endl;
    for(int i=0;i<m;i++){
        int v=e[i].first,
            u=e[i].second;
        cout<<v<<" "<<u<<" "<<wi[v][u]<<endl;
    }

}


#include <stdio.h>
#include <bits/stdc++.h>
typedef int integer;
#define int long long
#define rep(x, y, z) for(int (x) = (y); (x) < (z); (x)++)
#define fil(a,b) memset((a),(b),sizeof(a))
#define mod 1000000007
#define endl '\n'
#define mp make_pair
#define pb push_back
#define sz(x) (int) (x).size()
#define srt(x) sort((x).begin(), (x).end())
#define ii pair<int, int>
#define vi vector<int>
#define vii vector<ii>
#define vvi vector<vi>
#define fi first
#define se second
#define INF 1e12
#define EPS 1e-9
using namespace std;

priority_queue< ii, vii, greater<ii> > pq;
int n, m, s, t, L;
int parent[1000];
int adj[1000][1000];
int variable[1000][1000];
vi edges[1000];
vi dist;
vii output;

void dijkstra(){

	dist.clear();
	dist.resize(n, INF);
	dist[s] = 0;
	pq.push(mp(0, s));
	while (!pq.empty()){
		ii node = pq.top(); pq.pop();
		int u = node.se, cost = node.fi;
		if (cost != dist[u]) continue;
		for (int i = 0; i < sz(edges[u]); i++){
			int v = edges[u][i];
			int d = adj[u][v];
			if (!d) continue;

			if (cost + d < dist[v]){
				dist[v] = cost + d;
				parent[v] = u;
				pq.push(mp(dist[v], v));
			}
		}
	}
}

integer main() {
	ios_base::sync_with_stdio(false);
	cin >> n >> m >> L >> s >> t;
	memset(adj, -1, sizeof adj);
	memset(variable, -1, sizeof variable);
	for (int i = 0; i < m; i++){
		int a, b, c;
		cin >> a >> b >> c;
		adj[a][b] = adj[b][a] = c;
		if (!c)
			variable[a][b] = variable[b][a] = 1;
		edges[a].pb(b);
		edges[b].pb(a);
		output.pb(mp(a, b));
	}
	dijkstra();
	if (dist[t] < L){
		cout << "NO\n";
		return 0;
	}
	for (int i = 0; i < n; i++)
		for (int j = i+1; j < n; j++)
			if (adj[i][j] == 0)
				adj[i][j] = adj[j][i] = 1;
	dijkstra();

	if (dist[t] > L){
		cout << "NO\n";
		return 0;
	}
	while (dist[t] != L){
		int cur = t;
		while (cur != s){
			int p = parent[cur];
			if (variable[cur][p]){
				int diff = L - dist[t];
				adj[cur][p] = adj[p][cur] = diff + adj[cur][p];
				break;
			}
			cur = p;
		}
		dijkstra();
	}

	cout << "YES\n";
	for (int i = 0; i < m; i++){
		int u = output[i].fi, v = output[i].se;
		cout << u << ' ' << v << ' ' << adj[u][v] << endl;
	}
}