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.*;
import java.util.*;
public class div372D
{
	BufferedReader in;
	PrintWriter ob;
	StringTokenizer st;
	static int n,m,L, source , dest;
	static ArrayList<Integer> gr[];
	static long dist[],cost[][];
	static boolean visited[];
	static int res=0,u[],v[],w[];
	public static void main(String[] args) throws IOException {
		new div372D().run();
	}
	void run() throws IOException {
		in=new BufferedReader(new InputStreamReader(System.in));
		ob=new PrintWriter(System.out);
		solve();
		ob.flush();
	}
	@SuppressWarnings("unchecked")
	void solve() throws IOException {
		n=ni();
		m=ni();
		L=ni();
		cost=new long[n][n];
		source=ni();
		dest=ni();
		gr=new ArrayList[n];
		for (int i=0; i<n ; i++ )
			gr[i]=new ArrayList<Integer>();
		u=new int[m];
		v=new int[m];
		w=new int[m];
		for (int i=0; i<m ; i++ ) {
		 	u[i]=ni();
		 	v[i]=ni();
		 	w[i]=ni();
		 	gr[u[i]].add(v[i]);
		 	gr[v[i]].add(u[i]);
		 	cost[u[i]][v[i]]=w[i];
		 	cost[v[i]][u[i]]=w[i];
		 }
		 dist=new long[n];
		 visited=new boolean[n];
		 dijkstra(source,dest);
		 if(dist[dest]==Long.MAX_VALUE) {
		 	ob.println("NO");
		 }
		 else {
		 	if(res==0) {
		 		if(dist[dest]==L) {
		 			ob.println("YES");
		 			print(0);
		 		}
		 		else {
		 			ob.println("NO");
		 		}
		 	}
		 	else {
		 		long answer=(L-dist[dest])/res;
		 		if(answer>=0)
		 		{
		 			ob.println("YES");
		 			print(answer);
		 		}
		 		else
		 			ob.println("NO");
		 	}

		 }
	}
	void print(long n) {
		for (int i=0 ; i<m ; i++ ) {
			if(w[i]==0)
				ob.println(u[i]+" "+v[i]+" "+n);
			else
				ob.println(u[i]+" "+v[i]+" "+w[i]);
		}
	}
	void dijkstra(int source,int dest) {
		Arrays.fill(dist,Long.MAX_VALUE);
		Arrays.fill(visited,false);
		dist[0]=0;
		PriorityQueue<Nodez> pq=new PriorityQueue<Nodez>(new Comparator<Nodez>(){
			public int compare(Nodez x, Nodez y) {
				return Long.compare(x.p,y.p);
			} 
		});
		Nodez start=new Nodez();
		start.i=source;
		start.p=0;
		start.cnt=0;
		pq.offer(start);
		visited[source]=true;
		while(pq.isEmpty()==false) {
			Nodez temp=pq.poll();
			int ele=temp.i;
			long p=temp.p;
			int cnt=temp.cnt;
			if(ele==dest) {res=cnt;return;}
			visited[ele]=true;
			for (int u : gr[ele]) {
					if(!visited[u]) {
						if(cost[ele][u]+p<=dist[u]) {
							dist[u]=cost[ele][u]+p;
							Nodez temp2=new Nodez();
							temp2.i=u;
							temp2.p=dist[u];
							if(cost[ele][u]==0)++cnt;
							temp2.cnt=cnt;
							pq.offer(temp2);
						}
					}
			}
		}
	}
	int ni() throws IOException {
		return Integer.parseInt(nextToken());
	}
	String nextToken() throws IOException {
		if(st==null || !st.hasMoreTokens())
			st=new StringTokenizer(in.readLine());
		return st.nextToken();
	}
}
class Nodez {
	int i;
	long p;
	int cnt=0;
}