#include <bits/stdc++.h>
using namespace std;
long long D[1000007];
vector<int> parent[1000007], adjTree[1000007];
vector<pair<int, long long> > adj[1000007];
vector<int> rev[1000007];
int n, m, s;
int dp[1000007][20];
int depth[1000007], in[1000007];
bool visited[1000007];
void dijkstra() {
  for (int i = (1); i <= (n); ++i) D[i] = 1000000000000000007LL;
  D[s] = 0LL;
  set<pair<long long, int> > st;
  st.insert(make_pair(0LL, s));
  while (!st.empty()) {
    int u = (*st.begin()).second;
    st.erase(st.begin());
    for (int i = (0); i <= ((int)adj[u].size() - 1); ++i) {
      int v = adj[u][i].first;
      long long w = adj[u][i].second;
      if (D[v] > D[u] + w) {
        st.erase(make_pair(D[v], v));
        D[v] = D[u] + w;
        st.insert(make_pair(D[v], v));
        parent[v].clear();
      }
      if (D[v] == D[u] + w) parent[v].emplace_back(u);
    }
  }
  return;
}
int goUp(int u, int k) {
  for (int i = (18); i >= (0); --i) {
    if (k >= (1 << i)) {
      k -= (1 << i);
      u = dp[u][i];
    }
  }
  return u;
}
int LCA(int u, int v) {
  if (depth[u] < depth[v]) swap(u, v);
  u = goUp(u, depth[u] - depth[v]);
  if (u == v) return u;
  for (int i = (18); i >= (0); --i) {
    if (dp[u][i] != dp[v][i]) {
      u = dp[u][i];
      v = dp[v][i];
    }
  }
  return dp[u][0];
}
void BFS() {
  queue<int> q;
  for (int i = (1); i <= (n); ++i) {
    if (!in[i]) {
      q.push(i);
      depth[i] = 1;
    }
  }
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    int par;
    if (parent[u].empty())
      par = -1;
    else {
      par = parent[u][0];
      for (int i = (1); i <= ((int)parent[u].size() - 1); ++i) {
        int v = parent[u][i];
        par = LCA(par, v);
      }
    }
    dp[u][0] = par;
    if (par > 0) {
      adjTree[par].emplace_back(u);
      depth[u] = depth[par] + 1;
    }
    for (int i = (1); i <= (18); ++i) {
      int v = dp[u][i - 1];
      if (v == -1)
        dp[u][i] = -1;
      else
        dp[u][i] = dp[v][i - 1];
    }
    for (int i = (0); i <= ((int)adj[u].size() - 1); ++i) {
      int v = adj[u][i].first;
      --in[v];
      if (!in[v]) q.push(v);
    }
  }
}
int ans = 0;
int f[1000007];
void getAns(int u) {
  f[u] = 1LL;
  visited[u] = 1;
  for (int i = (0); i <= ((int)adjTree[u].size() - 1); ++i) {
    int v = adjTree[u][i];
    if (!visited[v]) {
      getAns(v);
      ans = max(ans, f[v]);
      f[u] += f[v];
    }
  }
}
int main() {
  scanf("%d%d%d", &n, &m, &s);
  for (int i = (1); i <= (m); ++i) {
    int u, v;
    long long w;
    scanf("%d%d%lld", &u, &v, &w);
    adj[u].emplace_back(v, w);
    adj[v].emplace_back(u, w);
  }
  dijkstra();
  for (int i = (1); i <= (n); ++i) adj[i].clear();
  for (int v = (1); v <= (n); ++v) {
    for (int i = (0); i <= ((int)parent[v].size() - 1); ++i) {
      int u = parent[v][i];
      adj[u].emplace_back(make_pair(v, 0));
    }
  }
  for (int i = (1); i <= (n); ++i) in[i] = (int)parent[i].size();
  BFS();
  for (int i = (1); i <= (n); ++i) visited[i] = 0;
  getAns(s);
  cout << ans << endl;
  return 0;
}
