#include <bits/stdc++.h>
using namespace std;
vector<vector<long long int> > G, W, F;
vector<long long int> first, sdom, p, dsu;
vector<long long int> original, minimum;
vector<vector<long long int> > rev;
int cnt;
void init_dt(int n) {
  cnt = 0;
  first = p = dsu = original = minimum = sdom = vector<long long int>(n, -1);
  rev = vector<vector<long long int> >(n);
  for (int i = 0; i < n; ++i) dsu[i] = minimum[i] = sdom[i] = i;
}
void dfs_dt(int v) {
  original[cnt] = v;
  first[v] = cnt++;
  for (int u : G[v]) {
    if (first[u] == -1) {
      dfs_dt(u);
      p[first[u]] = first[v];
    }
    rev[first[u]].push_back(first[v]);
  }
}
int find_min(int u, int x) {
  if (u == dsu[u]) {
    if (x) return -1;
    return u;
  }
  int v = find_min(dsu[u], x + 1);
  if (v < 0) return u;
  if (sdom[minimum[dsu[u]]] < sdom[minimum[u]]) minimum[u] = minimum[dsu[u]];
  dsu[u] = v;
  if (x) return v;
  return minimum[u];
}
vector<vector<long long int> > dominator_tree(int n, int start) {
  init_dt(n);
  dfs_dt(start);
  vector<long long int> idom(n, 0);
  vector<vector<long long int> > mysdom(n);
  p[0] = 0;
  for (int v = n - 1; v >= 0; --v) {
    if (p[v] == -1) continue;
    for (int u : rev[v]) sdom[v] = min(sdom[v], sdom[find_min(u, 0)]);
    if (v) mysdom[sdom[v]].push_back(v);
    for (int u : mysdom[v]) {
      int minim = find_min(u, 0);
      if (sdom[u] == sdom[minim])
        idom[u] = sdom[u];
      else
        idom[u] = minim;
    }
    if (v) dsu[v] = p[v];
  }
  for (int v = 1; v < n; ++v) {
    if (p[v] == -1) continue;
    if (sdom[v] != idom[v]) idom[v] = idom[idom[v]];
  }
  vector<vector<long long int> > ans(n);
  for (int v = 1; v < n; ++v) {
    if (p[v] == -1) continue;
    ans[original[v]].push_back(original[idom[v]]);
    ans[original[idom[v]]].push_back(original[v]);
  }
  return ans;
}
void dijkstra(int n, int start) {
  priority_queue<vector<long long int> > Q;
  Q.push({-0, start, -1});
  vector<long long int> dist(n, 1e18);
  while (not Q.empty()) {
    vector<long long int> aux = Q.top();
    Q.pop();
    long long int d = -aux[0], v = aux[1], p = aux[2];
    if (dist[v] < d) continue;
    if (p != -1) F[p].push_back(v);
    if (dist[v] == d) continue;
    dist[v] = d;
    for (int i = 0; i < G[v].size(); ++i) {
      long long int u = G[v][i], w = W[v][i];
      if (dist[u] >= w + d) Q.push({-w - d, u, v});
    }
  }
}
vector<long long int> childs;
int dfs(int v, int p) {
  ++childs[v];
  for (int u : G[v]) {
    if (u != p) childs[v] += dfs(u, v);
  }
  return childs[v];
}
int solve(int start) {
  dfs(start, start);
  long long int ans = 0;
  for (int u : G[start]) ans = max(ans, childs[u]);
  return ans;
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  int n, m, c;
  cin >> n >> m >> c;
  --c;
  G = W = F = vector<vector<long long int> >(n);
  for (int i = 0; i < m; ++i) {
    long long int x, y, w;
    cin >> x >> y >> w;
    --x;
    --y;
    G[x].push_back(y);
    G[y].push_back(x);
    W[x].push_back(w);
    W[y].push_back(w);
  }
  dijkstra(n, c);
  G = F;
  G = dominator_tree(n, c);
  childs = vector<long long int>(n, 0);
  cout << solve(c) << endl;
}
