#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define l(a, b, i) for (ll i = a; i < b; i++)
#define rl(a, b, i) for (ll i = a; i >= b; i--)
#define vpair vector<pair<ll, ll>>
#define inf LLONG_MAX
#define ninf LLONG_MIN
ll N, M, S, T, L, K, A, B, C;
struct Edge {
ll to, W;
};
vector<vector<Edge>> adjlist;
vector<bool> visited;
vector<ll> dist; // array này sẽ là ans của mình á :>
void dijkstra(ll start) { // lấy 1 parameter duy nhất là source node
visited.assign(N+1, false);
dist.assign(N+1, inf);
priority_queue<pair<ll, ll>, vector<pair<ll, ll>>, greater<pair<ll, ll>>> pq;
dist[start] = 0; // initialise cái path từ source node đến chính nó là 0
pq.push({0, start});
while(!pq.empty()) {
ll node = pq.top().second;
pq.pop();
if (!visited[node]) {
visited[node] = true;
for (const Edge &e : adjlist[node]) {
if (dist[e.to] > dist[node] + e.W) { // nếu path đến e.to hiện tại > path mới thì update
dist[e.to] = dist[node] + e.W;
pq.push({dist[e.to], e.to});
}
}
}
}
}
int main() {
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> N >> M >> S >> T >> L >> K;
adjlist.resize(N + 1);
l(0, M, i) {
cin >> A >> B >> C;
adjlist[A].push_back({B, C});
adjlist[B].push_back({A, C});
}
dijkstra(S);
vector<pair<ll, ll>> dist1(N + 1); // đi từ S về T
//vector<ll> distS = dist;
l(1, N + 1, i) dist1[i] = {dist[i], i};
if (dist1[T].first <= K) { // nếu chưa construct gì đã thỏa mãn thì construct kiểu quái gì cũng ok
cout << N * (N - 1) / 2;
return 0;
}
dijkstra(T);
vector<pair<ll, ll>> dist2(N + 1); // đi từ T về S
vector<ll> distT = dist; // cái vector này giữ nguyên thứ tự, nên distT[v] vẫn là shortest distance từ T đến v
l(1, N + 1, i) dist2[i] = {dist[i], i};
// Khi construct đường u <-> v thì mình sẽ đi kiểu S -> u -> v -> T
ll maxcost = K - L; // Max cost (S -> u) + (v -> T), vì mình phải chừa ít nhất cost L cho (u -> v)
sort(dist1.begin() + 1, dist1.end());
sort(dist2.begin() + 1, dist2.end());
ll ans = 0;
l(1, N + 1, i) {
if (dist1[i].first == inf) continue;
ll need = maxcost - dist1[i].first;
ll u = dist1[i].second;
if (need < 0) continue;
// pointer đến số đầu tiên trong dist[2] mà lớn hơn max length được phép của T -> v
auto pos = upper_bound(dist2.begin() + 1, dist2.end(), make_pair(need, inf));
ll cnt = pos - (dist2.begin() + 1); // đếm xem từ đầu dãy dist2 đến cái pointer đó là nhiu số
// Tại mình dùng ub á, nên có thể pos sẽ point to cái node unreachable (inf) vì nhỡ inf là số đầu tiên > need :)
//if (cnt > 0 && dist2[cnt].first > need) cnt--;
// Vì nhỡ shortest path từ T -> u <= need, nghĩa là mình đã thêm cái đường u -> u vô cnt :D
if (distT[u] <= need) cnt--;
ans += cnt;
}
cout << ans;
}