7 9 999999999 0 3
0 1 0
1 2 0
2 3 0
0 4 1
4 1 1
1 5 499999999
5 2 499999999
2 6 1
6 3 1
 7 9 320 0 3
0 1 0
1 2 0
2 3 0
0 4 1
4 1 1
1 5 100
5 2 100
2 6 59
6 3 61
 4 5 7 0 3
0 1 0
1 2 3
2 3 0
0 2 5
1 3 5
 8 9 10 1 0
1 2 1
2 4 1
1 3 0
3 4 0
4 5 0
5 6 1
6 0 1
5 7 0
7 0 0
 4 4 14 1 3
1 3 13
2 3 0
2 0 0
1 0 12
 5 6 1000000000 0 4
0 1 1
2 0 2
3 0 3
4 1 0
4 2 0
3 4 0
 4 5 10 1 2
0 1 3
1 2 0
1 3 4
2 3 4
2 0 6
 4 4 2 1 3
1 3 13
2 3 0
2 0 0
1 0 0
 5 5 2 0 2
0 1 1
1 2 1
0 4 0
4 3 0
3 2 0
 5 5 3 0 2
0 1 1
1 2 1
0 4 0
4 3 0
3 2 0
 4 4 8 1 3
1 3 13
2 3 0
2 0 0
1 0 6
 1000 1 1000000000 998 0
0 999 0
 5 5 1 0 2
0 1 1
1 2 1
0 4 0
4 3 0
3 2 0
 100 1 123456 99 0
0 99 123456
 4 4 13 1 3
1 3 13
2 3 0
2 0 0
1 0 12
 7 9 319 0 3
0 1 0
1 2 0
2 3 0
0 4 1
4 1 1
1 5 100
5 2 100
2 6 59
6 3 61
 1000 1 5 999 0
0 999 0

YES
0 1 1
1 2 999999996
2 3 999999997
0 4 1
4 1 1
1 5 499999999
5 2 499999999
2 6 1
6 3 1
 YES
0 1 1
1 2 199
2 3 318
0 4 1
4 1 1
1 5 100
5 2 100
2 6 59
6 3 61
 YES
0 1 3
1 2 3
2 3 2
0 2 5
1 3 5
 YES
1 2 1
2 4 1
1 3 1
3 4 1
4 5 6
5 6 1
6 0 1
5 7 1
7 0 1
 NO YES
0 1 1
2 0 2
3 0 3
4 1 999999999
4 2 999999998
3 4 999999997
 NO NO YES
0 1 1
1 2 1
0 4 1
4 3 1
3 2 1
 NO YES
1 3 13
2 3 1
2 0 1
1 0 6
 NO NO YES
0 99 123456
 YES
1 3 13
2 3 1
2 0 1
1 0 12
 YES
0 1 1
1 2 198
2 3 317
0 4 1
4 1 1
1 5 100
5 2 100
2 6 59
6 3 61
 YES
0 999 5

/* CRAP!!! I AM A WEB-DESIGNER!!! */

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.util.TreeSet;

/**
 * Created by Anna on 24.09.2016.
 */
public class TaskD {
    StringTokenizer st;
    BufferedReader in;
    PrintWriter out;

    public static void main(String[] args) throws IOException {
        TaskD task = new TaskD();
        task.open();
        task.solve();
        task.close();
    }

    class Edge {
        int ind;
        int a, b;
        long weight;
        boolean variable;

        public Edge(int ind, int a, int b, long weight, boolean variable) {
            this.ind = ind;
            this.a = a;
            this.b = b;
            this.weight = weight;
            this.variable = variable;
        }

        public int getOther(int v) {
            if (a == v) return b;
            else return a;
        }

    }

    ArrayList<Edge> edges;
    ArrayList<Edge>[] graph;
    int n;
    int m;
    int L;
    int start;
    int finish;

    long INFINITY;

    class DeikVertex implements Comparable<DeikVertex> {
        int ind;
        long mark;

