#include <bits/stdc++.h>
using namespace std;
struct Edge {
  int from, to, cost;
};
struct Graph {
  vector<Edge> edges;
  vector<int> G[200000];
  int V = 200000;
  long long d[200000];
  void dijkstra(int s) {
    priority_queue<pair<int, int>, vector<pair<int, int> >,
                   greater<pair<int, int> > >
        pq;
    fill(d, d + V, 2000000000);
    d[s] = 0;
    pq.push(pair<int, int>(0, s));
    while (!pq.empty()) {
      pair<int, int> p = pq.top();
      pq.pop();
      int v = p.second;
      if (d[v] < p.first) continue;
      for (int i : G[v]) {
        Edge e = edges[i];
        if (d[e.to] > d[v] + e.cost) {
          d[e.to] = d[v] + e.cost;
          pq.push(pair<int, int>(d[e.to], e.to));
        }
      }
    }
  }
  void add_edge(int from, int to, int cost) {
    edges.push_back((Edge){to, from, cost});
    edges.push_back((Edge){from, to, cost});
    G[from].push_back(edges.size() - 1);
    G[to].push_back(edges.size() - 2);
  }
  void print_ans(int l) {
    int ans = 0;
    for (int i = 0; i < 200000; i++)
      if (d[i] == l) ans++;
    for (auto &e : edges) {
      if (d[e.from] < l && d[e.to] + d[e.from] + e.cost > l + l &&
          d[e.from] + e.cost > l)
        ans++;
      else if (d[e.from] < l && d[e.to] + d[e.from] + e.cost == l + l &&
               e.from < e.to && d[e.from] + e.cost > l)
        ans++;
    }
    cout << ans << endl;
  }
} g;
void solve(int n, int m, int s) {
  for (int i = 1; i <= m; i++) {
    int u, v, w;
    cin >> u >> v >> w;
    g.add_edge(u, v, w);
  }
  int l;
  cin >> l;
  g.dijkstra(s);
  g.print_ans(l);
  return;
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int n, m, s;
  cin >> n >> m >> s;
  solve(n, m, s);
  return 0;
}
