#include <bits/stdc++.h>

using namespace std;

#define all(x) x.begin(), x.end()
#define endl '\n'
#define IO ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
typedef long long ll;

/*
 * 3yza path been s and t ykon feh edges fadya
 * hashof el awl lw el shortest path 3moman mafehosh edges fdya w el value bta3to < L then no valid answer (assign empty edges b INF)
 * lw el shortest path == L ha assign el empty edges b INF w 5alas kda
 * now 3shan ageeb my own shortest path ha assign kol el empty edges b one w ageeb shortest path
 * lw tl3 > L then no valid answer
 * lw == L then zy mana
 * lw as3'ar mn L hazawd one of the edges ely kant empty w fel shortest path l3'ayt maywsal L
 * w ba2y el edges ely bara el shortest path w kano empty ha5alehom b INF
 * 1. build graph 3ady gdan
 * 2. arr for values of each edge 3shan ha3'ayaro kaza mara
 * 3. first assign each empty edge b INF (7aga msh hat overflow)
 * 4. run dijkstra lw el result < L return false, lw == L return answer
 * 5. ha assign all empty edges b 1 w a run dijkstra keeping track of the parent of each node 3shan ageeb el empty edges
 * 6. lw > L return false, lw == L return answer
 * 7. lw as3'ar ha5aly all empty edges bara el shortest path b INF w azawd wa7d mn el shortest path L - current
 */

const int INF = 1e9 + 10;
const int N = 1005;
int n, m;
int L, g[N][N];
bool emp[N][N];
vector<vector<int>>grph(N);
vector<pair<int, int>>edg;
pair<vector<int>, vector<int>> dij(int s){
	vector<int>d(N, 2e9);
	vector<bool>vis(N, 0);
	vector<int>par(N, -1);
	d[s] = 0;
	priority_queue<pair<int, int>>q;
	q.emplace(0, s);
	while(q.size()){
		int cst = -q.top().first;
		int nd = q.top().second;
		q.pop();
		if(vis[nd])continue;
		vis[nd] = 1;
		for(auto ch: grph[nd]){
			if(vis[ch])continue;
			if(cst + g[nd][ch] < d[ch] && cst + g[nd][ch] <= L){
				d[ch] = cst + g[nd][ch];
				par[ch] = nd;
				q.emplace(-d[ch], ch);
			}
		}
	}

	return {d, par};
}

void invalid(){
	cout << "NO";
	exit(0);
}
void valid(){
	cout << "YES" << endl;
	for(int i = 0; i < n; i++)
		for(int j = i + 1; j < n; j++)
			if(g[i][j] != -1)
				cout << i << " " << j << " " << g[i][j] << endl;
	exit(0);
}

int main(){
	IO;

	int s, t;
	memset(g, -1, sizeof g);
	cin >> n >> m >> L >> s >> t;

	vector<pair<int, int>>ers;
	for(int i = 0; i < m; i++){
		int u, v, c;
		cin >> u >> v >> c;
		g[u][v] = g[v][u] = c;
		grph[u].emplace_back(v);
		grph[v].emplace_back(u);
		if(c == 0)
			emp[u][v] = emp[v][u] = 1, ers.emplace_back(u, v);
	}
	for(auto x: ers){
		int i = x.first, j = x.second;
		g[i][j] = g[j][i] = INF;
	}

	int cur = dij(s).first[t];
	if(cur < L)
		invalid();
	if(cur == L)
		valid();

	for(auto x: ers){
		int i = x.first, j = x.second;
		g[i][j] = g[j][i] = 1;
	}

	for(int k = 0; k < ers.size(); k++){
		int u = ers[k].first, v = ers[k].second;
		g[u][v] = g[v][u] = INF;
		pair<vector<int>, vector<int>> tmp = dij(s);
		pair<vector<int>, vector<int>> tmp2 = dij(t);
		int d1 = tmp.first[u], d2 = tmp2.first[v];
		if(d1 + d2 < L){
			for(auto e: ers){
				int i = e.first, j = e.second;
				g[i][j] = g[j][i] = INF;
			}
			int cur = u;
			while(tmp.second[cur] != -1){
				if(emp[cur][tmp.second[cur]])
					g[cur][tmp.second[cur]] = g[tmp.second[cur]][cur] = 1;
				cur = tmp.second[cur];
			}
			cur = v;
			while(tmp2.second[cur] != -1){
				if(emp[cur][tmp2.second[cur]])
					g[cur][tmp2.second[cur]] = g[tmp2.second[cur]][cur] = 1;
				cur = tmp2.second[cur];
			}
			g[u][v] = g[v][u] = L - d1 - d2;
			tmp = dij(s);
			if(tmp.first[t] == L)
				valid();
		}
		d1 = tmp.first[v], d2 = tmp2.first[u];
		if(d1 + d2 < L){
			for(auto e: ers){
				int i = e.first, j = e.second;
				g[i][j] = g[j][i] = INF;
			}
			int cur = u;
			while(tmp.second[cur] != -1){
				if(emp[cur][tmp.second[cur]])
					g[cur][tmp.second[cur]] = g[tmp.second[cur]][cur] = 1;
				cur = tmp.second[cur];
			}
			cur = v;
			while(tmp2.second[cur] != -1){
				if(emp[cur][tmp2.second[cur]])
					g[cur][tmp2.second[cur]] = g[tmp2.second[cur]][cur] = 1;
				cur = tmp2.second[cur];
			}
			g[u][v] = g[v][u] = L - d1 - d2;
			tmp = dij(s);
			if(tmp.first[t] == L)
				valid();
		}
	}
	invalid();
}


#include <bits/stdc++.h>

using namespace std;

#define all(x) x.begin(), x.end()
#define endl '\n'
#define IO ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
typedef long long ll;

/*
 * 3yza path been s and t ykon feh edges fadya
 * hashof el awl lw el shortest path 3moman mafehosh edges fdya w el value bta3to < L then no valid answer (assign empty edges b INF)
 * lw el shortest path == L ha assign el empty edges b INF w 5alas kda
 * now 3shan ageeb my own shortest path ha assign kol el empty edges b one w ageeb shortest path
 * lw tl3 > L then no valid answer
 * lw == L then zy mana
 * lw as3'ar mn L hazawd one of the edges ely kant empty w fel shortest path l3'ayt maywsal L
 * w ba2y el edges ely bara el shortest path w kano empty ha5alehom b INF
 * 1. build graph 3ady gdan
 * 2. arr for values of each edge 3shan ha3'ayaro kaza mara
 * 3. first assign each empty edge b INF (7aga msh hat overflow)
 * 4. run dijkstra lw el result < L return false, lw == L return answer
 * 5. ha assign all empty edges b 1 w a run dijkstra keeping track of the parent of each node 3shan ageeb el empty edges
 * 6. lw > L return false, lw == L return answer
 * 7. lw as3'ar ha5aly all empty edges bara el shortest path b INF w azawd wa7d mn el shortest path L - current
 */

const int INF = 1e9 + 10;
const int N = 1005;
int n, m;
int L, g[N][N];
bool emp[N][N];
vector<vector<int>>grph(N);
vector<pair<int, int>>edg;
pair<vector<int>, vector<int>> dij(int s){
	vector<int>d(N, 2e9);
	vector<bool>vis(N, 0);
	vector<int>par(N, -1);
	d[s] = 0;
	priority_queue<pair<int, int>>q;
	q.emplace(0, s);
	while(q.size()){
		int cst = -q.top().first;
		int nd = q.top().second;
		q.pop();
		if(vis[nd])continue;
		vis[nd] = 1;
		for(auto ch: grph[nd]){
			if(vis[ch])continue;
			if(cst + g[nd][ch] < d[ch] && cst + g[nd][ch] <= L){
				d[ch] = cst + g[nd][ch];
				par[ch] = nd;
				q.emplace(-d[ch], ch);
			}
		}
	}

	return {d, par};
}

void invalid(){
	cout << "NO";
	exit(0);
}
void valid(){
	cout << "YES" << endl;
	for(int i = 0; i < n; i++)
		for(int j = i + 1; j < n; j++)
			if(g[i][j] != -1)
				cout << i << " " << j << " " << g[i][j] << endl;
	exit(0);
}

int main(){
	IO;

	int s, t;
	memset(g, -1, sizeof g);
	cin >> n >> m >> L >> s >> t;

	vector<pair<int, int>>ers;
	for(int i = 0; i < m; i++){
		int u, v, c;
		cin >> u >> v >> c;
		g[u][v] = g[v][u] = c;
		grph[u].emplace_back(v);
		grph[v].emplace_back(u);
		if(c == 0)
			emp[u][v] = emp[v][u] = 1, ers.emplace_back(u, v);
	}
	for(auto x: ers){
		int i = x.first, j = x.second;
		g[i][j] = g[j][i] = INF;
	}

	int cur = dij(s).first[t];
	if(cur < L)
		invalid();
	if(cur == L)
		valid();

	for(auto x: ers){
		int i = x.first, j = x.second;
		g[i][j] = g[j][i] = 1;
	}

	for(int k = 0; k < ers.size(); k++){
		int u = ers[k].first, v = ers[k].second;
		g[u][v] = g[v][u] = INF;
		pair<vector<int>, vector<int>> tmp = dij(s);
		pair<vector<int>, vector<int>> tmp2 = dij(t);
		int d1 = tmp.first[u], d2 = tmp2.first[v];
		if(d1 *1ll + d2 < L *1ll){
			for(auto e: ers){
				int i = e.first, j = e.second;
				g[i][j] = g[j][i] = INF;
			}
			int cur = u;
			while(tmp.second[cur] != -1){
				if(emp[cur][tmp.second[cur]])
					g[cur][tmp.second[cur]] = g[tmp.second[cur]][cur] = 1;
				cur = tmp.second[cur];
			}
			cur = v;
			while(tmp2.second[cur] != -1){
				if(emp[cur][tmp2.second[cur]])
					g[cur][tmp2.second[cur]] = g[tmp2.second[cur]][cur] = 1;
				cur = tmp2.second[cur];
			}
			g[u][v] = g[v][u] = L - d1 - d2;
			tmp = dij(s);
			if(tmp.first[t] == L)
				valid();
		}
		d1 = tmp.first[v], d2 = tmp2.first[u];
		if(d1 *1ll + d2 < L *1ll){
			for(auto e: ers){
				int i = e.first, j = e.second;
				g[i][j] = g[j][i] = INF;
			}
			int cur = u;
			while(tmp.second[cur] != -1){
				if(emp[cur][tmp.second[cur]])
					g[cur][tmp.second[cur]] = g[tmp.second[cur]][cur] = 1;
				cur = tmp.second[cur];
			}
			cur = v;
			while(tmp2.second[cur] != -1){
				if(emp[cur][tmp2.second[cur]])
					g[cur][tmp2.second[cur]] = g[tmp2.second[cur]][cur] = 1;
				cur = tmp2.second[cur];
			}
			g[u][v] = g[v][u] = L - d1 - d2;
			tmp = dij(s);
			if(tmp.first[t] == L)
				valid();
		}
	}
	invalid();
}


#include <bits/stdc++.h>

using namespace std;

#define all(x) x.begin(), x.end()
#define endl '\n'
#define IO ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
typedef long long ll;

/*
 * 3yza path been s and t ykon feh edges fadya
 * hashof el awl lw el shortest path 3moman mafehosh edges fdya w el value bta3to < L then no valid answer (assign empty edges b INF)
 * lw el shortest path == L ha assign el empty edges b INF w 5alas kda
 * now 3shan ageeb my own shortest path ha assign kol el empty edges b one w ageeb shortest path
 * lw tl3 > L then no valid answer
 * lw == L then zy mana
 * lw as3'ar mn L hazawd one of the edges ely kant empty w fel shortest path l3'ayt maywsal L
 * w ba2y el edges ely bara el shortest path w kano empty ha5alehom b INF
 * 1. build graph 3ady gdan
 * 2. arr for values of each edge 3shan ha3'ayaro kaza mara
 * 3. first assign each empty edge b INF (7aga msh hat overflow)
 * 4. run dijkstra lw el result < L return false, lw == L return answer
 * 5. ha assign all empty edges b 1 w a run dijkstra keeping track of the parent of each node 3shan ageeb el empty edges
 * 6. lw > L return false, lw == L return answer
 * 7. lw as3'ar ha5aly all empty edges bara el shortest path b INF w azawd wa7d mn el shortest path L - current
 */
const ll INF = 1e10;
const int N = 1005;
int n, m, L, s, t;
ll g[N][N];
bool emp[N][N];
vector<pair<int, int>>edg;
ll dij(){
	vector<bool>vis(N);
	vector<ll>dis(N, 1e18);
	vector<int>par(N, -1);
	priority_queue<pair<ll, int>> q;
	q.emplace(0, s);
	while(q.size()){
		ll cst = -q.top().first;
		int nd = q.top().second;
		q.pop();
		if(vis[nd])continue;
		vis[nd] = 1;
		for(int i = 0; i < n; i++){
			if(g[nd][i] == -1 || vis[i])continue;
			if(cst + g[nd][i] < dis[i]){
				dis[i] = cst + g[nd][i];
				par[i] = nd;
				q.emplace(-dis[i], i);
			}
		}
	}
	edg.clear();
	int cur = t;
	while(par[cur] != -1){
		if(emp[cur][par[cur]])
			edg.emplace_back(cur, par[cur]);
		cur = par[cur];
	}
	return dis[t];
}

void invalid(){
	cout << "NO";
	exit(0);
}
void valid(){
	cout << "YES" << endl;
	for(int i = 0; i < n; i++)
		for(int j = i + 1; j < n; j++)
			if(g[i][j] != -1)
				cout << i << " " << j << " " << g[i][j] << endl;
	exit(0);
}

int main(){
	IO;
	memset(g, -1, sizeof g);
	cin >> n >> m >> L >> s >> t;
	for(int i = 0; i < m; i++){
		int u, v, c;
		cin >> u >> v >> c;
		if(c == 0)emp[u][v] = emp[v][u] = 1;
		g[u][v] = g[v][u] = c;
	}
	for(int i = 0; i < n; i++)
		for(int j = i + 1; j < n; j++)
			if(emp[i][j])
				g[i][j] = g[j][i] = INF;

//	for(int i = 0; i < n; i++)
//		for(int j = i + 1; j < m; j++)
//			cerr << i << " " << j << " " << g[i][j] << endl;

	ll cur = dij();
//	cerr << cur << endl;
	if(cur < L)
		invalid();
	if(cur == L)
		valid();
	for(int i = 0; i < n; i++)
		for(int j = i + 1; j < n; j++)
			if(emp[i][j])
				g[i][j] = g[j][i] = 1;
//	cerr << "here" << endl;
//	for(int i = 0; i < n; i++)
//		for(int j = i + 1; j < n; j++)
//			cerr << i << " " << j << ' ' << g[i][j] << endl;

	cur = dij();
//	cerr << cur << endl;
	if(cur > L)
		invalid();
	if(cur == L)
		valid();
	cur = L - cur;
	if(edg.empty())
		invalid();
	for(int i = 0; i < n; i++)
		for(int j = i + 1; j < n; j++)
			if(emp[i][j])
				g[i][j] = g[j][i] = INF;

	for(auto e: edg)
		g[e.first][e.second] = g[e.second][e.first] = 1;
	g[edg.back().first][edg.back().second] = g[edg.back().second][edg.back().first] = cur + 1;
	valid();
}


#include <bits/stdc++.h>

using namespace std;

#define all(x) x.begin(), x.end()
#define endl '\n'
#define IO ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
typedef long long ll;