        @Override
        public int compareTo(DeikVertex o) {
            if (this.mark != o.mark) return Long.compare(this.mark, o.mark);
            return Integer.compare(this.ind, o.ind);
        }

        public DeikVertex(int ind, long mark) {
            this.ind = ind;
            this.mark = mark;
        }
    }

    boolean[] cannotDeik;
    DeikVertex[] marks;

    private long deikstra() {
        boolean[] used = new boolean[n];
        Arrays.fill(used, false);
        used[start] = true;

        TreeSet<DeikVertex> mins = new TreeSet<>();
        marks = new DeikVertex[n];
        for (int i = 0; i < n; i++) {
            if (i == start) continue;
            marks[i] = new DeikVertex(i, INFINITY);
            mins.add(marks[i]);
        }
        marks[start] = new DeikVertex(start, 0);
        mins.add(marks[start]);

        while (marks[finish].mark == INFINITY) {
            DeikVertex minEdge = mins.pollFirst();
            int minInd = minEdge.ind;
            long minMark = minEdge.mark;
            if (minMark == INFINITY) break;
            for (Edge edge : graph[minInd]) {
                if (cannotDeik[edge.ind]) continue;
                int other = edge.getOther(minInd);
                if (used[other]) continue;

                if (minMark + edge.weight < marks[other].mark) {
                    mins.remove(marks[other]);
                    marks[other].mark = minMark + edge.weight;
                    mins.add(marks[other]);
                }
            }
        }
        return marks[finish].mark;
    }

    boolean[] usedCheck;

    Edge checkVariableInShortestPath(int v, long cur) {
        usedCheck[v] = true;
        for (Edge edge : graph[v]) {
            int otherV = edge.getOther(v);
            if (usedCheck[otherV]) continue;
            if (marks[otherV].mark + cur + edge.weight == marks[finish].mark) {
                if (edge.variable) return edge;
                else return checkVariableInShortestPath(otherV, cur + edge.weight);
            }
        }
        return null;
    }

    private void solve() throws IOException {
        n = nextInt();
        m = nextInt();
        L = nextInt();
        start = nextInt();
        finish = nextInt();

        INFINITY = L + 1;

        edges = new ArrayList<>();
        graph = new ArrayList[n];
        cannotDeik = new boolean[m];
        usedCheck = new boolean[n];

        for (int i = 0; i < n; i++) {
            graph[i] = new ArrayList<>();
        }

        for (int i = 0; i < m; i++) {
            int a = nextInt();
            int b = nextInt();
            int w = nextInt();
            final boolean variable = w == 0;
            Edge edge = new Edge(i, a, b, w, variable);
            cannotDeik[i] = variable;
            graph[a].add(edge);
            graph[b].add(edge);
            edges.add(edge);
        }

        long shortestSure = deikstra();

        if (shortestSure < L) {
            out.println("NO");
            return;
        }

        Arrays.fill(cannotDeik, false);

        for (Edge edge : edges) {
            if (edge.variable) {
                edge.weight = 1;
            }
        }

        long curShortest = deikstra();

        if (curShortest > L) {
            out.println("NO");
            return;
        }

        while (curShortest != L) {
            curShortest = deikstra();
            Arrays.fill(usedCheck, false);
            Edge nextVar = checkVariableInShortestPath(finish, 0);
            if (nextVar == null) break;
            nextVar.variable = false;
            nextVar.weight += L - curShortest;
        }

        out.println("YES");
        for (Edge edge : edges) {
            out.println(edge.a + " " + edge.b + " " + edge.weight);
        }
    }

    private void close() {
        out.flush();
        out.close();
    }

    private void open() {
        in = new BufferedReader(new InputStreamReader(System.in));
        out = new PrintWriter(System.out);
    }

    private int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    private String nextToken() throws IOException {
        while (st == null || !st.hasMoreTokens()) {
            String str = in.readLine();
            if (str == null) return null;
            st = new StringTokenizer(str);
        }
        return st.nextToken();
    }


    private double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

    private double nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

}
