#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
const uint32_t INF = INT32_MAX;
// void PrintGraph(std::vector<std::vector<std::pair<uint32_t, uint32_t>>> graph) {
// for (int i = 0; i < graph.size(); ++i) {
// std::cout << i << " : ";
// for (int j = 0; j < graph[i].size(); ++j) {
// std::cout << graph[i][j].first << " : w = " << graph[i][j].second << ", ";
// }
// std::cout << "\n";
// }
// }
std::vector<std::vector<std::pair<uint32_t, uint32_t>>> ReverseGraph(std::vector<std::vector<std::pair<uint32_t, uint32_t>>> graph) {
std::vector<std::vector<std::pair<uint32_t, uint32_t>>> graphR(graph.size());
for (uint32_t i = 0; i < graph.size(); ++i) {
for (uint32_t j = 0; j < graph[i].size(); ++j) {
graphR[graph[i][j].first].push_back(std::make_pair(i, graph[i][j].second));
}
}
return graphR;
}
void InitializeSingleSource(uint32_t source, std::vector<uint32_t> &distances) {
for (uint32_t i = 0; i < distances.size(); ++i) {
distances[i] = INF;
}
distances[source] = 0;
}
void Relax(uint32_t u, uint32_t v, uint32_t weight,
std::set<std::pair<uint32_t, uint32_t>> &q,
std::vector<uint32_t> &distances) {
if (distances[v] > distances[u] + weight) {
q.erase(std::make_pair(distances[v], v));
distances[v] = distances[u] + weight;
q.insert(std::make_pair(distances[v], v));
}
}
void Dijkstra(std::vector<std::vector<std::pair<uint32_t, uint32_t>>> graph,
std::vector<uint32_t> &distances,
uint32_t source) {
InitializeSingleSource(source, distances);
std::set<std::pair<uint32_t, uint32_t>> q;
for (uint32_t i = 0; i < graph.size(); ++i) {
q.insert(std::make_pair(distances[i], i));
}
uint32_t u, v;
uint32_t weight;
while (!q.empty()) {
u = q.begin()->second;
q.erase(q.begin());
for (uint32_t i = 0; i < graph[u].size(); ++i) {
v = graph[u][i].first;
weight = graph[u][i].second;
Relax(u, v, weight, q, distances);
}
}
}
struct ComparatorAsc {
std::vector<uint32_t> values;
bool operator() (uint32_t i, uint32_t j) {
return (values[i] < values[j]);
}
};
struct ComparatorDesc {
std::vector<uint32_t> values;
bool operator() (uint32_t i, uint32_t j) {
return (values[i] > values[j]);
}
};
int main() {
uint32_t n, m;
std::cin >> n >> m;
std::vector<std::vector<std::pair<uint32_t, uint32_t>>> graph(n);
std::vector<std::vector<std::pair<uint32_t, uint32_t>>> graphR(n);
std::vector<uint32_t> forwardDistances(n);
std::vector<uint32_t> backwardDistances(n);
uint32_t u, v;
uint32_t weight;
for (uint32_t i = 0; i < m; ++i) {
std::cin >> u >> v >> weight;
graph[u - 1].push_back(std::make_pair(v - 1, weight));
}
uint32_t s, t, d;
std::cin >> s >> t >> d;
Dijkstra(graph, forwardDistances, s - 1);
graphR = ReverseGraph(graph);
Dijkstra(graphR, backwardDistances, t - 1);
std::vector<uint32_t> forwardIndices(n);
std::vector<uint32_t> backwardIndices(n);
for (uint32_t i = 0; i < n; ++i) {
forwardIndices[i] = i;
backwardIndices[i] = i;
}
uint64_t count = 0;
if (forwardDistances[t - 1] <= d) {
count = n*(n - 1);
} else {
ComparatorAsc forwardCompare;
ComparatorDesc backwardCompare;
forwardCompare.values = forwardDistances;
backwardCompare.values = backwardDistances;
std::sort(forwardIndices.begin(), forwardIndices.end(), forwardCompare);
std::sort(backwardIndices.begin(), backwardIndices.end(), backwardCompare);
uint32_t j = 0;
for (uint32_t i = 0; i < n; ++i) {
while ((forwardDistances[forwardIndices[i]] + backwardDistances[backwardIndices[j]] >= d) && (j < n)) {
j += 1;
}
count += n - j;
}
}
std::cout << count;
return 0;
}