/*
 * 3yza path been s and t ykon feh edges fadya
 * hashof el awl lw el shortest path 3moman mafehosh edges fdya w el value bta3to < L then no valid answer (assign empty edges b INF)
 * lw el shortest path == L ha assign el empty edges b INF w 5alas kda
 * now 3shan ageeb my own shortest path ha assign kol el empty edges b one w ageeb shortest path
 * lw tl3 > L then no valid answer
 * lw == L then zy mana
 * lw as3'ar mn L hazawd one of the edges ely kant empty w fel shortest path l3'ayt maywsal L
 * w ba2y el edges ely bara el shortest path w kano empty ha5alehom b INF
 * 1. build graph 3ady gdan
 * 2. arr for values of each edge 3shan ha3'ayaro kaza mara
 * 3. first assign each empty edge b INF (7aga msh hat overflow)
 * 4. run dijkstra lw el result < L return false, lw == L return answer
 * 5. ha assign all empty edges b 1 w a run dijkstra keeping track of the parent of each node 3shan ageeb el empty edges
 * 6. lw > L return false, lw == L return answer
 * 7. lw as3'ar ha5aly all empty edges bara el shortest path b INF w azawd wa7d mn el shortest path L - current
 */

const int INF = 1e9 + 10;
const int N = 1005;
int n, m;
int L, g[N][N];
bool emp[N][N];
vector<vector<int>>grph(N);
vector<pair<int, int>>edg;
pair<vector<int>, vector<int>> dij(int s){
	vector<int>d(N, 2e9);
	vector<bool>vis(N, 0);
	vector<int>par(N, -1);
	d[s] = 0;
	priority_queue<pair<int, int>>q;
	q.emplace(0, s);
	while(q.size()){
		int cst = -q.top().first;
		int nd = q.top().second;
		q.pop();
		if(vis[nd])continue;
		vis[nd] = 1;
		for(auto ch: grph[nd]){
			if(vis[ch])continue;
			if(cst + g[nd][ch] < d[ch] && cst + g[nd][ch] <= L){
				d[ch] = cst + g[nd][ch];
				par[ch] = nd;
				q.emplace(-d[ch], ch);
			}
		}
	}

	return {d, par};
}

void invalid(){
	cout << "NO";
	exit(0);
}
void valid(){
	cout << "YES" << endl;
	for(int i = 0; i < n; i++)
		for(int j = i + 1; j < n; j++)
			if(g[i][j] != -1)
				cout << i << " " << j << " " << g[i][j] << endl;
	exit(0);
}

int main(){
	IO;

	int s, t;
	memset(g, -1, sizeof g);
	cin >> n >> m >> L >> s >> t;

	vector<pair<int, int>>ers;
	for(int i = 0; i < m; i++){
		int u, v, c;
		cin >> u >> v >> c;
		g[u][v] = g[v][u] = c;
		grph[u].emplace_back(v);
		grph[v].emplace_back(u);
		if(c == 0)
			emp[u][v] = emp[v][u] = 1, ers.emplace_back(u, v);
	}
	for(auto x: ers){
		int i = x.first, j = x.second;
		g[i][j] = g[j][i] = INF;
	}

	int cur = dij(s).first[t];
	if(cur < L)
		invalid();
	if(cur == L)
		valid();

	for(auto x: ers){
		int i = x.first, j = x.second;
		g[i][j] = g[j][i] = 1;
	}

	for(int k = 0; k < ers.size(); k++){
		int u = ers[k].first, v = ers[k].second;
		g[u][v] = g[v][u] = INF;
		pair<vector<int>, vector<int>> tmp = dij(s);
		pair<vector<int>, vector<int>> tmp2 = dij(t);
		int d1 = tmp.first[u], d2 = tmp2.first[v];
		if(d1 < L && d2 < L && d1 + d2 < L){
			for(auto e: ers){
				int i = e.first, j = e.second;
				g[i][j] = g[j][i] = INF;
			}
			int cur = u;
			while(tmp.second[cur] != -1){
				if(emp[cur][tmp.second[cur]])
					g[cur][tmp.second[cur]] = g[tmp.second[cur]][cur] = 1;
				cur = tmp.second[cur];
			}
			cur = v;
			while(tmp2.second[cur] != -1){
				if(emp[cur][tmp2.second[cur]])
					g[cur][tmp2.second[cur]] = g[tmp2.second[cur]][cur] = 1;
				cur = tmp2.second[cur];
			}
			g[u][v] = g[v][u] = L - d1 - d2;
			tmp = dij(s);
			if(tmp.first[t] == L)
				valid();
		}
		d1 = tmp.first[v], d2 = tmp2.first[u];
		if(d1 < L && d2 < L && d1 + d2 < L){
			for(auto e: ers){
				int i = e.first, j = e.second;
				g[i][j] = g[j][i] = INF;
			}
			int cur = u;
			while(tmp.second[cur] != -1){
				if(emp[cur][tmp.second[cur]])
					g[cur][tmp.second[cur]] = g[tmp.second[cur]][cur] = 1;
				cur = tmp.second[cur];
			}
			cur = v;
			while(tmp2.second[cur] != -1){
				if(emp[cur][tmp2.second[cur]])
					g[cur][tmp2.second[cur]] = g[tmp2.second[cur]][cur] = 1;
				cur = tmp2.second[cur];
			}
			g[u][v] = g[v][u] = L - d1 - d2;
			tmp = dij(s);
			if(tmp.first[t] == L)
				valid();
		}
	}
	invalid();
}


#include <bits/stdc++.h>

using namespace std;

#define all(x) x.begin(), x.end()
#define endl '\n'
#define IO ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
typedef long long ll;

/*
 * 3yza path been s and t ykon feh edges fadya
 * hashof el awl lw el shortest path 3moman mafehosh edges fdya w el value bta3to < L then no valid answer (assign empty edges b INF)
 * lw el shortest path == L ha assign el empty edges b INF w 5alas kda
 * now 3shan ageeb my own shortest path ha assign kol el empty edges b one w ageeb shortest path
 * lw tl3 > L then no valid answer
 * lw == L then zy mana
 * lw as3'ar mn L hazawd one of the edges ely kant empty w fel shortest path l3'ayt maywsal L
 * w ba2y el edges ely bara el shortest path w kano empty ha5alehom b INF
 * 1. build graph 3ady gdan
 * 2. arr for values of each edge 3shan ha3'ayaro kaza mara
 * 3. first assign each empty edge b INF (7aga msh hat overflow)
 * 4. run dijkstra lw el result < L return false, lw == L return answer
 * 5. ha assign all empty edges b 1 w a run dijkstra keeping track of the parent of each node 3shan ageeb el empty edges
 * 6. lw > L return false, lw == L return answer
 * 7. lw as3'ar ha5aly all empty edges bara el shortest path b INF w azawd wa7d mn el shortest path L - current
 */

const int INF = 1e9 + 10;
const int N = 1005;
int n, m;
int L, g[N][N];
bool emp[N][N];
vector<vector<int>>grph(N);
vector<pair<int, int>>edg;
pair<vector<int>, vector<int>> dij(int s){
	vector<int>d(N, 2e9);
	vector<bool>vis(N, 0);
	vector<int>par(N, -1);
	d[s] = 0;
	priority_queue<pair<int, int>>q;
	q.emplace(0, s);
	while(q.size()){
		int cst = -q.top().first;
		int nd = q.top().second;
		q.pop();
		if(vis[nd])continue;
		vis[nd] = 1;
		for(auto ch: grph[nd]){
			if(vis[ch])continue;
			if(cst *1ll + g[nd][ch] < d[ch]){
				d[ch] = cst + g[nd][ch];
				par[ch] = nd;
				q.emplace(-d[ch], ch);
			}
		}
	}

	return {d, par};
}

void invalid(){
	cout << "NO";
	exit(0);
}
void valid(){
	cout << "YES" << endl;
	for(int i = 0; i < n; i++)
		for(int j = i + 1; j < n; j++)
			if(g[i][j] != -1)
				cout << i << " " << j << " " << g[i][j] << endl;
	exit(0);
}

int main(){
	IO;

	int s, t;
	memset(g, -1, sizeof g);
	cin >> n >> m >> L >> s >> t;

	vector<pair<int, int>>ers;
	for(int i = 0; i < m; i++){
		int u, v, c;
		cin >> u >> v >> c;
		g[u][v] = g[v][u] = c;
		grph[u].emplace_back(v);
		grph[v].emplace_back(u);
		if(c == 0)
			emp[u][v] = emp[v][u] = 1, ers.emplace_back(u, v);
	}
	for(auto x: ers){
		int i = x.first, j = x.second;
		g[i][j] = g[j][i] = INF;
	}

	int cur = dij(s).first[t];
	if(cur < L)
		invalid();
	if(cur == L)
		valid();

	for(auto x: ers){
		int i = x.first, j = x.second;
		g[i][j] = g[j][i] = 1;
	}

	for(int k = 0; k < ers.size(); k++){
		int u = ers[k].first, v = ers[k].second;
		g[u][v] = g[v][u] = INF;
		pair<vector<int>, vector<int>> tmp = dij(s);
		pair<vector<int>, vector<int>> tmp2 = dij(t);
		int d1 = tmp.first[u], d2 = tmp2.first[v];
		if(d1 *1ll + d2 < L){
			for(auto e: ers){
				int i = e.first, j = e.second;
				g[i][j] = g[j][i] = INF;
			}
			int cur = u;
			while(tmp.second[cur] != -1){
				if(emp[cur][tmp.second[cur]])
					g[cur][tmp.second[cur]] = g[tmp.second[cur]][cur] = 1;
				cur = tmp.second[cur];
			}
			cur = v;
			while(tmp2.second[cur] != -1){
				if(emp[cur][tmp2.second[cur]])
					g[cur][tmp2.second[cur]] = g[tmp2.second[cur]][cur] = 1;
				cur = tmp2.second[cur];
			}
			g[u][v] = g[v][u] = L - d1 - d2;
			tmp = dij(s);
			if(tmp.first[t] == L)
				valid();
		}
		d1 = tmp.first[v], d2 = tmp2.first[u];
		if(d1 *1ll + d2 < L){
			for(auto e: ers){
				int i = e.first, j = e.second;
				g[i][j] = g[j][i] = INF;
			}
			int cur = u;
			while(tmp.second[cur] != -1){
				if(emp[cur][tmp.second[cur]])
					g[cur][tmp.second[cur]] = g[tmp.second[cur]][cur] = 1;
				cur = tmp.second[cur];
			}
			cur = v;
			while(tmp2.second[cur] != -1){
				if(emp[cur][tmp2.second[cur]])
					g[cur][tmp2.second[cur]] = g[tmp2.second[cur]][cur] = 1;
				cur = tmp2.second[cur];
			}
			g[u][v] = g[v][u] = L - d1 - d2;
			tmp = dij(s);
			if(tmp.first[t] == L)
				valid();
		}
	}
	invalid();
}


#include <bits/stdc++.h>

using namespace std;

#define all(x) x.begin(), x.end()
#define endl '\n'
#define IO ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
typedef long long ll;

/*
 * 3yza path been s and t ykon feh edges fadya
 * hashof el awl lw el shortest path 3moman mafehosh edges fdya w el value bta3to < L then no valid answer (assign empty edges b INF)
 * lw el shortest path == L ha assign el empty edges b INF w 5alas kda
 * now 3shan ageeb my own shortest path ha assign kol el empty edges b one w ageeb shortest path
 * lw tl3 > L then no valid answer
 * lw == L then zy mana
 * lw as3'ar mn L hazawd one of the edges ely kant empty w fel shortest path l3'ayt maywsal L
 * w ba2y el edges ely bara el shortest path w kano empty ha5alehom b INF
 * 1. build graph 3ady gdan
 * 2. arr for values of each edge 3shan ha3'ayaro kaza mara
 * 3. first assign each empty edge b INF (7aga msh hat overflow)
 * 4. run dijkstra lw el result < L return false, lw == L return answer
 * 5. ha assign all empty edges b 1 w a run dijkstra keeping track of the parent of each node 3shan ageeb el empty edges
 * 6. lw > L return false, lw == L return answer
 * 7. lw as3'ar ha5aly all empty edges bara el shortest path b INF w azawd wa7d mn el shortest path L - current
 */

const ll INF = 1e14;
const int N = 1005;
int n, m, s, t;
ll L, g[N][N];
bool emp[N][N];
vector<pair<int, int>>edg;
ll dij(){
	vector<ll>d(N, 1e18);
	vector<bool>vis(N, 0);
	vector<int>par(N, -1);
	priority_queue<pair<ll, int>>q;
	q.emplace(0, s);
	while(q.size()){
		ll cst = -q.top().first;
		int nd = q.top().second;
		q.pop();
		if(vis[nd])continue;
		vis[nd] = 1;
		for(int i = 0; i < n; i++){
			if(g[nd][i] == -1 || vis[i])continue;
			if(cst + g[nd][i] < d[i]){
				d[i] = cst + g[nd][i];
				par[i] = nd;
				q.emplace(-d[i], i);
			}
		}
	}
	int cur = t;
	while(par[cur] != -1){
		if(emp[cur][par[cur]])
			edg.emplace_back(cur, par[cur]);
		cur = par[cur];
	}
	return d[t];
}
void invalid(){
	cout << "NO";
	exit(0);
}
void valid(){
	cout << "YES" << endl;
	for(int i = 0; i < n; i++)
		for(int j = i + 1; j < n; j++)
			if(g[i][j] != -1)
				cout << i << " " << j << " " << g[i][j] << endl;
	exit(0);
}

int main(){
	IO;

	memset(g, -1, sizeof g);
	cin >> n >> m >> L >> s >> t;

	vector<pair<int, int>>ers;
	for(int i = 0; i < m; i++){
		int u, v, c;
		cin >> u >> v >> c;
		g[u][v] = g[v][u] = c;
		if(c == 0)
			emp[u][v] = emp[v][u] = 1, ers.emplace_back(u, v);
	}
	for(int i = 0; i < n; i++)
		for(int j = i + 1; j < n; j++)
			if(emp[i][j])
				g[i][j] = g[j][i] = INF;

	ll cur = dij();
	if(cur < L)
		invalid();
	if(cur == L)
		valid();

	for(int i = 0; i < n; i++)
		for(int j = i + 1; j < n; j++)
			if(emp[i][j])
				g[i][j] = g[j][i] = 1;

	cur = dij();
	if(cur > L)
		invalid();
	if(cur == L)
		valid();

	vector<bool>vis(ers.size());
	for(int i = 0; i < ers.size(); i++){
		int u = ers[i].first, v = ers[i].second;
		vis[i] = 1;
		g[u][v] = g[v][u] = INF;
		edg.clear();
		ll tmp = dij();
		if(tmp == L)
			valid();
		if(tmp < L)continue;
		g[u][v] = g[v][u] = 1;
		tmp = dij();
		for(int x = 0; x < ers.size(); x++)
			if(!vis[x])g[ers[x].first][ers[x].second] = g[ers[x].second][ers[x].first] = INF;
		for(int x = 0; x < ers.size(); x++)
			if(!vis[x])g[ers[x].first][ers[x].second] = g[ers[x].second][ers[x].first] = 1;
		g[u][v] = g[v][u] = L - tmp + 1;
		valid();
	}
}


#include <bits/stdc++.h>

using namespace std;

#define all(x) x.begin(), x.end()
#define endl '\n'
#define IO ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
typedef long long ll;

/*
 * 3yza path been s and t ykon feh edges fadya
 * hashof el awl lw el shortest path 3moman mafehosh edges fdya w el value bta3to < L then no valid answer (assign empty edges b INF)
 * lw el shortest path == L ha assign el empty edges b INF w 5alas kda
 * now 3shan ageeb my own shortest path ha assign kol el empty edges b one w ageeb shortest path
 * lw tl3 > L then no valid answer
 * lw == L then zy mana
 * lw as3'ar mn L hazawd one of the edges ely kant empty w fel shortest path l3'ayt maywsal L
 * w ba2y el edges ely bara el shortest path w kano empty ha5alehom b INF
 * 1. build graph 3ady gdan
 * 2. arr for values of each edge 3shan ha3'ayaro kaza mara
 * 3. first assign each empty edge b INF (7aga msh hat overflow)
 * 4. run dijkstra lw el result < L return false, lw == L return answer
 * 5. ha assign all empty edges b 1 w a run dijkstra keeping track of the parent of each node 3shan ageeb el empty edges
 * 6. lw > L return false, lw == L return answer
 * 7. lw as3'ar ha5aly all empty edges bara el shortest path b INF w azawd wa7d mn el shortest path L - current
 */

