#include <bits/stdc++.h>
using namespace std;
inline int read() {
  int sum = 0;
  char c = getchar();
  bool f = 0;
  while (c < '0' || c > '9') {
    if (c == '-') f = 1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    sum = sum * 10 + c - '0';
    c = getchar();
  }
  if (f) return -sum;
  return sum;
}
const int N = 600005;
const long long orz = (1LL << 61);
int n, m, S;
namespace Tree {
struct e {
  int num, next;
} map[N];
int head[N], len, ans;
inline void link(int x, int y) {
  len++;
  map[len].num = y;
  map[len].next = head[x];
  head[x] = len;
}
inline int dfs(int k) {
  int i, s = 1;
  for (i = head[k]; i; i = map[i].next) s += dfs(map[i].num);
  if (k && k != S) ans = max(ans, s);
  return s;
}
inline void work() {
  dfs(0);
  printf("%d", ans);
}
}  // namespace Tree
namespace G2 {
struct e {
  int num, next;
} map[N];
int head[N], d[N], f[N][19], dep[N], len;
inline void link(int x, int y) {
  len++;
  map[len].num = y;
  map[len].next = head[x];
  head[x] = len;
  d[y]++;
}
queue<int> q;
vector<int> R[N];
inline int LCA(int x, int y) {
  if (!x) return y;
  if (dep[x] < dep[y]) swap(x, y);
  int i, del = dep[x] - dep[y];
  for (i = 0; i <= 18; i++)
    if ((1 << i) & del) x = f[x][i];
  if (x == y) return x;
  for (i = 18; i >= 0; i--)
    if (f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];
  return f[x][0];
}
inline void work() {
  int i, x, y, k = 0;
  q.push(S);
  vector<int>::iterator it, ed;
  while (!q.empty()) {
    x = q.front();
    q.pop();
    k = 0;
    for (it = R[x].begin(), ed = R[x].end(); it != ed; it++) k = LCA(k, *it);
    Tree::link(k, x);
    f[x][0] = k;
    dep[x] = dep[k] + 1;
    for (i = 1; i <= 18; i++) f[x][i] = f[f[x][i - 1]][i - 1];
    for (i = head[x]; i; i = map[i].next) {
      y = map[i].num;
      d[y]--;
      R[y].push_back(x);
      if (!d[y]) q.push(y);
    }
  }
}
}  // namespace G2
namespace Graph {
struct e {
  int num, next, w;
} map[N];
int head[N], len;
inline void link(int x, int y, int w) {
  len++;
  map[len].num = y;
  map[len].next = head[x];
  head[x] = len;
  map[len].w = w;
  len++;
  map[len].num = x;
  map[len].next = head[y];
  head[y] = len;
  map[len].w = w;
}
struct ex {
  int id;
  long long v;
};
inline bool operator<(const ex &a, const ex &b) { return a.v > b.v; }
priority_queue<ex> q;
long long dis[N];
bool vis[N];
inline void Dij() {
  int i, j, k, x;
  for (i = 1; i <= n; i++) dis[i] = orz;
  dis[S] = 0;
  q.push((ex){S, 0});
  while (!q.empty()) {
    k = q.top().id;
    q.pop();
    if (vis[k]) continue;
    vis[k] = 1;
    for (i = head[k]; i; i = map[i].next) {
      x = map[i].num;
      if (dis[k] + map[i].w < dis[x]) {
        dis[x] = dis[k] + map[i].w;
        q.push((ex){x, dis[x]});
      }
    }
  }
  for (i = 1; i <= n; i++)
    for (j = head[i]; j; j = map[j].next)
      if (dis[map[j].num] == dis[i] + map[j].w) G2::link(i, map[j].num);
}
}  // namespace Graph
int main() {
  int i, x, y, w;
  n = read();
  m = read();
  S = read();
  for (i = 1; i <= m; i++) {
    x = read(), y = read(), w = read();
    Graph::link(x, y, w);
  }
  Graph::Dij();
  G2::work();
  Tree::work();
  return 0;
}
