#include <bits/stdc++.h>
#pragma GCC optimize(3)
using namespace std;
const int Mod = 1e9 + 7;
const int N = 1e5 + 100;
const int INF = 0x3f3f3f3f;
const long long LINF = 0x3f3f3f3f3f3f3f3f;
inline long long dpow(long long a, long long b) {
  long long r = 1, t = a;
  while (b) {
    if (b & 1) r = (r * t) % Mod;
    b >>= 1;
    t = (t * t) % Mod;
  }
  return r;
}
inline long long fpow(long long a, long long b) {
  long long r = 1, t = a;
  while (b) {
    if (b & 1) r = (r * t);
    b >>= 1;
    t = (t * t);
  }
  return r;
}
vector<pair<int, int>> G[N];
int dis[N], cost[N];
int n, m, s, l, ans;
bool vis[N];
pair<int, int> eg[N];
void Dijkstra(int s) {
  priority_queue<pair<int, int>, vector<pair<int, int>>,
                 greater<pair<int, int>>>
      q;
  memset(dis, INF, sizeof(dis));
  dis[s] = 0, q.push({0, s});
  int ans = 0;
  while (!q.empty()) {
    pair<int, int> now = q.top();
    q.pop();
    int u = now.second;
    if (vis[u]) continue;
    vis[u] = true;
    for (auto it : G[u]) {
      int v = it.first, id = it.second;
      if (dis[v] > dis[u] + cost[id]) {
        dis[v] = dis[u] + cost[id];
        q.push({dis[v], v});
      }
    }
  }
}
int main() {
  cin >> n >> m >> s;
  for (int i = 1; i <= m; i++) {
    int u, v, w;
    scanf("%d %d %d", &u, &v, &w);
    G[u].push_back({v, i});
    G[v].push_back({u, i});
    cost[i] = w;
    eg[i] = {u, v};
  }
  cin >> l;
  Dijkstra(s);
  for (int i = 1; i <= n; i++)
    if (dis[i] == l) ans++;
  for (int i = 1; i <= m; i++) {
    int u = eg[i].first, v = eg[i].second;
    int d1 = dis[u], d2 = dis[v];
    if (d1 > d2) swap(d1, d2);
    if (d1 + cost[i] == d2) {
      if (l > d1 && l < d2) ans++;
    } else {
      if (d1 >= l) continue;
      int w = cost[i] - (d2 - d1);
      if (d2 >= l)
        ans++;
      else {
        if (d2 + w / 2 == l) {
          ans++;
          if (w & 1) ans++;
        } else if (d2 + w / 2 > l)
          ans += 2;
      }
    }
  }
  printf("%d\n", ans);
  return 0;
}