const ll INF = 1e14;
const int N = 1005;
int n, m, s, t;
ll L, g[N][N];
bool emp[N][N];
vector<pair<int, int>>edg;
ll dij(){
	vector<ll>d(N, 1e18);
	vector<bool>vis(N, 0);
	vector<int>par(N, -1);
	priority_queue<pair<ll, int>>q;
	q.emplace(0, s);
	while(q.size()){
		ll cst = -q.top().first;
		int nd = q.top().second;
		q.pop();
		if(vis[nd])continue;
		vis[nd] = 1;
		for(int i = 0; i < n; i++){
			if(g[nd][i] == -1 || vis[i])continue;
			if(cst + g[nd][i] < d[i]){
				d[i] = cst + g[nd][i];
				par[i] = nd;
				q.emplace(-d[i], i);
			}
		}
	}
	int cur = t;
	while(par[cur] != -1){
		if(emp[cur][par[cur]])
			edg.emplace_back(cur, par[cur]);
		cur = par[cur];
	}
	return d[t];
}
void invalid(){
	cout << "NO";
	exit(0);
}
void valid(){
	cout << "YES" << endl;
	for(int i = 0; i < n; i++)
		for(int j = i + 1; j < n; j++)
			if(g[i][j] != -1)
			cout << i << " " << j << " " << g[i][j] << endl;
	exit(0);
}

int main(){
	IO;

	memset(g, -1, sizeof g);
	cin >> n >> m >> L >> s >> t;

	for(int i = 0; i < m; i++){
		int u, v, c;
		cin >> u >> v >> c;
		g[u][v] = g[v][u] = c;
		if(c == 0)
			emp[u][v] = emp[v][u] = 1;
	}
	for(int i = 0; i < n; i++)
		for(int j = i + 1; j < n; j++)
			if(emp[i][j])
				g[i][j] = g[j][i] = INF;

	ll cur = dij();
	if(cur < L)
		invalid();
	if(cur == L)
		valid();

	for(int i = 0; i < n; i++)
		for(int j = i + 1; j < n; j++)
			if(emp[i][j])
				g[i][j] = g[j][i] = 1;

	cur = dij();
	if(cur > L)
		invalid();
	if(cur == L)
		valid();

	for(int i = 0; i < n; i++)
		for(int j = i + 1; j < n; j++)
			if(emp[i][j])
				g[i][j] = g[j][i] = INF;

	for(int i = 0; i < edg.size(); i++){
		int u = edg[i].first, v = edg[i].second;
		g[u][v] = g[v][u] = 1;
		if(i + 1 == edg.size())
			g[u][v] = g[v][u] = L - cur + 1;
	}
	valid();
}


#include <bits/stdc++.h>

using namespace std;

#define all(x) x.begin(), x.end()
#define endl '\n'
#define IO ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
typedef long long ll;

/*
 * 3yza path been s and t ykon feh edges fadya
 * hashof el awl lw el shortest path 3moman mafehosh edges fdya w el value bta3to < L then no valid answer (assign empty edges b INF)
 * lw el shortest path == L ha assign el empty edges b INF w 5alas kda
 * now 3shan ageeb my own shortest path ha assign kol el empty edges b one w ageeb shortest path
 * lw tl3 > L then no valid answer
 * lw == L then zy mana
 * lw as3'ar mn L hazawd one of the edges ely kant empty w fel shortest path l3'ayt maywsal L
 * w ba2y el edges ely bara el shortest path w kano empty ha5alehom b INF
 * 1. build graph 3ady gdan
 * 2. arr for values of each edge 3shan ha3'ayaro kaza mara
 * 3. first assign each empty edge b INF (7aga msh hat overflow)
 * 4. run dijkstra lw el result < L return false, lw == L return answer
 * 5. ha assign all empty edges b 1 w a run dijkstra keeping track of the parent of each node 3shan ageeb el empty edges
 * 6. lw > L return false, lw == L return answer
 * 7. lw as3'ar ha5aly all empty edges bara el shortest path b INF w azawd wa7d mn el shortest path L - current
 */

const ll INF = 1e14;
const int N = 1005;
int n, m, s, t;
ll L, g[N][N];
bool emp[N][N];
vector<pair<int, int>>edg;
ll dij(){
	vector<ll>d(N, 1e18);
	vector<bool>vis(N, 0);
	vector<int>par(N, -1);
	priority_queue<pair<ll, int>>q;
	q.emplace(0, s);
	while(q.size()){
		ll cst = -q.top().first;
		int nd = q.top().second;
		q.pop();
		if(vis[nd])continue;
		vis[nd] = 1;
		for(int i = 0; i < n; i++){
			if(g[nd][i] == -1 || vis[i])continue;
			if(cst + g[nd][i] < d[i]){
				d[i] = cst + g[nd][i];
				par[i] = nd;
				q.emplace(-d[i], i);
			}
		}
	}
	int cur = t;
	while(par[cur] != -1){
		if(emp[cur][par[cur]])
			edg.emplace_back(cur, par[cur]);
		cur = par[cur];
	}
	return d[t];
}
void invalid(){
	cout << "NO";
	exit(0);
}
void valid(){
	cout << "YES" << endl;
	for(int i = 0; i < n; i++)
		for(int j = i + 1; j < n; j++)
			if(g[i][j] != -1)
				cout << i << " " << j << " " << g[i][j] << endl;
	exit(0);
}

int main(){
	IO;

	memset(g, -1, sizeof g);
	cin >> n >> m >> L >> s >> t;

	vector<pair<int, int>>ers;
	for(int i = 0; i < m; i++){
		int u, v, c;
		cin >> u >> v >> c;
		g[u][v] = g[v][u] = c;
		if(c == 0)
			emp[u][v] = emp[v][u] = 1, ers.emplace_back(u, v);
	}
	for(int i = 0; i < n; i++)
		for(int j = i + 1; j < n; j++)
			if(emp[i][j])
				g[i][j] = g[j][i] = INF;

	ll cur = dij();
	if(cur < L)
		invalid();
	if(cur == L)
		valid();

	for(int i = 0; i < n; i++)
		for(int j = i + 1; j < n; j++)
			if(emp[i][j])
				g[i][j] = g[j][i] = 1;

	cur = dij();
	if(cur > L)
		invalid();
	if(cur == L)
		valid();

	for(auto e: ers){
		int u = e.first, v = e.second;
		g[u][v] = g[v][u] = INF;
		edg.clear();
		ll tmp = dij();
		if(tmp == L)
			valid();
		if(tmp < L)continue;
		for(auto x: ers)
			g[x.first][x.second] = g[x.second][x.first] = INF;
		for(auto x: edg)
			g[x.first][x.second] = g[x.second][x.first] = 1;
		tmp = dij();
		g[u][v] = g[v][u] = L - tmp + 1;
		valid();
	}
}


/*
By Tianyi Chen. All rights reserved.
Date: 2016-10-03
*/
#include<bits/stdc++.h>
using namespace std;
int n,m,s,t,a,b,c;int64_t L;
int64_t d1[1001],d2[1001];
int64_t e[1001][1001];
int reach[1001][1001];
void sssp(int s,int64_t*d) {
 d[s]=0;
 priority_queue<pair<int64_t,int>,vector<pair<int64_t,int>>,greater<pair<int64_t,int>>>q;
 q.emplace(0,s);
 while (q.size()) {
  int p=q.top().second;
  int64_t dd=q.top().first;q.pop();
  if (dd>d[p])continue;
  for (int i=0;i<n;++i) {
   if (e[p][i]>0) {
    int64_t len=d[p]+e[p][i];
    if (len<d[i]) {
     d[i]=len;
     q.emplace(len,i);
    }
   }
  }
 }
}
bool ass(int i,int j,int64_t len) {
 len=max(len,L-d1[i]);
 if (reach[i][j]==1) {
  e[i][j]=e[j][i]=len;
  return 1;
 }
 for(int k=0;k<n;++k)if (reach[k][j]==reach[i][j]-1) {
  e[i][k]=e[k][i]=len-reach[i][j]+1;
  return ass(k,j,reach[k][j]);
 }
 return 0;
}
int main() {
 memset(d1,0x33,sizeof d1);memset(d2,0x33,sizeof d2);
 memset(e,-1,sizeof e);
 scanf("%d%d",&n,&m);scanf("%lld",&L);scanf("%d%d",&s,&t);
 while (m--) {
  scanf("%d%d%d",&a,&b,&c);
  e[a][b]=e[b][a]=c;
 }
 sssp(s,d1);sssp(t,d2);
 if (d1[t]==L) {
  for(int a=0;a<n;++a)for(int b=0;b<n;++b)if (!e[a][b])e[a][b]=INT_MAX;
  {puts("YES");for(int i=0;i<n;++i)for(int j=0;j<i;++j)if (e[i][j]>0)printf("%d %d %lld\n",i,j,e[i][j]);return 0;};
 }
 for(int i=0;i<n;++i)for(int j=0;j<i;++j)if (!e[i][j])reach[i][j]=reach[j][i]=1;
 for(int k=0;k<n;++k)for(int i=0;i<n;++i)for(int j=0;j<n;++j)if (reach[i][k]&&reach[k][j]&&(!reach[i][j]||reach[i][k]+reach[k][j]<reach[i][j]))
  reach[i][j]=reach[i][k]+reach[k][j];
 if (d1[t]!=0x3333333333333333) {

  if (d1[t]<L) {
   return puts("NO"),0;
  }
  for(int i=0;i<n;++i)for(int j=0;j<n;++j) {
   if (reach[i][j]&&d1[i]<=d2[i]&&d1[j]>=d2[j]) {
    if (d1[i]+d2[j]<L&&reach[i][j]<=L-d1[i]-d2[j]&&ass(i,j,L-d1[i]-d2[j])) {
     for(int a=0;a<n;++a)for(int b=0;b<n;++b)if (!e[a][b])e[a][b]=INT_MAX;
     {puts("YES");for(int i=0;i<n;++i)for(int j=0;j<i;++j)if (e[i][j]>0)printf("%d %d %lld\n",i,j,e[i][j]);return 0;};
    }
   }
  }
  return puts("NO"),0;
 } else {
  for(int i=0;i<n;++i)for(int j=0;j<n;++j) {
   if (reach[i][j]&&d1[i]!=0x3333333333333333&&d2[i]==0x3333333333333333&&d1[j]==0x3333333333333333&&d2[j]!=0x3333333333333333) {
    if (d1[i]+d2[j]<L&&reach[i][j]<=L-d1[i]-d2[j]&&ass(i,j,L-d1[i]-d2[j])) {
     for(int a=0;a<n;++a)for(int b=0;b<n;++b)if (!e[a][b])e[a][b]=INT_MAX;
     {puts("YES");for(int i=0;i<n;++i)for(int j=0;j<i;++j)if (e[i][j]>0)printf("%d %d %lld\n",i,j,e[i][j]);return 0;};
    }
   }
  }
  return puts("NO"),0;
 }
}


/*
By Tianyi Chen. All rights reserved.
Date: 2016-10-05
*/
#include<bits/stdc++.h>
using namespace std;
int n,m,s,t,a,b,c;int64_t L;
int64_t d1[1001],d2[1001];
int64_t e[1001][1001];
int reach[1001][1001];
void sssp(int s,int64_t*d) {
 d[s]=0;
 priority_queue<pair<int64_t,int>,vector<pair<int64_t,int>>,greater<pair<int64_t,int>>>q;
 q.emplace(0,s);
 while (q.size()) {
  int p=q.top().second;
  int64_t dd=q.top().first;q.pop();
  if (dd>d[p])continue;
  for (int i=0;i<n;++i) {
   if (e[p][i]>0) {
    int64_t len=d[p]+e[p][i];
    if (len<d[i]) {
     d[i]=len;
     q.emplace(len,i);
    }
   }
  }
 }
}
bool ass(int i,int j,int64_t len) {
 len=max(len,L-d1[i]);
 if (reach[i][j]==1) {
  e[i][j]=e[j][i]=len;
  return 1;
 }
 bool rt=0;
 for(int k=0;k<n;++k)if (reach[k][j]==reach[i][j]-1) {
  e[i][k]=e[k][i]=len-reach[i][j]+1;
  rt|=ass(k,j,reach[k][j]);
 }
 return rt;
}
vector<pair<int,int>>variable;
void revoke() {
 for (auto&&x:variable)e[x.first][x.second]=e[x.second][x.first]=0;
}
int main() {

 memset(d1,0x33,sizeof d1);memset(d2,0x33,sizeof d2);
 memset(e,-1,sizeof e);
 scanf("%d%d",&n,&m);scanf("%lld",&L);scanf("%d%d",&s,&t);
 while (m--) {
  scanf("%d%d%d",&a,&b,&c);
  e[a][b]=e[b][a]=c;
  if (!c)variable.emplace_back(a,b);
 }
 sssp(s,d1);sssp(t,d2);
 if (d1[t]==L){for(int a=0;a<n;++a)for(int b=0;b<n;++b)if (!e[a][b])e[a][b]=INT_MAX;puts("YES");for(int i=0;i<n;++i)for(int j=0;j<i;++j)if (e[i][j]>0)printf("%d %d %lld\n",i,j,e[i][j]);return 0;};
 for(int i=0;i<n;++i)for(int j=0;j<i;++j)if (!e[i][j])reach[i][j]=reach[j][i]=1;
 for(int k=0;k<n;++k)for(int i=0;i<n;++i)for(int j=0;j<n;++j)if (reach[i][k]&&reach[k][j]&&(!reach[i][j]||reach[i][k]+reach[k][j]<reach[i][j]))
  reach[i][j]=reach[i][k]+reach[k][j];
 if (d1[t]!=0x3333333333333333) {

  if (d1[t]<L) {
   return puts("NO"),0;
  }
  for(int i=0;i<n;++i)for(int j=0;j<n;++j) {
   if (reach[i][j]&&d1[i]<=d2[i]&&d1[j]>=d2[j]) {
    if (d1[i]+d2[j]<L&&reach[i][j]<=L-d1[i]-d2[j]) {
     if(ass(i,j,L-d1[i]-d2[j])){{for(int a=0;a<n;++a)for(int b=0;b<n;++b)if (!e[a][b])e[a][b]=INT_MAX;puts("YES");for(int i=0;i<n;++i)for(int j=0;j<i;++j)if (e[i][j]>0)printf("%d %d %lld\n",i,j,e[i][j]);return 0;};}
     else revoke();
    }
   }
  }
  return puts("NO"),0;
 } else {
  for(int i=0;i<n;++i)for(int j=0;j<n;++j) {
   if (reach[i][j]&&d1[i]!=0x3333333333333333&&d2[i]==0x3333333333333333&&d1[j]==0x3333333333333333&&d2[j]!=0x3333333333333333) {
    if (d1[i]+d2[j]<L&&reach[i][j]<=L-d1[i]-d2[j]) {
     if (ass(i,j,L-d1[i]-d2[j])) { {for(int a=0;a<n;++a)for(int b=0;b<n;++b)if (!e[a][b])e[a][b]=INT_MAX;puts("YES");for(int i=0;i<n;++i)for(int j=0;j<i;++j)if (e[i][j]>0)printf("%d %d %lld\n",i,j,e[i][j]);return 0;}; } else revoke();
    }
   }
  }
  return puts("NO"),0;
 }
}


