#include <bits/stdc++.h>
using namespace std;
int ans;
struct EDGE {
  int to, next;
};
struct tree {
  int head[200200], siz[200200], cnt;
  EDGE edge[300300];
  void AddEdge(int u, int v) {
    edge[++cnt] = (EDGE){v, head[u]}, head[u] = cnt;
  }
  void dfs(int u, int rt) {
    siz[u] = 1;
    for (int i = head[u]; i; i = edge[i].next) {
      int v = edge[i].to;
      dfs(v, rt);
      siz[u] += siz[v];
    }
    if (u != rt) ans = max(ans, siz[u]);
  }
} dt;
int x[300300 << 1], y[300300 << 1];
const int oo = 1073741819;
struct domt {
  int tail[4][200200];
  int next[4][2000000], sora[4][2000000];
  int ss[4], top, w_time, n, m;
  int rel[200200], semi[200200], b[200200], idom[200200], best[200200],
      st[200200], pre[200200];
  int ans[200200];
  void origin() {
    for (int e = 0; e <= 3; e++) ss[e] = n;
    for (int i = 1; i <= n; i++) {
      for (int e = 0; e <= 3; e++) tail[e][i] = i, next[e][i] = 0;
      rel[i] = 0;
      semi[i] = idom[i] = pre[i] = 0, best[i] = i;
      b[i] = i;
      ans[i] = 0;
    }
    rel[0] = oo;
  }
  void link(int e, int x, int y) {
    ++ss[e], next[e][tail[e][x]] = ss[e], tail[e][x] = ss[e],
             sora[e][ss[e]] = y, next[e][ss[e]] = 0;
  }
  void dfs(int x, int y) {
    ++w_time, rel[x] = w_time;
    st[++top] = x, pre[x] = y;
    for (int i = x, ne; next[0][i];) {
      i = next[0][i], ne = sora[0][i];
      if (!rel[ne]) dfs(ne, x);
    }
  }
  int find(int x) {
    int y = b[x];
    if (b[x] != x) b[x] = find(b[x]);
    if (rel[semi[best[y]]] < rel[semi[best[x]]]) best[x] = best[y];
    return b[x];
  }
  void getans(int x, int sum) {
    ans[x] = sum + x;
    for (int i = x, ne; next[3][i];) {
      i = next[3][i], ne = sora[3][i];
      getans(ne, sum + x);
    }
  }
  void build(int _, int __) {
    n = _, m = __;
    origin();
    for (int i = 1; i <= m; i++) {
      link(0, x[i], y[i]);
      link(1, y[i], x[i]);
    }
    w_time = 0;
    top = 0;
    dfs(n, 0);
    for (int i = top; i >= 1; i--) {
      int ne = st[i];
      for (int j = ne, na; next[1][j];) {
        j = next[1][j], na = sora[1][j];
        if (!rel[na]) continue;
        if (rel[na] > rel[ne]) {
          find(na);
          int y = semi[best[na]];
          if (rel[y] < rel[semi[ne]]) semi[ne] = y;
        } else {
          int y = na;
          if (rel[y] < rel[semi[ne]]) semi[ne] = y;
        }
      }
      if (ne != n) link(2, semi[ne], ne);
      for (int j = ne, na; next[2][j];) {
        j = next[2][j], na = sora[2][j];
        find(na);
        int y = best[na];
        if (semi[y] == semi[na])
          idom[na] = semi[na];
        else
          idom[na] = y;
      }
      for (int j = ne, na; next[0][j];) {
        j = next[0][j], na = sora[0][j];
        if (pre[na] == ne) {
          na = find(na);
          b[na] = ne;
        }
      }
    }
    for (int i = 2; i <= top; i++) {
      int ne = st[i];
      if (idom[ne] != semi[ne]) idom[ne] = idom[idom[ne]];
      dt.AddEdge(idom[ne], ne);
    }
  }
} dom;
int head[200200], cnt, n, m, s, done[200200], e;
struct Edge {
  int to, next, cost;
} edge[300300 << 1];
void AddEdge(int u, int v, int w) {
  edge[++cnt] = (Edge){v, head[u], w}, head[u] = cnt;
  edge[++cnt] = (Edge){u, head[v], w}, head[v] = cnt;
}
struct node {
  long long d;
  int u;
  bool operator<(const node &r) const { return d > r.d; }
};
priority_queue<node> q;
long long dis[200200];
void dij(int s) {
  memset(dis, 60, sizeof dis);
  dis[s] = 0;
  q.push((node){0, s});
  while (!q.empty()) {
    node now = q.top();
    q.pop();
    if (done[now.u]) continue;
    done[now.u] = 1;
    for (int i = head[now.u]; i; i = edge[i].next) {
      int v = edge[i].to;
      if (dis[v] > dis[now.u] + edge[i].cost)
        q.push((node){dis[v] = dis[now.u] + edge[i].cost, v});
    }
  }
  for (int u = 1; u <= n; u++)
    for (int i = head[u]; i; i = edge[i].next) {
      int v = edge[i].to;
      if (dis[v] == dis[u] + edge[i].cost) ++e, x[e] = u, y[e] = v;
    }
}
int main() {
  int s;
  scanf("%d%d%d", &n, &m, &s);
  for (int i = 1; i <= m; i++) {
    int u, v, w;
    scanf("%d%d%d", &u, &v, &w);
    if (u == s)
      u = n;
    else if (u == n)
      u = s;
    if (v == s)
      v = n;
    else if (v == n)
      v = s;
    AddEdge(u, v, w);
  }
  dij(n);
  dom.build(n, e);
  dt.dfs(n, n);
  printf("%d\n", ans);
  return 0;
}
