#include <bits/stdc++.h>
using namespace std;
struct kraw {
  int a, w;
};
const int INF = 1000000000;
void Dijkstra(int start, vector<int>& D, vector<vector<kraw> >& G) {
  priority_queue<pair<int, int>, vector<pair<int, int> >,
                 greater<pair<int, int> > >
      Q;
  Q.push(make_pair(0, start));
  while (!Q.empty()) {
    pair<int, int> x = Q.top();
    Q.pop();
    if (x.first <= D[x.second]) {
      for (int i = 0; i < G[x.second].size(); ++i) {
        kraw y = G[x.second][i];
        if (D[y.a] > D[x.second] + y.w) {
          D[y.a] = D[x.second] + y.w;
          Q.push(make_pair(D[y.a], y.a));
        }
      }
    }
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  int n, m, s;
  cin >> n >> m >> s;
  --s;
  vector<vector<kraw> > G(n);
  for (int i = 0; i < m; ++i) {
    int a, b, w;
    cin >> a >> b >> w;
    --a;
    --b;
    G[a].push_back({b, w});
    G[b].push_back({a, w});
  }
  int l;
  cin >> l;
  vector<int> D(n, INF);
  D[s] = 0;
  Dijkstra(s, D, G);
  int odp = 0;
  for (int i = 0; i < n; ++i) {
    if (D[i] == l) ++odp;
    for (int j = 0; j < G[i].size(); ++j) {
      if (i < G[i][j].a) {
        vector<int> x;
        if (D[i] < l && D[i] + G[i][j].w > l) {
          int d = l - D[i];
          if ((G[i][j].w - d) + D[G[i][j].a] >= l) x.push_back(d);
        }
        if (D[G[i][j].a] < l && D[G[i][j].a] + G[i][j].w > l) {
          int d = l - D[G[i][j].a];
          if ((G[i][j].w - d) + D[i] >= l) x.push_back(d);
        }
        if (x.size() == 1)
          ++odp;
        else {
          if (x.size() == 2) {
            if (x[0] + x[1] == G[i][j].w)
              ++odp;
            else
              odp += 2;
          }
        }
      }
    }
  }
  cout << odp;
  return 0;
}