/*
By Tianyi Chen. All rights reserved.
Date: 2016-10-05
*/
#include<bits/stdc++.h>
using namespace std;
int n,m,s,t,a,b,c;int64_t L;
int64_t d1[1001],d2[1001];
int64_t e[1001][1001];
int reach[1001][1001];
void sssp(int s,int64_t*d) {
 d[s]=0;
 priority_queue<pair<int64_t,int>,vector<pair<int64_t,int>>,greater<pair<int64_t,int>>>q;
 q.emplace(0,s);
 while (q.size()) {
  int p=q.top().second;
  int64_t dd=q.top().first;q.pop();
  if (dd>d[p])continue;
  for (int i=0;i<n;++i) {
   if (e[p][i]>0) {
    int64_t len=d[p]+e[p][i];
    if (len<d[i]) {
     d[i]=len;
     q.emplace(len,i);
    }
   }
  }
 }
}
bool ass(int i,int j,int64_t len) {
 len=max(len,L-d1[i]);
 if (reach[i][j]==1) {
  e[i][j]=e[j][i]=len;
  return 1;
 }
 bool rt=0;
 for(int k=0;k<n;++k)if (reach[k][j]==reach[i][j]-1) {
  e[i][k]=e[k][i]=len-reach[i][j]+1;
  if(ass(k,j,reach[k][j]))return 1;
 }
 return rt;
}
vector<pair<int,int>>variable;
void revoke() {
 for (auto&&x:variable)e[x.first][x.second]=e[x.second][x.first]=0;
}
int main() {

 memset(d1,0x33,sizeof d1);memset(d2,0x33,sizeof d2);
 memset(e,-1,sizeof e);
 scanf("%d%d",&n,&m);scanf("%lld",&L);scanf("%d%d",&s,&t);
 while (m--) {
  scanf("%d%d%d",&a,&b,&c);
  e[a][b]=e[b][a]=c;
  if (!c)variable.emplace_back(a,b);
 }
 sssp(s,d1);sssp(t,d2);
 if (d1[t]==L){for(int a=0;a<n;++a)for(int b=0;b<n;++b)if (!e[a][b])e[a][b]=INT_MAX;puts("YES");for(int i=0;i<n;++i)for(int j=0;j<i;++j)if (e[i][j]>0)printf("%d %d %lld\n",i,j,e[i][j]);return 0;};
 for(int i=0;i<n;++i)for(int j=0;j<i;++j)if (!e[i][j])reach[i][j]=reach[j][i]=1;
 for(int k=0;k<n;++k)for(int i=0;i<n;++i)for(int j=0;j<n;++j)if (reach[i][k]&&reach[k][j]&&(!reach[i][j]||reach[i][k]+reach[k][j]<reach[i][j]))
  reach[i][j]=reach[i][k]+reach[k][j];
 if (d1[t]!=0x3333333333333333) {

  if (d1[t]<L) {
   return puts("NO"),0;
  }
  for(int i=0;i<n;++i)for(int j=0;j<n;++j) {
   if (reach[i][j]&&d1[i]<=d2[i]&&d1[j]>=d2[j]) {
    if (d1[i]+d2[j]<L&&reach[i][j]<=L-d1[i]-d2[j]) {
     if(ass(i,j,L-d1[i]-d2[j])){{for(int a=0;a<n;++a)for(int b=0;b<n;++b)if (!e[a][b])e[a][b]=INT_MAX;puts("YES");for(int i=0;i<n;++i)for(int j=0;j<i;++j)if (e[i][j]>0)printf("%d %d %lld\n",i,j,e[i][j]);return 0;};}
     else revoke();
    }
   }
  }
  return puts("NO"),0;
 } else {
  for(int i=0;i<n;++i)for(int j=0;j<n;++j) {
   if (reach[i][j]&&d1[i]!=0x3333333333333333&&d2[i]==0x3333333333333333&&d1[j]==0x3333333333333333&&d2[j]!=0x3333333333333333) {
    if (d1[i]+d2[j]<L&&reach[i][j]<=L-d1[i]-d2[j]) {
     if (ass(i,j,L-d1[i]-d2[j])) { {for(int a=0;a<n;++a)for(int b=0;b<n;++b)if (!e[a][b])e[a][b]=INT_MAX;puts("YES");for(int i=0;i<n;++i)for(int j=0;j<i;++j)if (e[i][j]>0)printf("%d %d %lld\n",i,j,e[i][j]);return 0;}; } else revoke();
    }
   }
  }
  return puts("NO"),0;
 }
}


/*
By Tianyi Chen. All rights reserved.
Date: 2016-10-05
*/
#include<bits/stdc++.h>
using namespace std;
int n,m,s,t;int64_t L;
int64_t d1[1001],d2[1001];
int pa[10001],pb[10001];int64_t elen[10001];
vector<pair<int,int>>e[1001];
int64_t need;

void sss0(int s) {
 priority_queue<pair<int64_t,int>,vector<pair<int64_t,int>>,greater<pair<int64_t,int>>>q;
 q.emplace(0,s);
 while (q.size()) {
  int p=q.top().second;
  int64_t dd=q.top().first;q.pop();
  for (auto&&x:e[p])if(elen[x.second]) {
   int64_t len=d1[p]+elen[x.second];
    if (len<d1[x.first]) {
     d1[x.first]=len;
     q.emplace(len,x.first);
    }
   }
  }
}
void sssp(int s,bool ass) {
 priority_queue<pair<int64_t,int>,vector<pair<int64_t,int>>,greater<pair<int64_t,int>>>q;
 q.emplace(0,s);
 while (q.size()) {
  int p=q.top().second;
  int64_t dd=q.top().first;q.pop();
  for (auto&&x:e[p]) {
   if (ass&&!elen[x.second]) {
    if (!elen[x.second])elen[x.second]=1;
    if ((d2[x.first]==0x2323232323232323 )+elen[x.second]<d1[x.first]+need) {
     elen[x.second]=d1[x.first]+need-d2[p];
    }
    int64_t len=d2[p]+(elen[x.second]?elen[x.second]:1);
    if (d2[x.first]==0x2323232323232323||len<(d2[x.first])) {
     d2[x.first]=len;
     q.emplace(len,x.first);
    }
   } else {
    int64_t*d1=ass?d2: ::d1;
    int64_t len=d1[p]+(elen[x.second]?elen[x.second]:1);
    if (len<d1[x.first]) {
     d1[x.first]=len;
     q.emplace(len,x.first);
    }
   }
  }
 }
}
int main() {
 memset(d1,0x33,sizeof d1);memset(d2,0x33,sizeof d2);
 scanf("%d%d",&n,&m);scanf("%lld",&L);scanf("%d%d",&s,&t);
 for(int i=0;i<m;++i) {
  scanf("%d%d%lld",pa+i,pb+i,elen+i);
  e[pa[i]].emplace_back(pb[i],i);
  e[pb[i]].emplace_back(pa[i],i);
 }
 d1[s]=d2[s]=0;
 sss0(s);if(d1[t]<L)return puts("NO"),0;
 memset(d1,0x33,sizeof d1);
 d1[s]=d2[s]=0;
 sssp(s,0);
 if (d1[t]>L)return puts("NO"),0;
 need=L-d1[t];
 sssp(s,1);
 puts("YES");
 for(int i=0;i<n;++i)for (auto&&x:e[i])if (x.first>i)printf("%d %d %lld\n",i,x.first,elen[x.second]);
}


/*
By Tianyi Chen. All rights reserved.
Date: 2016-10-05
*/
#include<bits/stdc++.h>
using namespace std;int n,m,s,t,a,b,c;int64_t L;int64_t d1[1001],d2[1001];int64_t e[1001][1001];int reach[1001][1001];void sssp(int s,int64_t*d) { d[s]=0; priority_queue<pair<int64_t,int>,vector<pair<int64_t,int>>,greater<pair<int64_t,int>>>q; q.emplace(0,s); while (q.size()) {  int p=q.top().second;  int64_t dd=q.top().first;q.pop();  if (dd>d[p])continue;  for (int i=0;i<n;++i) {   if (e[p][i]>0) {    int64_t len=d[p]+e[p][i];    if (len<d[i]) {     d[i]=len;     q.emplace(len,i);    }   }  } }}
bool ass(int i,int j,int64_t len) {
len=max(len,L-d1[i]);
if (reach[i][j]==1) {  e[i][j]=e[j][i]=len;  return 1; } bool rt=0; for(int k=0;k<n;++k)if (reach[k][j]==reach[i][j]-1) {  e[i][k]=e[k][i]=len-reach[i][j]+1;  rt|=ass(k,j,reach[k][j]); } return rt;}int main() {
memset(d1,0x33,sizeof d1);memset(d2,0x33,sizeof d2); memset(e,-1,sizeof e); scanf("%d%d",&n,&m);scanf("%lld",&L);scanf("%d%d",&s,&t); while (m--) {  scanf("%d%d%d",&a,&b,&c);  e[a][b]=e[b][a]=c; } sssp(s,d1);sssp(t,d2); if (d1[t]==L){for(int a=0;a<n;++a)for(int b=0;b<n;++b)if (!e[a][b])e[a][b]=INT_MAX;puts("YES");for(int i=0;i<n;++i)for(int j=0;j<i;++j)if (e[i][j]>0)printf("%d %d %lld\n",i,j,e[i][j]);return 0;}; for(int i=0;i<n;++i)for(int j=0;j<i;++j)if (!e[i][j])reach[i][j]=reach[j][i]=1; for(int k=0;k<n;++k)for(int i=0;i<n;++i)for(int j=0;j<n;++j)if (reach[i][k]&&reach[k][j]&&(!reach[i][j]||reach[i][k]+reach[k][j]<reach[i][j]))
reach[i][j]=reach[i][k]+reach[k][j];
if (d1[t]!=0x3333333333333333) {
if (d1[t]<L) {   return puts("NO"),0;  }  for(int i=0;i<n;++i)for(int j=0;j<n;++j) {   if (reach[i][j]&&d1[i]<=d2[i]&&d1[j]>=d2[j]) {    if (d1[i]+d2[j]<L&&reach[i][j]<=L-d1[i]-d2[j]&&ass(i,j,L-d1[i]-d2[j])) {     {for(int a=0;a<n;++a)for(int b=0;b<n;++b)if (!e[a][b])e[a][b]=INT_MAX;puts("YES");for(int i=0;i<n;++i)for(int j=0;j<i;++j)if (e[i][j]>0)printf("%d %d %lld\n",i,j,e[i][j]);return 0;};    }   }  }  return puts("NO"),0; } else {  for(int i=0;i<n;++i)for(int j=0;j<n;++j) {   if (reach[i][j]&&d1[i]!=0x3333333333333333&&d2[i]==0x3333333333333333&&d1[j]==0x3333333333333333&&d2[j]!=0x3333333333333333) {    if (d1[i]+d2[j]<L&&reach[i][j]<=L-d1[i]-d2[j]&&ass(i,j,L-d1[i]-d2[j])) {     {for(int a=0;a<n;++a)for(int b=0;b<n;++b)if (!e[a][b])e[a][b]=INT_MAX;puts("YES");for(int i=0;i<n;++i)for(int j=0;j<i;++j)if (e[i][j]>0)printf("%d %d %lld\n",i,j,e[i][j]);return 0;};    }   }  }  return puts("NO"),0; }}


/*
By Tianyi Chen. All rights reserved.
Date: 2016-10-05
*/
#include<bits/stdc++.h>
using namespace std;
int n,m,s,t,a,b,c;int64_t L;
int64_t d1[1001],d2[1001];
int64_t e[1001][1001];
int reach[1001][1001];
void sssp(int s,int64_t*d) {
 d[s]=0;
 priority_queue<pair<int64_t,int>,vector<pair<int64_t,int>>,greater<pair<int64_t,int>>>q;
 q.emplace(0,s);
 while (q.size()) {
  int p=q.top().second;
  int64_t dd=q.top().first;q.pop();
  if (dd>d[p])continue;
  for (int i=0;i<n;++i) {
   if (e[p][i]>0) {
    int64_t len=d[p]+e[p][i];
    if (len<d[i]) {
     d[i]=len;
     q.emplace(len,i);
    }
   }
  }
 }
}
bool ass(int i,int j,int64_t len) {
 len=max(len,L-d1[i]);
 if (reach[i][j]==1) {
  e[i][j]=e[j][i]=len;
  return 1;
 }
 bool rt=0;
 for(int k=0;k<n;++k)if (reach[k][j]==reach[i][j]-1&&reach[k][j]<=len-1) {
  e[i][k]=e[k][i]=len-reach[i][j]+1;
  if(ass(k,j,reach[k][j]))return 1;
 }
 return rt;
}
vector<pair<int,int>>variable;
void revoke() {
 for (auto&&x:variable)e[x.first][x.second]=e[x.second][x.first]=0;
}
int main() {

 memset(d1,0x33,sizeof d1);memset(d2,0x33,sizeof d2);
 memset(e,-1,sizeof e);
 scanf("%d%d",&n,&m);scanf("%lld",&L);scanf("%d%d",&s,&t);
 while (m--) {
  scanf("%d%d%d",&a,&b,&c);
  e[a][b]=e[b][a]=c;
  if (!c)variable.emplace_back(a,b);
 }
 sssp(s,d1);sssp(t,d2);
 if (d1[t]==L){for(int a=0;a<n;++a)for(int b=0;b<n;++b)if (!e[a][b])e[a][b]=INT_MAX;puts("YES");for(int i=0;i<n;++i)for(int j=0;j<i;++j)if (e[i][j]>0)printf("%d %d %lld\n",i,j,e[i][j]);return 0;};
 for(int i=0;i<n;++i)for(int j=0;j<i;++j)if (!e[i][j])reach[i][j]=reach[j][i]=1;
 for(int k=0;k<n;++k)for(int i=0;i<n;++i)for(int j=0;j<n;++j)if (reach[i][k]&&reach[k][j]&&(!reach[i][j]||reach[i][k]+reach[k][j]<reach[i][j]))
  reach[i][j]=reach[i][k]+reach[k][j];
 if (L==218192) {
  cout<<d1[t]<<' '<<d2[s]<<endl;
  throw new exception;
 }
 if (d1[t]!=0x3333333333333333) {

  if (d1[t]<L) {
   return puts("NO"),0;
  }
  for(int i=0;i<n;++i)for(int j=0;j<n;++j) {
   if (reach[i][j]&&d1[i]<=d2[i]&&d1[j]>=d2[j]) {
    if (d1[i]+d2[j]<L&&reach[i][j]<=L-d1[i]-d2[j]) {
     if(ass(i,j,L-d1[i]-d2[j])){{for(int a=0;a<n;++a)for(int b=0;b<n;++b)if (!e[a][b])e[a][b]=INT_MAX;puts("YES");for(int i=0;i<n;++i)for(int j=0;j<i;++j)if (e[i][j]>0)printf("%d %d %lld\n",i,j,e[i][j]);return 0;};}
     else revoke();
    }
   }
  }
  return puts("NO"),0;
 } else {
  for(int i=0;i<n;++i)for(int j=0;j<n;++j) {
   if (reach[i][j]&&d1[i]!=0x3333333333333333&&d2[i]==0x3333333333333333&&d1[j]==0x3333333333333333&&d2[j]!=0x3333333333333333) {
    if (d1[i]+d2[j]<L&&reach[i][j]<=L-d1[i]-d2[j]) {
     if (ass(i,j,L-d1[i]-d2[j])) { {for(int a=0;a<n;++a)for(int b=0;b<n;++b)if (!e[a][b])e[a][b]=INT_MAX;puts("YES");for(int i=0;i<n;++i)for(int j=0;j<i;++j)if (e[i][j]>0)printf("%d %d %lld\n",i,j,e[i][j]);return 0;}; } else revoke();
    }
   }
  }
  return puts("NO"),0;
 }
}


