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

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Set;
import java.io.IOException;
import java.util.HashMap;
import java.io.InputStreamReader;
import java.util.stream.Collectors;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Objects;
import java.util.stream.Stream;
import java.util.StringTokenizer;
import java.util.Map;
import java.io.BufferedReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        MyBufferedReader in = new MyBufferedReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        private int n;
        private int m;
        private int L;
        private int s;
        private int t;
        private GraphUtils.GraphNode[] nodes;
        Map<GraphUtils.GraphNode, GraphUtils.GraphNode> parents = new HashMap<>();
        Map<GraphUtils.GraphNode, GraphUtils.Edge> parentEdges = new HashMap<>();
        Map<GraphUtils.Edge, GraphUtils.Edge> reversed = new HashMap<>();
        Map<GraphUtils.GraphNode, Long> distances;

        public void solve(int testNumber, MyBufferedReader in, PrintWriter out) {
            int[] data = in.getALineOfInts(5);
            n = data[0];
            m = data[1];
            L = data[2];
            s = data[3];
            t = data[4];

            nodes = new GraphUtils.GraphNode[n];
            for (int i = 0; i < n; i++) {
                nodes[i] = new GraphUtils.GraphNode(new GraphUtils.IdState(i));
            }

            for (int i = 0; i < m; i++) {
                data = in.getALineOfInts(3);
                GraphUtils.GraphNode g1 = nodes[data[0]];
                GraphUtils.GraphNode g2 = nodes[data[1]];
                GraphUtils.WeightedEdge original = new GraphUtils.WeightedEdge(g1, g2, Math.max
                        (data[2], 1), data[2] == 0,
                                                                               true);
                g1.transitions.add(original);
                GraphUtils.WeightedEdge otherway = new GraphUtils.WeightedEdge(g2, g1, Math.max
                        (data[2], 1), data[2] == 0,
                                                                               false);
                g2.transitions.add(otherway);
                reversed.put(original, otherway);
                reversed.put(otherway, original);

            }

            distances = GraphUtils.djikstra(nodes[s], parentEdges, parents);

            if (!distances.containsKey(nodes[t]) || distances.get(nodes[t]) > L) {
                out.println("NO");
                return;
            }

            if (canUpdate(nodes[t], L, new HashSet<>())) {
                printGraph(out);
            } else {
                out.println("NO");
            }

        }

        private boolean canUpdate(GraphUtils.GraphNode node, long pathGoal, Set<GraphUtils
                .GraphNode> visited) {
            if (node == nodes[s]) {
                return false;
            }

            visited.add(node);

            for (GraphUtils.Edge transition : node.transitions) {
                GraphUtils.WeightedEdge edge = (GraphUtils.WeightedEdge) transition;
                if (visited.contains(edge.neighbour)) {
                    continue;
                } else {
                    long shortestToNeighbour = distances.get(transition.neighbour);
                    if (shortestToNeighbour + edge.weight < pathGoal) {
                        if (edge.was0) {
                            //TODO overflow?
                            edge.weight = 1 + Math.max(edge.weight - 1, pathGoal -
                                    (shortestToNeighbour + edge.weight));
                            ((GraphUtils.WeightedEdge) (reversed.get(edge))).weight = edge.weight;
                        } else {
                            if (!canUpdate(edge.neighbour, pathGoal - edge.weight, visited)) {
                                visited.remove(node);
                                return false;
                            }
                        }
                    }
                }
            }

            visited.remove(node);
            return true;
        }

        private void printGraph(PrintWriter out) {
            out.println("YES");
            for (GraphUtils.GraphNode node : nodes) {
                for (GraphUtils.Edge transition : node.transitions) {
                    GraphUtils.WeightedEdge transition1 = (GraphUtils.WeightedEdge) transition;
                    if (transition1.wasInOriginal) {
                        out.println(((GraphUtils.IdState) node.s).id + " " + ((GraphUtils
                                .IdState) transition1.neighbour.s)
                                .id + " " + transition1.weight);
                    }
                }
            }
        }

    }

    static class Pairs {
        public static class Pair<T1, T2> {
            public T1 t1;
            public T2 t2;

            public Pair(T1 t1, T2 t2) {
                this.t1 = t1;
                this.t2 = t2;
            }


            public int hashCode() {
                return Objects.hash(t1, t2);
            }


            public boolean equals(Object o) {
                return o instanceof Pairs.Pair && t1.equals(((Pairs.Pair) o).t1) && t2.equals((
                        (Pairs.Pair) o).t2);
            }


            public String toString() {
                return "(" + t1.toString() + ", " + t2.toString() + ")";
            }

        }

        public static class ComparablePair<T1, T2 extends Comparable> extends Pairs.Pair<T1, T2>
                implements Comparable {
            ComparablePair(T1 t1, T2 t2) {
                super(t1, t2);
            }


            public int compareTo(Object o) {
                return t2.compareTo(((Pairs.ComparablePair) o).t2);
            }

        }

    }

    static class GraphUtils {
        public static Map<GraphUtils.GraphNode, Long> djikstra(GraphUtils.GraphNode start,
                                                               Map<GraphUtils.GraphNode,
                GraphUtils.Edge> parentTransitions, Map<GraphUtils.GraphNode, GraphUtils
                .GraphNode> parents) {
            Map<GraphUtils.GraphNode, Long> res = new HashMap<>();
            Heap<Pairs.ComparablePair<GraphUtils.GraphNode, Long>> closestNodesQueue = new Heap<>
                    (true);
            Pairs.ComparablePair<GraphUtils.GraphNode, Long> startNodeDistPair = new Pairs
                    .ComparablePair<>(start, 0L);
            closestNodesQueue.add(startNodeDistPair);
            Map<GraphUtils.GraphNode, Pairs.ComparablePair<GraphUtils.GraphNode, Long>>
                    inQueuePairs = new HashMap<>();
            inQueuePairs.put(start, startNodeDistPair);
            Set<GraphUtils.GraphNode> removed = new HashSet<>();

            while (!closestNodesQueue.isEmpty()) {
                Pairs.Pair<GraphUtils.GraphNode, Long> nextClosest = closestNodesQueue.remove();
                res.put(nextClosest.t1, nextClosest.t2);
                removed.add(nextClosest.t1);
                inQueuePairs.remove(nextClosest.t1);

                long nextClosestDistance = nextClosest.t2;
                for (GraphUtils.Edge transition : nextClosest.t1.transitions) {
                    GraphUtils.GraphNode neighbour = transition.neighbour;
                    if (removed.contains(neighbour))
                        continue;

                    long transitionCost = ((GraphUtils.WeightedEdge) transition).weight;
                    if (inQueuePairs.containsKey(neighbour)) {
                        Pairs.ComparablePair<GraphUtils.GraphNode, Long> neighbourPairInQueue =
                                inQueuePairs
                                .get(neighbour);
                        long currDistanceToNeighbour = neighbourPairInQueue.t2;
                        if (nextClosestDistance + transitionCost < currDistanceToNeighbour) {
                            parentTransitions.put(neighbour, transition);
                            parents.put(neighbour, nextClosest.t1);
                            neighbourPairInQueue.t2 = nextClosestDistance + transitionCost;
                            closestNodesQueue.update(neighbourPairInQueue);
                        }
                    } else {
                        Pairs.ComparablePair<GraphUtils.GraphNode, Long> newNeighbourPairInQueue
                                = new Pairs.ComparablePair<>(neighbour, nextClosestDistance +
                                transitionCost);
                        parentTransitions.put(neighbour, transition);
                        parents.put(neighbour, nextClosest.t1);
                        closestNodesQueue.add(newNeighbourPairInQueue);
                        inQueuePairs.put(neighbour, newNeighbourPairInQueue);
                    }
                }
            }

            return res;
        }

        public static class Edge {
            public GraphUtils.GraphNode neighbour;
            private boolean isParentEdge;

            public Edge(GraphUtils.GraphNode neighbour) {
                this.neighbour = neighbour;
                this.isParentEdge = false;
            }

            public Edge(GraphUtils.GraphNode neighbour, boolean isParentEdge) {
                this.neighbour = neighbour;
                this.isParentEdge = isParentEdge;
            }


            public boolean equals(Object o) {
                return o instanceof GraphUtils.Edge && ((GraphUtils.Edge) o).neighbour.equals
                        (neighbour) && isParentEdge ==
                        ((GraphUtils.Edge) o).isParentEdge;
            }


            public int hashCode() {
                return neighbour.hashCode() + (isParentEdge ? 1 : 0);
            }

        }

        public static class WeightedEdge extends GraphUtils.Edge {
            public long weight;
            public boolean was0;
            public boolean wasInOriginal;
            public GraphUtils.GraphNode source;

            public WeightedEdge(GraphUtils.GraphNode neighbour, int weight) {
                super(neighbour);
                this.weight = weight;
            }

            public WeightedEdge(GraphUtils.GraphNode source, GraphUtils.GraphNode neighbour, int
                    weight, boolean was0, boolean wasInOriginal) {
                super(neighbour);
                this.source = source;
                this.weight = weight;
                this.was0 = was0;
                this.wasInOriginal = wasInOriginal;
            }


            public boolean equals(Object o) {
                if (this == o) return true;
                if (o == null || getClass() != o.getClass()) return false;
                if (!super.equals(o)) return false;

                GraphUtils.WeightedEdge that = (GraphUtils.WeightedEdge) o;

                return source.equals(that.source);
            }


            public int hashCode() {
                int result = super.hashCode();
                result = 31 * result + source.hashCode();
                return result;
            }

        }

        public static class GraphNode {
            public GraphUtils.State s;
            public Set<GraphUtils.Edge> transitions;

            public GraphNode(GraphUtils.State s) {
                this.s = s;
                transitions = new HashSet<GraphUtils.Edge>();
            }

            public String toString() {
                return "(" + s.toString() + " : " + transitions.stream().map(t -> t.neighbour.s
                        .toString()).collect(Collectors.joining(", ")) + ")";
            }

        }

        public interface State {
        }

        public static class IdState implements GraphUtils.State {
            public int id;

            public IdState(int i) {
                id = i;
            }

            public String toString() {
                return Integer.toString(id);
            }

        }

    }

    static class MyBufferedReader {
        BufferedReader in;

        public MyBufferedReader(InputStream s) {
            this.in = new BufferedReader(new InputStreamReader(s));
        }

        public int[] getALineOfInts(int numExpected) {
            int[] res = new int[numExpected];
            StringTokenizer st = null;
            try {
                st = new StringTokenizer(in.readLine());
            } catch (IOException e) {
                e.printStackTrace();
            }
            for (int i = 0; i < numExpected; i++)
                res[i] = Integer.parseInt(st.nextToken());
            return res;
        }

    }

    static class Heap<E extends Comparable> {
        ArrayList<E> heap;
        Map<E, Integer> pos;
        int comparisonSign;

        Heap(boolean min) {
            heap = new ArrayList<E>();
            pos = new HashMap<E, Integer>();
            if (min) {
                comparisonSign = 1;
            } else {
                comparisonSign = -1;
            }
        }

        Heap(ArrayList<E> unorderedList) {
            this.heap = unorderedList;
            pos = new HashMap<E, Integer>();
            heapify();
        }

        void add(E e) {
            heap.add(e);
            pos.put(e, heap.size() - 1);
            bubbleUp(heap.size() - 1);
        }

        E remove() {
            if (heap.size() == 0)
                return null;

            E result = heap.get(0);
            swap(0, heap.size() - 1);
            heap.remove(heap.size() - 1);
            pos.remove(result);
            heapify(0);
            return result;
        }

        void update(E e) {
            if (!pos.containsKey(e))
                return;

            int epos = pos.get(e);
            if (epos == 0 || comparisonSign * e.compareTo(heap.get(parent(epos))) >= 0)
                heapify(epos);
            else
                bubbleUp(epos);
        }

        void bubbleUp(int child) {
            if (child == 0)
                return;

            int parent = parent(child);
            if (comparisonSign * heap.get(child).compareTo(heap.get(parent)) < 0) {
                swap(parent, child);
                bubbleUp(parent);
            }
        }

        void heapify() {
            if (heap.size() <= 1)
                return;

            for (int i = parent(heap.size() - 1); i >= 0; i--) {
                heapify(i);
            }
        }

        void heapify(int root) {
            if (root >= heap.size())
                return;

            int extremeChild = left(root);
            if (right(root) < heap.size() && comparisonSign * heap.get(right(root)).compareTo(heap.get(left(root))) < 0)
                extremeChild = right(root);

            if (extremeChild < heap.size() && comparisonSign * heap.get(extremeChild).compareTo(heap.get(root)) < 0) {
                swap(root, extremeChild);
                heapify(extremeChild);
            }
        }

        void swap(int idx1, int idx2) {
            pos.put(heap.get(idx1), idx2);
            pos.put(heap.get(idx2), idx1);

            E temp = heap.get(idx1);
            heap.set(idx1, heap.get(idx2));
            heap.set(idx2, temp);
        }

        int parent(int i) {
            return (i - 1) / 2;
        }

        int left(int i) {
            return 2 * i + 1;
        }

        int right(int i) {
            return 2 * i + 2;
        }

        boolean isEmpty() {
            return heap.size() == 0;
        }

    }
}

