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

#include<cstdio>
#include<queue>
#include<utility>
#include<cstring>
#include<algorithm>
#define MAXM 50100
#define MAXN 1100

using namespace std;

int n,m,L,s,t,num,tot;
int g[MAXN],next[MAXM],cost[MAXM],y[MAXM];
int dis[MAXN],f[MAXN];
bool vis[MAXN];

struct rec{
	int u,v,z;
}edge[MAXM];

void Insert(int u,int v,int z){
	y[++tot]=v;
	next[tot]=g[u];
	g[u]=tot;
	cost[tot]=z;
}

int Scan(){
	int u,v,z;
	scanf("%d%d%d%d%d",&n,&m,&L,&s,&t);
	tot=1;
	for (int i=1;i<=m;i++){
		scanf("%d%d%d",&u,&v,&z);
		edge[++num].u=u;edge[num].v=v;edge[num].z=z;
		Insert(u,v,z); Insert(v,u,z);
	}
}

struct cmp{
	bool operator ()(pair<int,int> a,pair<int,int> b){
		return a.second>b.second;
	}
};

void Dijkstra(int st,int*d,int*anti,bool flag){
	priority_queue<pair<int,int>,vector<pair<int,int> >,cmp> q;
	memset(vis,0,sizeof(vis));
	d[st]=0;
	q.push(make_pair<int,int>(st,d[st]));
	while (!q.empty()){
		pair<int,int>sa=q.top(); q.pop();
		int now=sa.first;
		int used=sa.second;
		if (vis[now]) continue;
		vis[now]=true;
		for (int e=g[now];e!=0;e=next[e]){
			int son=y[e];
			if (cost[e]==0&&flag==0) continue;
			if (cost[e]==0&&flag==1) {
				cost[e]=cost[e^1]=max(1,L-used-anti[son]);
				edge[e/2].z=edge[(e^1)/2].z=cost[e];
			}
			if (d[son]>used+cost[e]) {
				d[son]=used+cost[e];
				q.push(make_pair<int,int>(son,d[son]));
			}
		}
	}
}

void Work(){
	memset(dis,60,sizeof(dis));
	memset(f,60,sizeof(f));
	Dijkstra(t,f,dis,false);
	Dijkstra(s,dis,f,true);
}

void Print(){
	if (dis[t]==L){
		printf("YES\n");
		for (int i=1;i<=m;i++) printf("%d %d %d\n",edge[i].u,edge[i].v,edge[i].z);
	} else printf("NO\n");
}

int main(){
	Scan();
	Work();
	Print();
}