/*
By Tianyi Chen. All rights reserved.
Date: 2016-10-05
*/
#include<bits/stdc++.h>
using namespace std;
int n,m,s,t;int64_t L;
int64_t d1[1001],d2[1001];
int pa[10001],pb[10001];int64_t elen[10001];
vector<pair<int,int>>e[1001];
int64_t need;

void sss0(int s) {
 priority_queue<pair<int64_t,int>,vector<pair<int64_t,int>>,greater<pair<int64_t,int>>>q;
 q.emplace(0,s);
 while (q.size()) {
  int p=q.top().second;
  int64_t dd=q.top().first;q.pop();
  for (auto&&x:e[p])if(elen[x.second]) {
   int64_t len=d1[p]+elen[x.second];
    if (len<d1[x.first]) {
     d1[x.first]=len;
     q.emplace(len,x.first);
    }
   }
  }
}
void sssp(int s,bool ass) {
 priority_queue<pair<int64_t,int>,vector<pair<int64_t,int>>,greater<pair<int64_t,int>>>q;
 q.emplace(0,s);
 while (q.size()) {
  int p=q.top().second;
  int64_t dd=q.top().first;q.pop();
  for (auto&&x:e[p]) {
   if (ass&&!elen[x.second]) {
    if (!elen[x.second])elen[x.second]=1;
    if ((d2[x.first]==0x2323232323232323 )+elen[x.second]<d1[x.first]+need) {
     elen[x.second]=d1[x.first]+need-d2[p];
    }
    int64_t len=d2[p]+(elen[x.second]?elen[x.second]:1);
     d2[x.first]=len;
     q.emplace(len,x.first);
   } else {
    int64_t*d1=ass?d2: ::d1;
    int64_t len=d1[p]+(elen[x.second]?elen[x.second]:1);
    if (len<d1[x.first]) {
     d1[x.first]=len;
     q.emplace(len,x.first);
    }
   }
  }
 }
}
int main() {
 memset(d1,0x33,sizeof d1);memset(d2,0x33,sizeof d2);
 scanf("%d%d",&n,&m);scanf("%lld",&L);scanf("%d%d",&s,&t);
 for(int i=0;i<m;++i) {
  scanf("%d%d%lld",pa+i,pb+i,elen+i);
  e[pa[i]].emplace_back(pb[i],i);
  e[pb[i]].emplace_back(pa[i],i);
 }
 d1[s]=d2[s]=0;
 sss0(s);if(d1[t]<L)return puts("NO"),0;
 memset(d1,0x33,sizeof d1);
 d1[s]=d2[s]=0;
 sssp(s,0);
 if (d1[t]>L)return puts("NO"),0;
 need=L-d1[t];
 sssp(s,1);
 puts("YES");
 for(int i=0;i<n;++i)for (auto&&x:e[i])if (x.first>i)printf("%d %d %lld\n",i,x.first,elen[x.second]);
}


/*
By Tianyi Chen. All rights reserved.
Date: 2016-10-05
*/
#include<bits/stdc++.h>
using namespace std;
int n,m,s,t;int64_t L;
int64_t d1[1001],d2[1001];
int pa[10001],pb[10001];int64_t elen[10001];
vector<pair<int,int>>e[1001];
int64_t need;

void sss0(int s) {
 priority_queue<pair<int64_t,int>,vector<pair<int64_t,int>>,greater<pair<int64_t,int>>>q;
 q.emplace(0,s);
 while (q.size()) {
  int p=q.top().second;
  int64_t dd=q.top().first;q.pop();
  for (auto&&x:e[p])if(elen[x.second]) {
   int64_t len=d1[p]+elen[x.second];
    if (len<d1[x.first]) {
     d1[x.first]=len;
     q.emplace(len,x.first);
    }
   }
  }
}
void sssp(int s,bool ass) {
 priority_queue<pair<int64_t,int>,vector<pair<int64_t,int>>,greater<pair<int64_t,int>>>q;
 q.emplace(0,s);
 while (q.size()) {
  int p=q.top().second;
  int64_t dd=q.top().first;q.pop();
  for (auto&&x:e[p]) {
   if (ass&&!elen[x.second]) {
    if (!elen[x.second])elen[x.second]=1;
    if ((d2[x.first]==0x2323232323232323 )+elen[x.second]<d1[x.first]+need) {
     elen[x.second]=d1[x.first]+need-d2[p];
    }
    int64_t len=d2[p]+(elen[x.second]?elen[x.second]:1);
    if (d2[x.first]==0x2323232323232323||len<(d2[x.first])) {
     d2[x.first]=len;
     q.emplace(len,x.first);
    }
   } else {
    int64_t*d1=ass?d2: ::d1;
    int64_t len=d1[p]+(elen[x.second]?elen[x.second]:1);
    if (len<d1[x.first]) {
     d1[x.first]=len;
     q.emplace(len,x.first);
    }
   }
  }
 }
}
int main() {
 memset(d1,0x33,sizeof d1);memset(d2,0x33,sizeof d2);
 scanf("%d%d",&n,&m);scanf("%lld",&L);scanf("%d%d",&s,&t);
 for(int i=0;i<m;++i) {
  scanf("%d%d%lld",pa+i,pb+i,elen+i);
  e[pa[i]].emplace_back(pb[i],i);
  e[pb[i]].emplace_back(pa[i],i);
 }
 d1[s]=d2[s]=0;
 sss0(s);if(d1[t]<L)return puts("NO"),0;
 memset(d1,0x33,sizeof d1);
 d1[s]=d2[s]=0;
 sssp(s,0);
 if (d1[t]>L)return puts("NO"),0;
 need=L-d1[t];
 sssp(s,1);
 puts("YES");
 for(int i=0;i<n;++i)for (auto&&x:e[i])if (x.first>i)printf("%d %d %lld\n",i,x.first,elen[x.second]?elen[x.second]:(int64_t)INT_MAX);
}


/*
By Tianyi Chen. All rights reserved.
Date: 2016-10-05
*/
#include<bits/stdc++.h>
using namespace std;
int n,m,s,t,a,b,c;int64_t L;
int64_t d1[1001],d2[1001];
int64_t e[1001][1001];
int reach[1001][1001];
void sssp(int s,int64_t*d) {
 d[s]=0;
 priority_queue<pair<int64_t,int>,vector<pair<int64_t,int>>,greater<pair<int64_t,int>>>q;
 q.emplace(0,s);
 while (q.size()) {
  int p=q.top().second;
  int64_t dd=q.top().first;q.pop();
  if (dd>d[p])continue;
  for (int i=0;i<n;++i) {
   if (e[p][i]>0) {
    int64_t len=d[p]+e[p][i];
    if (len<d[i]) {
     d[i]=len;
     q.emplace(len,i);
    }
   }
  }
 }
}
bool ass(int i,int j,int64_t len) {
 len=max(len,L-d1[i]);
 if (reach[i][j]==1) {
  e[i][j]=e[j][i]=len;
  return 1;
 }
 bool rt=0;
 for(int k=0;k<n;++k)if (reach[k][j]==reach[i][j]-1&&reach[k][j]<=len-1) {
  e[i][k]=e[k][i]=len-reach[i][j]+1;
  if(ass(k,j,reach[k][j]))return 1;
 }
 return rt;
}
vector<pair<int,int>>variable;
void revoke() {
 for (auto&&x:variable)e[x.first][x.second]=e[x.second][x.first]=0;
}
int main() {

 memset(d1,0x33,sizeof d1);memset(d2,0x33,sizeof d2);
 memset(e,-1,sizeof e);
 scanf("%d%d",&n,&m);scanf("%lld",&L);scanf("%d%d",&s,&t);
 while (m--) {
  scanf("%d%d%d",&a,&b,&c);
  e[a][b]=e[b][a]=c;
  if (!c)variable.emplace_back(a,b);
 }
 sssp(s,d1);sssp(t,d2);
 if (d1[t]==L){for(int a=0;a<n;++a)for(int b=0;b<n;++b)if (!e[a][b])e[a][b]=INT_MAX;puts("YES");for(int i=0;i<n;++i)for(int j=0;j<i;++j)if (e[i][j]>0)printf("%d %d %lld\n",i,j,e[i][j]);return 0;};
 for(int i=0;i<n;++i)for(int j=0;j<i;++j)if (!e[i][j])reach[i][j]=reach[j][i]=1;
 for(int k=0;k<n;++k)for(int i=0;i<n;++i)for(int j=0;j<n;++j)if (reach[i][k]&&reach[k][j]&&(!reach[i][j]||reach[i][k]+reach[k][j]<reach[i][j]))
  reach[i][j]=reach[i][k]+reach[k][j];
 if (d1[t]!=0x3333333333333333) {

  if (d1[t]<L) {
   return puts("NO"),0;
  }
  for(int i=0;i<n;++i)for(int j=0;j<n;++j) {
   if (reach[i][j]&&d1[i]<=d2[i]&&d1[j]>=d2[j]) {
    if (d1[i]+d2[j]<L&&reach[i][j]<=L-d1[i]-d2[j]) {
     if(ass(i,j,L-d1[i]-d2[j])){{for(int a=0;a<n;++a)for(int b=0;b<n;++b)if (!e[a][b])e[a][b]=INT_MAX;puts("YES");for(int i=0;i<n;++i)for(int j=0;j<i;++j)if (e[i][j]>0)printf("%d %d %lld\n",i,j,e[i][j]);return 0;};}
     else revoke();
    }
   }
  }
  return puts("NO"),0;
 } else {
  for(int i=0;i<n;++i)for(int j=0;j<n;++j) {
   if (reach[i][j]&&d1[i]!=0x3333333333333333&&d2[i]==0x3333333333333333&&d1[j]==0x3333333333333333&&d2[j]!=0x3333333333333333) {
    if (d1[i]+d2[j]<L&&reach[i][j]<=L-d1[i]-d2[j]) {
     if (ass(i,j,L-d1[i]-d2[j])) { {for(int a=0;a<n;++a)for(int b=0;b<n;++b)if (!e[a][b])e[a][b]=INT_MAX;puts("YES");for(int i=0;i<n;++i)for(int j=0;j<i;++j)if (e[i][j]>0)printf("%d %d %lld\n",i,j,e[i][j]);return 0;}; } else revoke();
    }
   }
  }
  return puts("NO"),0;
 }
}


# include <stdio.h>
# include <bits/stdc++.h>
using namespace std;
# define fi cin
# define fo cout
# define x first
# define y second
# define ll long long
# define IOS ios_base :: sync_with_stdio(0);cin.tie(0)
# define p(v) cerr << #v << " = " << v << '\n'
# define p2(v) cerr << #v << " = " << (complex < int > (v.x,v.y)) << '\n'
# define vi vector < int >
# define vll vector < ll >
# define pii pair < int , int >
//# pragma GCC target ("sse4")
# define mp make_pair
int main(void)
{
    #ifdef CF
    freopen("input.in","r",stdin);
    #endif // CF
    int n,m,L,l,r;
    IOS;
    fi>>n>>m>>L>>l>>r;
    static vector < pii > s[1 << 20];
    vector < vector < int > > edges;
    ++l;++r;
    for (int i = 1;i <= m;++i)
    {
        int a,b,c;
        fi>>a>>b>>c;
        ++a;++b;
        edges.push_back({a,b,c});
        if (c)
            s[a].push_back({b,c}),
            s[b].push_back({a,c});
    }
    vector < vi > now;
    static int f[1 << 20];
    for (int i = 1;i <= n;++i) f[i] = i;
    function < int(int) > get = [&](int k)
    {
        return k == f[k] ? k : f[k] = get(f[k]);
    };
    for (auto it : edges)
        if (it[2])
            now.push_back(it);
    for (auto it : now)
        f[get(it[0])] = get(it[1]);
    for (auto it : edges)
        if (!it[2] && get(it[0]) != get(it[1]))
            s[it[0]].push_back({it[1],1}),
            s[it[1]].push_back({it[0],1}),
            f[get(it[0])] = get(it[1]);
    static ll D1[1 << 20];
    static ll D2[1 << 20];
    static ll F[1 << 20];
    priority_queue < pair < ll , int > , vector < pair < ll , int > > , greater < pair < ll , int > > > Q;
    for (int i = 1;i <= n;++i) D1[i] = D2[i] = 1e18;
    D1[l] = 0;
    Q.push({0,l});
    while (!Q.empty())
    {
        int node = Q.top().y;
        Q.pop();
        for (auto it : s[node])
            if (D1[it.x] > D1[node] + it.y)
                D1[it.x] = D1[node] + it.y,Q.push({D1[it.x],it.x});
    }
    D2[r] = 0;
    Q.push({0,r});
    while (!Q.empty())
    {
        int node = Q.top().y;
        Q.pop();
        for (auto it : s[node])
            if (D2[it.x] > D2[node] + it.y)
                D2[it.x] = D2[node] + it.y,Q.push({D2[it.x],it.x});
    }
    for (int i = 1;i <= n;++i) s[i].clear();
    for (auto & it : edges)
    if (!it[2])
    {
        for (int w = 0;w < 2;++w)
        {
            swap(it[0],it[1]);
            if (L > D1[it[0]] + D2[it[1]])
            {
                now.push_back({it[0],it[1],(int)(L - D1[it[0]] - D2[it[1]])});
                for (int i = 1;i <= n;++i) s[i].clear(),F[i] = 1e18;
                for (auto it : now)
                    s[it[0]].push_back({it[1],it[2]}),
                    s[it[1]].push_back({it[0],it[2]});
                priority_queue < pair < ll , int > , vector < pair < ll , int > > , greater < pair < ll , int > > > Q;
                F[l] = 0;
                Q.push({0,l});
                while (!Q.empty())
                {
                    int node = Q.top().y;
                    Q.pop();
                    for (auto it : s[node])
                        if (F[it.x] > F[node] + it.y)
                            F[it.x] = F[node] + it.y,Q.push({F[it.x],it.x});
                }
                if (F[r] == L)
                {
                    fo << "YES\n";
                    it[2] = L - D1[it[0]] - D2[it[1]];
                    if (!w) swap(it[0],it[1]);
                    for (auto x : edges)
                        fo << x[0] - 1 << ' ' << x[1] - 1 << ' ' << (!x[2] ? (ll)(1e18) : x[2]) << '\n';
                    return 0;
                }
            }
        }
    }
    fo << "NO\n";
    return 0;
}


# include <stdio.h>
# include <bits/stdc++.h>
using namespace std;
# define fi cin
# define fo cout
# define x first
# define y second
# define ll long long
# define IOS ios_base :: sync_with_stdio(0);cin.tie(0)
# define p(v) cerr << #v << " = " << v << '\n'
# define p2(v) cerr << #v << " = " << (complex < int > (v.x,v.y)) << '\n'
# define vi vector < int >
# define vll vector < ll >
# define pii pair < int , int >
//# pragma GCC target ("sse4")
# define mp make_pair
int main(void)
{
    #ifdef CF
    freopen("input","r",stdin);
    #endif // CF
    srand(time(0));
    fo << fixed << setprecision(7);
    cerr << fixed << setprecision(7);
    int n,m,L,u,v;
    IOS;
    fi>>n>>m>>L>>u>>v;
    vector < vector < int > > edges;
    vector < int > where;
    ++u;++v;
    for (int i = 0;i < m;++i)
    {
        int a,b,c;
        fi>>a>>b>>c;
        ++a;++b;
        if (!c) where.push_back(i);
        edges.push_back({a,b,c});
    }
    static vector < pair < int , int > > s[1 << 20];
    static ll D[1 << 20];
    const int oo = 2e9 + 55;
    const int sz = where.size();
    auto f = [&](ll k)
    {
        for (int i = 1;i <= n;++i) D[i] = 1e18,s[i].clear();
        for (int i = 0;i < sz;++i)
            edges[where[i]][2] = k / sz + (k % sz < i);
        for (auto it : edges)
            s[it[0]].push_back({it[1],it[2]}),
            s[it[1]].push_back({it[0],it[2]});
        D[u] = 0;
        priority_queue < pair < int , int > , vector < pair < int , int > > , greater < pair < int , int > > > Q;
        Q.push({0,u});
        while (!Q.empty())
        {
            int node = Q.top().y;
            Q.pop();
            for (auto it : s[node])
                if (D[it.x] > D[node] + it.y)
                    D[it.x] = D[node] + it.y,Q.push({D[it.x],it.x});
        }
        return D[v];
    };
    if (f(sz) > L || f(1ll * sz * oo) < L) return puts("No") * 0;
    ll ans = 0;
    for (ll k = 1ll << 60;k;k /= 2)
        if (ans + k <= 1ll * sz * oo && f(ans + k) <= L)
            ans += k;
    f(ans);
    puts("Yes");
    for (auto it : edges)
        fo << it[0] << ' ' << it[1] << ' ' << it[2] << '\n';
    cerr << "Time elapsed :" << clock() * 1000.0 / CLOCKS_PER_SEC << " ms" << '\n';
    return 0;
}


