#include <bits/stdc++.h>
using namespace std;
inline long long read() {
  long long w = 0, f = 1;
  char ch = getchar();
  while (ch < '0' or ch > '9') {
    if (ch == '-') f = -f;
    ch = getchar();
  }
  while (ch >= '0' and ch <= '9') w = w * 10 + ch - '0', ch = getchar();
  return w * f;
}
const long long maxn = 4e5 + 5, maxm = 6e5 + 5, INF = 1e17 + 14;
struct Graph {
  long long head[maxn], ver[maxm], edge[maxm], Next[maxm], tot;
  void add(long long x, long long y, long long z = 0) {
    ver[++tot] = y, edge[tot] = z, Next[tot] = head[x], head[x] = tot;
  }
} A, B, T;
struct node {
  long long id, val;
  bool operator<(const node &x) const { return val > x.val; }
};
long long N, M, s, X[maxn], Y[maxn], Z[maxn], dis[maxn], in[maxn];
bool vis[maxn];
void dijkstra() {
  for (long long i = 1; i <= N; i++) dis[i] = INF, vis[i] = 0;
  dis[s] = 0;
  priority_queue<node> q;
  q.push((node){s, 0});
  while (!q.empty()) {
    long long x = q.top().id;
    q.pop();
    if (vis[x]) continue;
    vis[x] = 1;
    for (long long i = A.head[x]; i; i = A.Next[i]) {
      long long y = A.ver[i];
      if (dis[y] > dis[x] + A.edge[i]) {
        dis[y] = dis[x] + A.edge[i];
        q.push((node){y, dis[y]});
      }
    }
  }
}
long long topo[maxn], tot, f[maxn][20], d[maxn], siz[maxn];
vector<long long> pre[maxn];
void TopoSort() {
  queue<long long> q;
  for (long long i = 1; i <= N; i++)
    if (!in[i]) q.push(i);
  while (!q.empty()) {
    long long x = q.front();
    q.pop();
    topo[++tot] = x;
    for (long long i = B.head[x]; i; i = B.Next[i]) {
      long long y = B.ver[i];
      in[y]--;
      if (!in[y]) q.push(y);
    }
  }
}
long long lca(long long x, long long y) {
  if (d[x] < d[y]) swap(x, y);
  for (long long i = 18; i >= 0; i--)
    if (d[f[x][i]] >= d[y]) x = f[x][i];
  if (x == y) return x;
  for (long long i = 18; i >= 0; i--)
    if (f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];
  return f[x][0];
}
void dfs(long long x) {
  siz[x] = (dis[x] != INF);
  for (long long i = T.head[x]; i; i = T.Next[i]) {
    long long y = T.ver[i];
    dfs(y);
    siz[x] += siz[y];
  }
}
signed main() {
  N = read(), M = read(), s = read();
  for (long long i = 1; i <= M; i++) {
    X[i] = read(), Y[i] = read(), Z[i] = read();
    A.add(X[i], Y[i], Z[i]);
    A.add(Y[i], X[i], Z[i]);
  }
  dijkstra();
  for (long long i = 1; i <= M; i++) {
    if (dis[X[i]] + Z[i] == dis[Y[i]])
      B.add(X[i], Y[i]), in[Y[i]]++, pre[Y[i]].push_back(X[i]);
    if (dis[Y[i]] + Z[i] == dis[X[i]])
      B.add(Y[i], X[i]), in[X[i]]++, pre[X[i]].push_back(Y[i]);
  }
  TopoSort();
  for (long long i = 1; i <= tot; i++) {
    long long x = topo[i];
    if (pre[x].begin() != pre[x].end()) {
      f[x][0] = *pre[x].begin();
      for (auto it = pre[x].begin() + 1; it != pre[x].end(); ++it)
        f[x][0] = lca(f[x][0], *it);
    }
    d[x] = d[f[x][0]] + 1;
    T.add(f[x][0], x);
    for (long long s = 1; s <= 18; s++) f[x][s] = f[f[x][s - 1]][s - 1];
  }
  dfs(0);
  long long ans = 0;
  for (long long i = 1; i <= N; i++)
    if (i != s) ans = max(ans, siz[i]);
  cout << ans << endl;
  return 0;
}