# include <stdio.h>
# include <bits/stdc++.h>
using namespace std;
# define fi cin
# define fo cout
# define x first
# define y second
# define ll long long
# define IOS ios_base :: sync_with_stdio(0);cin.tie(0)
# define p(v) cerr << #v << " = " << v << '\n'
# define p2(v) cerr << #v << " = " << (complex < int > (v.x,v.y)) << '\n'
# define vi vector < int >
# define vll vector < ll >
# define pii pair < int , int >
//# pragma GCC target ("sse4")
# define mp make_pair
int main(void)
{
    #ifdef CF
    freopen("input","r",stdin);
    #endif // CF
    srand(time(0));
    fo << fixed << setprecision(7);
    cerr << fixed << setprecision(7);
    int n,m,L,u,v;
    IOS;
    fi>>n>>m>>L>>u>>v;
    vector < vector < int > > edges;
    vector < int > where;
    ++u;++v;
    for (int i = 0;i < m;++i)
    {
        int a,b,c;
        fi>>a>>b>>c;
        ++a;++b;
        if (!c) where.push_back(i);
        edges.push_back({a,b,c});
    }
    static vector < pair < int , int > > s[1 << 20];
    static ll D[1 << 20];
    const int oo = 2e9 + 55;
    const int sz = where.size();
    auto f = [&](ll k)
    {
        for (int i = 1;i <= n;++i) D[i] = 1e18,s[i].clear();
        for (int i = 0;i < sz;++i)
            edges[where[i]][2] = k / sz + (i < k % sz);
        for (auto it : edges)
            s[it[0]].push_back({it[1],it[2]}),
            s[it[1]].push_back({it[0],it[2]});
        D[u] = 0;
        priority_queue < pair < int , int > , vector < pair < int , int > > , greater < pair < int , int > > > Q;
        Q.push({0,u});
        while (!Q.empty())
        {
            int node = Q.top().y;
            Q.pop();
            for (auto it : s[node])
                if (D[it.x] > D[node] + it.y)
                    D[it.x] = D[node] + it.y,Q.push({D[it.x],it.x});
        }
        return D[v];
    };
    if (f(sz) > L || f(1ll * sz * oo) < L) return puts("NO") * 0;
    ll ans = 0;
    for (ll k = 1ll << 60;k;k /= 2)
        if (ans + k <= 1ll * sz * oo && f(ans + k) <= L)
            ans += k;
    f(ans);
    fo << "YES\n";
    for (auto it : edges)
        fo << it[0] - 1 << ' ' << it[1] - 1 << ' ' << it[2] << '\n';
    cerr << "Time elapsed :" << clock() * 1000.0 / CLOCKS_PER_SEC << " ms" << '\n';
    return 0;
}


# include <stdio.h>
# include <bits/stdc++.h>
using namespace std;
# define fi cin
# define fo cout
# define x first
# define y second
# define ll long long
# define IOS ios_base :: sync_with_stdio(0);cin.tie(0)
# define p(v) cerr << #v << " = " << v << '\n'
# define p2(v) cerr << #v << " = " << (complex < int > (v.x,v.y)) << '\n'
# define vi vector < int >
# define vll vector < ll >
# define pii pair < int , int >
//# pragma GCC target ("sse4")
# define mp make_pair
int main(void)
{
    #ifdef CF
    freopen("input.in","r",stdin);
    #endif // CF
    int n,m,L,l,r;
    IOS;
    fi>>n>>m>>L>>l>>r;
    static vector < pii > s[1 << 20];
    vector < vector < int > > edges;
    ++l;++r;
    for (int i = 1;i <= m;++i)
    {
        int a,b,c;
        fi>>a>>b>>c;
        ++a;++b;
        edges.push_back({a,b,c});
        if (c)
            s[a].push_back({b,c}),
            s[b].push_back({a,c});
        else
            s[a].push_back({b,1}),
            s[b].push_back({a,1});
    }
    static ll D1[1 << 20];
    static ll D2[1 << 20];
    static ll F[1 << 20];
    priority_queue < pair < ll , int > , vector < pair < ll , int > > , greater < pair < ll , int > > > Q;
    for (int i = 1;i <= n;++i) D1[i] = D2[i] = 1e18;
    D1[l] = 0;
    Q.push({0,l});
    while (!Q.empty())
    {
        int node = Q.top().y;
        Q.pop();
        for (auto it : s[node])
            if (D1[it.x] > D1[node] + it.y)
                D1[it.x] = D1[node] + it.y,Q.push({D1[it.x],it.x});
    }
    D2[r] = 0;
    Q.push({0,r});
    while (!Q.empty())
    {
        int node = Q.top().y;
        Q.pop();
        for (auto it : s[node])
            if (D2[it.x] > D2[node] + it.y)
                D2[it.x] = D2[node] + it.y,Q.push({D2[it.x],it.x});
    }
    for (int i = 1;i <= n;++i) s[i].clear();
    vector < vi > now;
    for (auto it : edges)
        if (it[2])
            now.push_back(it);
    for (auto & it : edges)
    if (!it[2])
    {
        for (int w = 0;w < 2;++w)
        {
            swap(it[0],it[1]);
            if (L > D1[it[0]] + D2[it[1]])
            {
                now.push_back({it[0],it[1],(int)(L - D1[it[0]] - D2[it[1]])});
                for (int i = 1;i <= n;++i) s[i].clear(),F[i] = 1e18;
                for (auto it : now)
                    s[it[0]].push_back({it[1],it[2]}),
                    s[it[1]].push_back({it[0],it[2]});
                priority_queue < pair < ll , int > , vector < pair < ll , int > > , greater < pair < ll , int > > > Q;
                F[l] = 0;
                Q.push({0,l});
                while (!Q.empty())
                {
                    int node = Q.top().y;
                    Q.pop();
                    for (auto it : s[node])
                        if (F[it.x] > F[node] + it.y)
                            F[it.x] = F[node] + it.y,Q.push({F[it.x],it.x});
                }
                if (F[r] == L)
                {
                    fo << "YES\n";
                    it[2] = L - D1[it[0]] - D2[it[1]];
                    if (!w) swap(it[0],it[1]);
                    for (auto x : edges)
                        fo << x[0] - 1 << ' ' << x[1] - 1 << ' ' << (!x[2] ? (ll)(1e18) : x[2]) << '\n';
                    return 0;
                }
            }
        }
    }
    fo << "NO\n";
    return 0;
}


# include <stdio.h>
# include <bits/stdc++.h>
using namespace std;
# define fi cin
# define fo cout
# define x first
# define y second
# define ll long long
# define IOS ios_base :: sync_with_stdio(0);cin.tie(0)
# define p(v) cerr << #v << " = " << v << '\n'
# define p2(v) cerr << #v << " = " << (complex < int > (v.x,v.y)) << '\n'
# define vi vector < int >
# define vll vector < ll >
# define pii pair < int , int >
//# pragma GCC target ("sse4")
# define mp make_pair
int main(void)
{
    #ifdef CF
    freopen("input","r",stdin);
    #endif // CF
    srand(time(0));
    fo << fixed << setprecision(7);
    cerr << fixed << setprecision(7);
    int n,m,L,u,v;
    IOS;
    fi>>n>>m>>L>>u>>v;
    vector < vector < int > > edges;
    vector < int > where;
    ++u;++v;
    for (int i = 0;i < m;++i)
    {
        int a,b,c;
        fi>>a>>b>>c;
        ++a;++b;
        if (!c) where.push_back(i);
        edges.push_back({a,b,c});
    }
    static vector < pair < int , int > > s[1 << 20];
    static ll D[1 << 20];
    const int oo = 2e9 + 55;
    const int sz = where.size();
    auto f = [&](ll k)
    {
        for (int i = 1;i <= n;++i) D[i] = 1e18,s[i].clear();
        for (int i = 0;i < sz;++i)
            edges[where[i]][2] = k / sz + (k % sz < i);
        for (auto it : edges)
            s[it[0]].push_back({it[1],it[2]}),
            s[it[1]].push_back({it[0],it[2]});
        D[u] = 0;
        priority_queue < pair < int , int > , vector < pair < int , int > > , greater < pair < int , int > > > Q;
        Q.push({0,u});
        while (!Q.empty())
        {
            int node = Q.top().y;
            Q.pop();
            for (auto it : s[node])
                if (D[it.x] > D[node] + it.y)
                    D[it.x] = D[node] + it.y,Q.push({D[it.x],it.x});
        }
        return D[v];
    };
    if (f(sz) > L || f(1ll * sz * oo) < L) return puts("NO") * 0;
    ll ans = 0;
    for (ll k = 1ll << 60;k;k /= 2)
        if (ans + k <= 1ll * sz * oo && f(ans + k) <= L)
            ans += k;
    f(ans);
    fo << "YES\n";
    for (auto it : edges)
        fo << it[0] - 1 << ' ' << it[1] - 1 << ' ' << it[2] << '\n';
    cerr << "Time elapsed :" << clock() * 1000.0 / CLOCKS_PER_SEC << " ms" << '\n';
    return 0;
}


# include <stdio.h>
# include <bits/stdc++.h>
using namespace std;
# define fi cin
# define fo cout
# define x first
# define y second
# define ll long long
# define IOS ios_base :: sync_with_stdio(0);cin.tie(0)
# define p(v) cerr << #v << " = " << v << '\n'
# define p2(v) cerr << #v << " = " << (complex < int > (v.x,v.y)) << '\n'
# define vi vector < int >
# define vll vector < ll >
# define pii pair < int , int >
//# pragma GCC target ("sse4")
# define mp make_pair
int main(void)
{
    #ifdef CF
    freopen("input","r",stdin);
    #endif // CF
    srand(time(0));
    fo << fixed << setprecision(7);
    cerr << fixed << setprecision(7);
    int n,m,L,u,v;
    IOS;
    fi>>n>>m>>L>>u>>v;
    vector < vector < int > > edges;
    vector < int > where;
    ++u;++v;
    for (int i = 0;i < m;++i)
    {
        int a,b,c;
        fi>>a>>b>>c;
        ++a;++b;
        if (!c) where.push_back(i);
        edges.push_back({a,b,c});
    }
    static vector < pair < int , int > > s[1 << 20];
    static ll D[1 << 20];
    const int oo = 2e9 + 55;
    const int sz = where.size();
    auto f = [&](ll k)
    {
        for (int i = 1;i <= n;++i) D[i] = 1e18,s[i].clear();
        for (int i = 0;i < sz;++i)
            edges[where[i]][2] = k / sz + (k % sz < i);
        for (auto it : edges)
            s[it[0]].push_back({it[1],it[2]}),
            s[it[1]].push_back({it[0],it[2]});
        D[u] = 0;
        priority_queue < pair < int , int > , vector < pair < int , int > > , greater < pair < int , int > > > Q;
        Q.push({0,u});
        while (!Q.empty())
        {
            int node = Q.top().y;
            Q.pop();
            for (auto it : s[node])
                if (D[it.x] > D[node] + it.y)
                    D[it.x] = D[node] + it.y,Q.push({D[it.x],it.x});
        }
        return D[v];
    };
    if (f(sz) > L || f(1ll * sz * oo) < L) return puts("NO") * 0;
    ll ans = 0;
    for (ll k = 1ll << 60;k;k /= 2)
        if (ans + k <= 1ll * sz * oo && f(ans + k) <= L)
            ans += k;
    f(ans);
    puts("YES");
    for (auto it : edges)
        fo << it[0] << ' ' << it[1] << ' ' << it[2] << '\n';
    cerr << "Time elapsed :" << clock() * 1000.0 / CLOCKS_PER_SEC << " ms" << '\n';
    return 0;
}


# include <stdio.h>
# include <bits/stdc++.h>
using namespace std;
# define fi cin
# define fo cout
# define x first
# define y second
# define ll long long
# define IOS ios_base :: sync_with_stdio(0);cin.tie(0)
# define p(v) cerr << #v << " = " << v << '\n'
# define p2(v) cerr << #v << " = " << (complex < int > (v.x,v.y)) << '\n'
# define vi vector < int >
# define vll vector < ll >
# define pii pair < int , int >
//# pragma GCC target ("sse4")
# define mp make_pair
int main(void)
{
    #ifdef CF
    freopen("input","r",stdin);
    #endif // CF
    srand(time(0));
    fo << fixed << setprecision(7);
    cerr << fixed << setprecision(7);
    int n,m,L,u,v;
    IOS;
    fi>>n>>m>>L>>u>>v;
    vector < vector < int > > edges;
    vector < int > where;
    ++u;++v;
    for (int i = 0;i < m;++i)
    {
        int a,b,c;
        fi>>a>>b>>c;
        ++a;++b;
        if (!c) where.push_back(i);
        edges.push_back({a,b,c});
    }
    static vector < pair < int , int > > s[1 << 20];
    static ll D[1 << 20];
    const int oo = 2e9 + 55;
    const int sz = where.size();
    auto f = [&](ll k)
    {
        for (int i = 1;i <= n;++i) D[i] = 1e18,s[i].clear();
        for (int i = 0;i < sz;++i)
            edges[where[i]][2] = k / sz + (k % sz < i);
        for (auto it : edges)
            s[it[0]].push_back({it[1],it[2]}),
            s[it[1]].push_back({it[0],it[2]});
        D[u] = 0;
        priority_queue < pair < int , int > , vector < pair < int , int > > , greater < pair < int , int > > > Q;
        Q.push({0,u});
        while (!Q.empty())
        {
            int node = Q.top().y;
            Q.pop();
            for (auto it : s[node])
                if (D[it.x] > D[node] + it.y)
                    D[it.x] = D[node] + it.y,Q.push({D[it.x],it.x});
        }
        return D[v];
    };
    if (f(sz) > L || f(1ll * sz * oo) < L) return puts("NO") * 0;
    ll ans = 0;
    for (ll k = 1ll << 60;k;k /= 2)
        if (ans + k <= 1ll * sz * oo && f(ans + k) <= L)
            ans += k;
    f(ans);
    fo << "YES\n";
    for (auto it : edges)
        fo << it[0] << ' ' << it[1] << ' ' << it[2] << '\n';
    cerr << "Time elapsed :" << clock() * 1000.0 / CLOCKS_PER_SEC << " ms" << '\n';
    return 0;
}


# include <stdio.h>
# include <bits/stdc++.h>
using namespace std;
# define fi cin
# define fo cout
# define x first
# define y second
# define ll long long
# define IOS ios_base :: sync_with_stdio(0);cin.tie(0)
# define p(v) cerr << #v << " = " << v << '\n'
# define p2(v) cerr << #v << " = " << (complex < int > (v.x,v.y)) << '\n'
# define vi vector < int >
# define vll vector < ll >
# define pii pair < int , int >
//# pragma GCC target ("sse4")
# define mp make_pair
int main(void)
{
    #ifdef CF
    freopen("input.in","r",stdin);
    #endif // CF
    int n,m,L,l,r;
    IOS;
    fi>>n>>m>>L>>l>>r;
    static vector < pii > s[1 << 20];
    vector < vector < int > > edges;
    ++l;++r;
    for (int i = 1;i <= m;++i)
    {
        int a,b,c;
        fi>>a>>b>>c;
        ++a;++b;
        edges.push_back({a,b,c});
        if (c)
            s[a].push_back({b,c}),
            s[b].push_back({a,c});
    }
    static ll D1[1 << 20];
    static ll D2[1 << 20];
    static ll F[1 << 20];
    priority_queue < pair < ll , int > , vector < pair < ll , int > > , greater < pair < ll , int > > > Q;
    for (int i = 1;i <= n;++i) D1[i] = D2[i] = 1e18;
    D1[l] = 0;
    Q.push({0,l});
    while (!Q.empty())
    {
        int node = Q.top().y;
        Q.pop();
        for (auto it : s[node])
            if (D1[it.x] > D1[node] + it.y)
                D1[it.x] = D1[node] + it.y,Q.push({D1[it.x],it.x});
    }
    D2[r] = 0;
    Q.push({0,r});
    while (!Q.empty())
    {
        int node = Q.top().y;
        Q.pop();
        for (auto it : s[node])
            if (D2[it.x] > D2[node] + it.y)
                D2[it.x] = D2[node] + it.y,Q.push({D2[it.x],it.x});
    }
    for (int i = 1;i <= n;++i) s[i].clear();
    vector < vi > now;
    for (auto it : edges)
        if (it[2])
            now.push_back(it);
    for (auto & it : edges)
    if (!it[2])
    {
        for (int w = 0;w < 2;++w)
        {
            swap(it[0],it[1]);
            if (L > D1[it[0]] + D2[it[1]])
            {
                now.push_back({it[0],it[1],(int)(L - D1[it[0]] - D2[it[1]])});
                for (int i = 1;i <= n;++i) s[i].clear(),F[i] = 1e18;
                for (auto it : now)
                    s[it[0]].push_back({it[1],it[2]}),
                    s[it[1]].push_back({it[0],it[2]});
                priority_queue < pair < ll , int > , vector < pair < ll , int > > , greater < pair < ll , int > > > Q;
                F[l] = 0;
                Q.push({0,l});
                while (!Q.empty())
                {
                    int node = Q.top().y;
                    Q.pop();
                    for (auto it : s[node])
                        if (F[it.x] > F[node] + it.y)
                            F[it.x] = F[node] + it.y,Q.push({F[it.x],it.x});
                }
                if (F[r] == L)
                {
                    fo << "YES\n";
                    it[2] = L - D1[it[0]] - D2[it[1]];
                    if (!w) swap(it[0],it[1]);
                    for (auto x : edges)
                        fo << x[0] - 1 << ' ' << x[1] - 1 << ' ' << (!x[2] ? (ll)(1e18) : x[2]) << '\n';
                    return 0;
                }
            }
        }
    }
    fo << "NO\n";
    return 0;
}


# include <stdio.h>
# include <bits/stdc++.h>
using namespace std;
# define fi cin
# define fo cout
# define x first
# define y second
# define ll long long
# define IOS ios_base :: sync_with_stdio(0);cin.tie(0)
# define p(v) cerr << #v << " = " << v << '\n'
# define p2(v) cerr << #v << " = " << (complex < int > (v.x,v.y)) << '\n'
# define vi vector < int >
# define vll vector < ll >
# define pii pair < int , int >
//# pragma GCC target ("sse4")
# define mp make_pair
int main(void)
{
    #ifdef CF
    freopen("input.in","r",stdin);
    #endif // CF
    int n,m,L,l,r;
    IOS;
    fi>>n>>m>>L>>l>>r;
    static vector < pii > s[1 << 20];
    vector < vector < int > > edges;
    ++l;++r;
    for (int i = 1;i <= m;++i)
    {
        int a,b,c;
        fi>>a>>b>>c;
        ++a;++b;
        edges.push_back({a,b,c});
        if (c)
            s[a].push_back({b,c}),
            s[b].push_back({a,c});
    }
    vector < vi > now;
    static int f[1 << 20];
    for (int i = 1;i <= n;++i) f[i] = i;
    function < int(int) > get = [&](int k)
    {
        return k == f[k] ? k : f[k] = get(f[k]);
    };
    for (auto it : edges)
        if (it[2])
            now.push_back(it);
    for (auto it : now)
        f[get(it[0])] = get(it[1]);
    for (auto it : edges)
        if (!it[2] && get(it[0]) != get(it[1]))
            s[it[0]].push_back({it[1],1}),
            s[it[1]].push_back({it[0],1}),
            f[get(it[0])] = get(it[1]);
    static ll D1[1 << 20];
    static ll D2[1 << 20];
    static ll F[1 << 20];
    priority_queue < pair < ll , int > , vector < pair < ll , int > > , greater < pair < ll , int > > > Q;
    for (int i = 1;i <= n;++i) D1[i] = D2[i] = 1e18;
    D1[l] = 0;
    Q.push({0,l});
    while (!Q.empty())
    {
        int node = Q.top().y;
        Q.pop();
        for (auto it : s[node])
            if (D1[it.x] > D1[node] + it.y)
                D1[it.x] = D1[node] + it.y,Q.push({D1[it.x],it.x});
    }
    D2[r] = 0;
    Q.push({0,r});
    while (!Q.empty())
    {
        int node = Q.top().y;
        Q.pop();
        for (auto it : s[node])
            if (D2[it.x] > D2[node] + it.y)
                D2[it.x] = D2[node] + it.y,Q.push({D2[it.x],it.x});
    }
    for (int i = 1;i <= n;++i) s[i].clear();
    for (auto & it : edges)
    if (!it[2])
    {
        for (int w = 0;w < 2;++w)
        {
            swap(it[0],it[1]);
            if (L > D1[it[0]] + D2[it[1]])
            {
                vector < vi > now;
                now.push_back({it[0],it[1],(int)(L - D1[it[0]] - D2[it[1]])});
                for (auto it : edges)
                    if (it[2])
                        now.push_back(it);
                for (int i = 1;i <= n;++i) f[i] = i;
                for (auto it : now)
                    f[get(it[0])] = get(it[1]);
                for (auto it : now)
                for (int i = 1;i <= n;++i) s[i].clear(),F[i] = 1e18;
                for (auto it : now)
                    s[it[0]].push_back({it[1],it[2]}),
                    s[it[1]].push_back({it[0],it[2]});
                 for (auto it : edges)
                    if (!it[2] && get(it[0]) != get(it[1]))
                        s[it[0]].push_back({it[1],1}),
                        s[it[1]].push_back({it[0],1}),
                        f[get(it[0])] = get(it[1]);
                priority_queue < pair < ll , int > , vector < pair < ll , int > > , greater < pair < ll , int > > > Q;
                F[l] = 0;
                Q.push({0,l});
                while (!Q.empty())
                {
                    int node = Q.top().y;
                    Q.pop();
                    for (auto it : s[node])
                        if (F[it.x] > F[node] + it.y)
                            F[it.x] = F[node] + it.y,Q.push({F[it.x],it.x});
                }
                if (F[r] == L)
                {
                    fo << "YES\n";
                    it[2] = L - D1[it[0]] - D2[it[1]];
                    if (!w) swap(it[0],it[1]);
                    for (auto x : edges)
                        fo << x[0] - 1 << ' ' << x[1] - 1 << ' ' << (!x[2] ? (ll)(1e18) : x[2]) << '\n';
                    return 0;
                }
            }
        }
    }
    fo << "NO\n";
    return 0;
}


/*************************************************************************
    > In god we trust
    > File Name: B.cpp
************************************************************************/
const bool debug = false;
#include <cstdio>
#include <iostream>
#include <cmath>
#include <stack>
#include <queue>
#include <climits>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <algorithm>
#include <stdarg.h>
using namespace std;
#define per(i,a,n) for(int i=n-1;i>=a;--i)
#define rep(i,a,n) for(int i=a;i<n;++i)
#define erep(i,a,n) for(int i=a;i<=n;++i)
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> PII;
#define lc(o) (o<<1)
#define rc(o) (o<<1|1)
ll powmod(ll a,ll b, ll MOD) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void buginfo(const char* f, ...) {if(!debug)return;va_list al; va_start(al, f);vprintf(f, al);va_end(al);}
/*------------------ head-------------------*/
const int maxn = 1e3 + 10;
const ll inf = 1ll<<60;
const int maxw = 1e9+10;
int n, m, L, s, t;

struct Edge {
    int from, to, w;
};

struct HeapNode {
    ll d;
    int u;
    bool operator < (const HeapNode& rhs) const {
        return d > rhs.d;
    }
};

struct Dijkstra {
    int n, m, p[maxn];
    ll d[maxn];
    vector<Edge> edges;
    vector<int> G[maxn];
    vector<int> zeros; /*edges with zeros*/
    bool done[maxn];

    void init(int n) {
        this->n = n;
        rep(i, 0, n) G[i].clear();
        edges.clear();
    }

    void setw(int x) {
        for(int i: zeros) {
            edges[i].w = x;
        }
    }

    void add_edge(int from, int to, int w) {
        edges.pb((Edge){from, to, w});
        edges.pb((Edge){to, from, w});
        m = edges.size();
        G[from].pb(m-2);
        G[to].pb(m-1);
        if (w == 0) { zeros.pb(m-1); zeros.pb(m-2);}
    }

    int dijkstra(int s, int t) {
        priority_queue<HeapNode> Q;
        rep(i, 0, n) d[i] = inf;
        d[s] = 0;
        memset(done, 0, sizeof(done));
        Q.push((HeapNode){0, s});
        while(!Q.empty()) {
            HeapNode x = Q.top(); Q.pop();
            int u = x.u;
            if (done[u]) continue;
            done[u] = true;
            rep(i, 0, G[u].size()) {
                Edge& e = edges[G[u][i]];
                if (d[e.to] > d[u] + e.w) {
                    d[e.to] = d[u] + e.w;
                    p[e.to] = G[u][i];
                    Q.push((HeapNode){d[e.to], e.to});
                }
            }
        }
        return d[t];
    }

    void ksprint() {
        printf("YES\n");
        for(int i=0; i<edges.size(); i+=2) {
            Edge& e = edges[i];
            printf("%d %d %d\n", e.from, e.to, e.w);
        }
    }
} sp;

int main() {
#ifdef ROACH_ONLINE_JUDGE
    freopen("B.txt", "r", stdin);
#endif
    scanf("%d%d%d%d%d", &n, &m, &L, &s, &t);
    sp.init(n);
    rep(i, 0, m) {
        int d1, d2, d3; scanf("%d%d%d", &d1, &d2, &d3);
        sp.add_edge(d1, d2, d3);
    }

    sp.setw(0);
    if (sp.dijkstra(s, t) > L) return 0*printf("NO\n");
    sp.setw(maxw);
    if (sp.dijkstra(s, t) < L) return 0*printf("NO\n");

    int fst = 0, lst = maxw;
    while(fst < lst) {
        int md = (fst+lst)/2;
        sp.setw(md);
        int j = sp.dijkstra(s, t);
        if (j==L)
        { sp.ksprint(); return 0;}
        else if (j<L) {
            fst = md + 1;
        } else {
            lst = md;
        }
    }

    sp.setw(fst);
    if (sp.dijkstra(s, t) != L) printf("NO\n");

    return 0;
}


/*************************************************************************
  > In god we trust
  > File Name: B.cpp
 ************************************************************************/
const bool debug = false;
#include <cstdio>
#include <iostream>
#include <cmath>
#include <stack>
#include <queue>
#include <assert.h>
#include <climits>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <algorithm>
#include <stdarg.h>
using namespace std;
#define per(i,a,n) for(int i=n-1;i>=a;--i)
#define rep(i,a,n) for(int i=a;i<n;++i)
#define erep(i,a,n) for(int i=a;i<=n;++i)
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> PII;
#define lc(o) (o<<1)
#define rc(o) (o<<1|1)
ll powmod(ll a,ll b, ll MOD) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void buginfo(const char* f, ...) {if(!debug)return;va_list al; va_start(al, f);vprintf(f, al);va_end(al);}
/*------------------ head-------------------*/
const int maxn = 1e3 + 10;
const ll inf = 1e15;
const ll maxw = 1e9;
int n, m, L, s, t;

struct Edge {
    int from, to;
    ll w;
};

struct HeapNode {
    ll d;
    int u;
    bool operator < (const HeapNode& rhs) const {
        return d > rhs.d;
    }
};

struct Dijkstra {
    int n, m, p[maxn], s, t;
    bool done[maxn];
    ll d[maxn];
    vector<Edge> edges;
    vector<int> G[maxn], G1[maxn];
    vector<int> zeros; /*edges with zeros*/

    void init(int n, int s, int t) {
        this->n = n;
        rep(i, 0, n) G[i].clear();
        edges.clear();
        this->s = s;
        this->t = t;
    }

    void add_edge(int from, int to, ll w) {
        bool z = (w==0);
        w = max(1ll, w);
        edges.pb((Edge){from, to, w});
        edges.pb((Edge){to, from, w});
        m = edges.size();
        G[from].pb(m-2);
        G[to].pb(m-1);
        if (z) {
            zeros.pb(m-1); zeros.pb(m-2);
        }
    }

    ll dijkstra() {
        priority_queue<HeapNode> Q;
        rep(i, 0, n) d[i] = inf;
        d[s] = 0;
        memset(done, 0, sizeof(done));
        Q.push((HeapNode){0, s});
        while(!Q.empty()) {
            HeapNode x = Q.top(); Q.pop();
            int u = x.u;
            if (done[u]) continue;
            done[u] = true;
            rep(i, 0, G[u].size()) {
                Edge& e = edges[G[u][i]];
                if (d[e.to] > d[u] + e.w) {
                    d[e.to] = d[u] + e.w;
                    p[e.to] = G[u][i];
                    Q.push((HeapNode){d[e.to], e.to});
                }
            }
        }
        return d[t];
    }

    void ksprint() {
        printf("YES\n");
        for(int i=0; i<edges.size(); i+=2) {
            Edge& e = edges[i];
            printf("%d %d %lld\n", e.from, e.to, e.w);
        }
    }

    ll check(ll sum) {
        for(int i: zeros) {
            edges[i^1].w = edges[i].w = min(maxw, sum);
            sum -= edges[i].w - 1;
        }
        return dijkstra();
    }
} sp;

int main() {
#ifdef ROACH_ONLINE_JUDGE
    freopen("B.txt", "r", stdin);
#endif
    scanf("%d%d%d%d%d", &n, &m, &L, &s, &t);
    sp.init(n, s, t);
    rep(i, 0, m) {
        int d1, d2, d3; scanf("%d%d%d", &d1, &d2, &d3);
        sp.add_edge(d1, d2, d3);
    }

    ll l = (ll)sp.zeros.size(), r = inf;
    if (sp.check(l) > L || sp.check(r) < L)
        return 0 * printf("NO\n");

    while(l<r) {
        ll md = (l+r)/2;
        ll now = sp.check(md);
        if (now == L) {
            sp.ksprint();
            return 0;
        }
        else if (now < L) l = md+1;
        else r = md;
    }

    return 0;
}


/*************************************************************************
    > In god we trust
    > File Name: B.cpp
************************************************************************/
const bool debug = false;
#include <cstdio>
#include <iostream>
#include <cmath>
#include <stack>
#include <queue>
#include <climits>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <algorithm>
#include <stdarg.h>
using namespace std;
#define per(i,a,n) for(int i=n-1;i>=a;--i)
#define rep(i,a,n) for(int i=a;i<n;++i)
#define erep(i,a,n) for(int i=a;i<=n;++i)
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> PII;
#define lc(o) (o<<1)
#define rc(o) (o<<1|1)
ll powmod(ll a,ll b, ll MOD) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void buginfo(const char* f, ...) {if(!debug)return;va_list al; va_start(al, f);vprintf(f, al);va_end(al);}
/*------------------ head-------------------*/
const int maxn = 1e3 + 10;
const ll inf = 1ll<<60;
const int maxw = 1e18+10;
int n, m, L, s, t;

struct Edge {
    int from, to;
    ll w;
};

struct HeapNode {
    ll d;
    int u;
    bool operator < (const HeapNode& rhs) const {
        return d > rhs.d;
    }
};

struct Dijkstra {
    int n, m, p[maxn];
    ll d[maxn];
    vector<Edge> edges;
    vector<int> G[maxn];
    vector<int> zeros; /*edges with zeros*/
    bool done[maxn];

    void init(int n) {
        this->n = n;
        rep(i, 0, n) G[i].clear();
        edges.clear();
    }

    void setw(ll x) {
        for(int i: zeros) {
            edges[i].w = x;
        }
    }

    void add_edge(int from, int to, ll w) {
        edges.pb((Edge){from, to, w});
        edges.pb((Edge){to, from, w});
        m = edges.size();
        G[from].pb(m-2);
        G[to].pb(m-1);
        if (w == 0) { zeros.pb(m-1); zeros.pb(m-2);}
    }

    ll dijkstra(int s, int t) {
        priority_queue<HeapNode> Q;
        rep(i, 0, n) d[i] = inf;
        d[s] = 0;
        memset(done, 0, sizeof(done));
        Q.push((HeapNode){0, s});
        while(!Q.empty()) {
            HeapNode x = Q.top(); Q.pop();
            int u = x.u;
            if (done[u]) continue;
            done[u] = true;
            rep(i, 0, G[u].size()) {
                Edge& e = edges[G[u][i]];
                if (d[e.to] > d[u] + e.w) {
                    d[e.to] = d[u] + e.w;
                    p[e.to] = G[u][i];
                    Q.push((HeapNode){d[e.to], e.to});
                }
            }
        }
        return d[t];
    }

    void ksprint() {
        printf("YES\n");
        for(int i=0; i<edges.size(); i+=2) {
            Edge& e = edges[i];
            printf("%d %d %lld\n", e.from, e.to, e.w);
        }
    }
} sp;

int main() {
#ifdef ROACH_ONLINE_JUDGE
    freopen("B.txt", "r", stdin);
#endif
    scanf("%d%d%d%d%d", &n, &m, &L, &s, &t);
    sp.init(n);
    rep(i, 0, m) {
        int d1, d2, d3; scanf("%d%d%d", &d1, &d2, &d3);
        sp.add_edge(d1, d2, d3);
    }

    /*sp.setw(0);
    if (sp.dijkstra(s, t) > L) return 0*printf("NO\n");
    sp.setw(maxw);
    if (sp.dijkstra(s, t) < L) return 0*printf("NO\n");*/

    ll fst = 0, lst = maxw;
    while(fst < lst) {
        ll md = (fst+lst)/2;
        sp.setw(md);
        ll j = sp.dijkstra(s, t);
        if (j==L)
        { sp.ksprint(); return 0;}
        else if (j<L) {
            fst = md + 1;
        } else {
            lst = md;
        }
    }

    sp.setw(fst);
    if (sp.dijkstra(s, t) != L) printf("NO\n");

    return 0;
}


/*************************************************************************
    > In god we trust
    > File Name: B.cpp
************************************************************************/
const bool debug = false;
#include <cstdio>
#include <iostream>
#include <cmath>
#include <stack>
#include <queue>
#include <assert.h>
#include <climits>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <algorithm>
#include <stdarg.h>
using namespace std;
#define per(i,a,n) for(int i=n-1;i>=a;--i)
#define rep(i,a,n) for(int i=a;i<n;++i)
#define erep(i,a,n) for(int i=a;i<=n;++i)
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> PII;
#define lc(o) (o<<1)
#define rc(o) (o<<1|1)
ll powmod(ll a,ll b, ll MOD) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void buginfo(const char* f, ...) {if(!debug)return;va_list al; va_start(al, f);vprintf(f, al);va_end(al);}
/*------------------ head-------------------*/
const int maxn = 1e3 + 10;
const ll inf = 1ll<<60;
const ll maxw = 1e15+10;
int n, m, L, s, t;

struct Edge {
    int from, to;
    ll w;
};

struct HeapNode {
    ll d;
    int u;
    bool operator < (const HeapNode& rhs) const {
        return d > rhs.d;
    }
};

struct Dijkstra {
    int n, m, p[maxn];
    bool done[maxn];
    ll d[maxn];
    vector<Edge> edges;
    vector<int> G[maxn];
    vector<int> zeros; /*edges with zeros*/

    void init(int n) {
        this->n = n;
        rep(i, 0, n) G[i].clear();
        edges.clear();
    }

    void setw(ll x) {
        for(int i: zeros) {
            edges[i].w = x;
        }
    }

    void add_edge(int from, int to, ll w) {
        edges.pb((Edge){from, to, w});
        edges.pb((Edge){to, from, w});
        m = edges.size();
        G[from].pb(m-2);
        G[to].pb(m-1);
        if (w == 0) { zeros.pb(m-1); zeros.pb(m-2);}
    }

    ll dijkstra(int s, int t) {
        priority_queue<HeapNode> Q;
        rep(i, 0, n) d[i] = inf;
        d[s] = 0;
        memset(done, 0, sizeof(done));
        Q.push((HeapNode){0, s});
        while(!Q.empty()) {
            HeapNode x = Q.top(); Q.pop();
            int u = x.u;
            if (done[u]) continue;
            done[u] = true;
            rep(i, 0, G[u].size()) {
                Edge& e = edges[G[u][i]];
                if (d[e.to] > d[u] + e.w) {
                    d[e.to] = d[u] + e.w;
                    p[e.to] = G[u][i];
                    Q.push((HeapNode){d[e.to], e.to});
                }
            }
        }
        return d[t];
    }

    set<int> getpath(int s, int t) {
        set<int> path;
        int x = t;
        while(1) {
            path.insert(x);
            int fa = edges[x].from;
            if (fa == s) break;
            x = p[fa];
        }
        return path;
    }

    void ksprint(int s, int t, ll cnt = 0) {
        set<int> path = getpath(s, t);
        printf("YES\n");
        for(int i=0; i<edges.size(); i+=2) {
            Edge& e = edges[i];
            if (cnt > 0 && path.count(i) > 0) {
                ++e.w; --cnt;
            }
            printf("%d %d %lld\n", e.from, e.to, e.w);
        }
    }
} sp;

int main() {
#ifdef ROACH_ONLINE_JUDGE
    freopen("B.txt", "r", stdin);
#endif
    scanf("%d%d%d%d%d", &n, &m, &L, &s, &t);
    sp.init(n);
    rep(i, 0, m) {
        int d1, d2, d3; scanf("%d%d%d", &d1, &d2, &d3);
        sp.add_edge(d1, d2, d3);
    }

    sp.setw(1);
    if (sp.dijkstra(s, t) > L) return 0*printf("NO\n");
    sp.setw(maxw);
    if (sp.dijkstra(s, t) < L) return 0*printf("NO\n");

    ll fst = 1, lst = maxw;
    while(fst < lst) {
        ll md = (fst+lst)/2;
        sp.setw(md);
        ll j = sp.dijkstra(s, t);
        if (j==L)
        { sp.ksprint(s, t); return 0;}
        else if (j<L) {
            fst = md + 1;
        } else {
            lst = md;
        }
    }

    --fst;
    sp.setw(fst);
    ll cnt = L - sp.dijkstra(s, t);
    assert(cnt > 0);
    sp.ksprint(s, t, cnt);

    return 0;
}


/*************************************************************************
    > In god we trust
    > File Name: B.cpp
************************************************************************/
const bool debug = false;
#include <cstdio>
#include <iostream>
#include <cmath>
#include <stack>
#include <queue>
#include <climits>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <algorithm>
#include <stdarg.h>
using namespace std;
#define per(i,a,n) for(int i=n-1;i>=a;--i)
#define rep(i,a,n) for(int i=a;i<n;++i)
#define erep(i,a,n) for(int i=a;i<=n;++i)
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> PII;
#define lc(o) (o<<1)
#define rc(o) (o<<1|1)
ll powmod(ll a,ll b, ll MOD) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void buginfo(const char* f, ...) {if(!debug)return;va_list al; va_start(al, f);vprintf(f, al);va_end(al);}
/*------------------ head-------------------*/
const int maxn = 1e3 + 10;
const ll inf = 1ll<<60;
const ll maxw = 1e15+10;
int n, m, L, s, t;

struct Edge {
    int from, to;
    ll w;
};

struct HeapNode {
    ll d;
    int u;
    bool operator < (const HeapNode& rhs) const {
        return d > rhs.d;
    }
};

struct Dijkstra {
    int n, m, p[maxn];
    ll d[maxn];
    vector<Edge> edges;
    vector<int> G[maxn];
    vector<int> zeros; /*edges with zeros*/
    bool done[maxn];

    void init(int n) {
        this->n = n;
        rep(i, 0, n) G[i].clear();
        edges.clear();
    }

    void setw(ll x) {
        for(int i: zeros) {
            edges[i].w = x;
        }
    }

    void add_edge(int from, int to, ll w) {
        edges.pb((Edge){from, to, w});
        edges.pb((Edge){to, from, w});
        m = edges.size();
        G[from].pb(m-2);
        G[to].pb(m-1);
        if (w == 0) { zeros.pb(m-1); zeros.pb(m-2);}
    }

    ll dijkstra(int s, int t) {
        priority_queue<HeapNode> Q;
        rep(i, 0, n) d[i] = inf;
        d[s] = 0;
        memset(done, 0, sizeof(done));
        Q.push((HeapNode){0, s});
        while(!Q.empty()) {
            HeapNode x = Q.top(); Q.pop();
            int u = x.u;
            if (done[u]) continue;
            done[u] = true;
            rep(i, 0, G[u].size()) {
                Edge& e = edges[G[u][i]];
                if (d[e.to] > d[u] + e.w) {
                    d[e.to] = d[u] + e.w;
                    p[e.to] = G[u][i];
                    Q.push((HeapNode){d[e.to], e.to});
                }
            }
        }
        return d[t];
    }

    void ksprint() {
        printf("YES\n");
        for(int i=0; i<edges.size(); i+=2) {
            Edge& e = edges[i];
            printf("%d %d %lld\n", e.from, e.to, e.w);
        }
    }
} sp;

int main() {
#ifdef ROACH_ONLINE_JUDGE
    freopen("B.txt", "r", stdin);
#endif
    scanf("%d%d%d%d%d", &n, &m, &L, &s, &t);
    sp.init(n);
    rep(i, 0, m) {
        int d1, d2, d3; scanf("%d%d%d", &d1, &d2, &d3);
        sp.add_edge(d1, d2, d3);
    }

    /*sp.setw(0);
    if (sp.dijkstra(s, t) > L) return 0*printf("NO\n");
    sp.setw(maxw);
    if (sp.dijkstra(s, t) < L) return 0*printf("NO\n");*/

    ll fst = 0, lst = maxw;
    while(fst < lst) {
        ll md = (fst+lst)/2;
        sp.setw(md);
        ll j = sp.dijkstra(s, t);
        if (j==L)
        { sp.ksprint(); return 0;}
        else if (j<L) {
            fst = md + 1;
        } else {
            lst = md;
        }
    }

    sp.setw(fst);
    if (sp.dijkstra(s, t) != L) printf("NO\n");

    return 0;
}


/*************************************************************************
    > In god we trust
    > File Name: B.cpp
************************************************************************/
const bool debug = false;
#include <cstdio>
#include <iostream>
#include <cmath>
#include <stack>
#include <queue>
#include <climits>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <algorithm>
#include <stdarg.h>
using namespace std;
#define per(i,a,n) for(int i=n-1;i>=a;--i)
#define rep(i,a,n) for(int i=a;i<n;++i)
#define erep(i,a,n) for(int i=a;i<=n;++i)
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> PII;
#define lc(o) (o<<1)
#define rc(o) (o<<1|1)
ll powmod(ll a,ll b, ll MOD) {ll res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
void buginfo(const char* f, ...) {if(!debug)return;va_list al; va_start(al, f);vprintf(f, al);va_end(al);}
/*------------------ head-------------------*/
const int maxn = 1e3 + 10;
const ll inf = 1ll<<60;
const int maxw = 1e18+10;
int n, m, L, s, t;

struct Edge {
    int from, to, w;
};

struct HeapNode {
    ll d;
    int u;
    bool operator < (const HeapNode& rhs) const {
        return d > rhs.d;
    }
};

struct Dijkstra {
    int n, m, p[maxn];
    ll d[maxn];
    vector<Edge> edges;
    vector<int> G[maxn];
    vector<int> zeros; /*edges with zeros*/
    bool done[maxn];

    void init(int n) {
        this->n = n;
        rep(i, 0, n) G[i].clear();
        edges.clear();
    }

    void setw(int x) {
        for(int i: zeros) {
            edges[i].w = x;
        }
    }

    void add_edge(int from, int to, int w) {
        edges.pb((Edge){from, to, w});
        edges.pb((Edge){to, from, w});
        m = edges.size();
        G[from].pb(m-2);
        G[to].pb(m-1);
        if (w == 0) { zeros.pb(m-1); zeros.pb(m-2);}
    }

    int dijkstra(int s, int t) {
        priority_queue<HeapNode> Q;
        rep(i, 0, n) d[i] = inf;
        d[s] = 0;
        memset(done, 0, sizeof(done));
        Q.push((HeapNode){0, s});
        while(!Q.empty()) {
            HeapNode x = Q.top(); Q.pop();
            int u = x.u;
            if (done[u]) continue;
            done[u] = true;
            rep(i, 0, G[u].size()) {
                Edge& e = edges[G[u][i]];
                if (d[e.to] > d[u] + e.w) {
                    d[e.to] = d[u] + e.w;
                    p[e.to] = G[u][i];
                    Q.push((HeapNode){d[e.to], e.to});
                }
            }
        }
        return d[t];
    }

    void ksprint() {
        printf("YES\n");
        for(int i=0; i<edges.size(); i+=2) {
            Edge& e = edges[i];
            printf("%d %d %d\n", e.from, e.to, e.w);
        }
    }
} sp;

int main() {
#ifdef ROACH_ONLINE_JUDGE
    freopen("B.txt", "r", stdin);
#endif
    scanf("%d%d%d%d%d", &n, &m, &L, &s, &t);
    sp.init(n);
    rep(i, 0, m) {
        int d1, d2, d3; scanf("%d%d%d", &d1, &d2, &d3);
        sp.add_edge(d1, d2, d3);
    }

    sp.setw(0);
    if (sp.dijkstra(s, t) > L) return 0*printf("NO\n");
    sp.setw(maxw);
    if (sp.dijkstra(s, t) < L) return 0*printf("NO\n");

    int fst = 0, lst = maxw;
    while(fst < lst) {
        int md = (fst+lst)/2;
        sp.setw(md);
        int j = sp.dijkstra(s, t);
        if (j==L)
        { sp.ksprint(); return 0;}
        else if (j<L) {
            fst = md + 1;
        } else {
            lst = md;
        }
    }

    sp.setw(fst);
    if (sp.dijkstra(s, t) != L) printf("NO\n");

    return 0;
}