#include <bits/stdc++.h>
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
using namespace std;
struct doset {
  doset(int n) {
    cout << fixed << setprecision(n);
    cerr << fixed << setprecision(n);
  }
};
struct myset {
  myset() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
  }
};
using ll = long long;
using ld = long double;
using dou = double;
const int inf = 1 << 30;
const ll INF = 1LL << 60;
const ld pi = 3.14159265358;
const ll mod1 = 1000000007LL;
const ll mod2 = 998244353LL;
template <class T, class U>
inline bool chmin(T& a, const U& b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T, class U>
inline bool chmax(T& a, const U& b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T, class U>
inline bool change(T& a, U& b) {
  if (a > b) {
    swap(a, b);
    return 1;
  }
  return 0;
}
ll modpow(ll n, ll m, ll MOD) {
  if (m == 0) return 1;
  if (m < 0) return -1;
  ll res = 1;
  while (m) {
    if (m & 1) res = (res * n) % MOD;
    m >>= 1;
    n *= n;
    n %= MOD;
  }
  return res;
}
ll mypow(ll n, ll m) {
  if (m == 0) return 1;
  if (m < 0) return -1;
  ll res = 1;
  while (m) {
    if (m & 1) res = (res * n);
    m >>= 1;
    n *= n;
  }
  return res;
}
template <class T>
inline bool isp(T n) {
  bool res = true;
  if (n == 1 || n == 0)
    return false;
  else {
    for (ll i = 2; i * i <= n; i++) {
      if (n % i == 0) {
        res = false;
        break;
      }
    }
    return res;
  }
}
template <class T = int>
T in() {
  T x;
  cin >> x;
  return x;
}
inline bool Yes(bool b) {
  cout << (b ? "Yes\n" : "No\n");
  return b;
}
inline bool YES(bool b) {
  cout << (b ? "YES\n" : "NO\n");
  return b;
}
int main() {
  myset m;
  ll N, nige, oni;
  cin >> N >> nige >> oni;
  nige--;
  oni--;
  vector<vector<ll>> G(N);
  ll a, b;
  for (int i = 0; i < (int)N - 1; ++i) {
    cin >> a >> b;
    a--;
    b--;
    G[a].push_back(b);
    G[b].push_back(a);
  }
  vector<ll> distn(N, INF), disto(N, INF);
  distn[nige] = 0;
  disto[oni] = 0;
  queue<ll> que;
  que.push(nige);
  while (!que.empty()) {
    ll n = que.front();
    que.pop();
    for (int x : G[n]) {
      if (distn[x] == INF) {
        distn[x] = distn[n] + 1;
        que.push(x);
      }
    }
  }
  que.push(oni);
  while (!que.empty()) {
    ll n = que.front();
    que.pop();
    for (int x : G[n]) {
      if (disto[x] == INF) {
        disto[x] = disto[n] + 1;
        que.push(x);
      }
    }
  };
  ;
  ll ans = 0;
  vector<bool> use(N);
  for (int i = 0; i < (int)N; ++i) {
    if (disto[i] == distn[i] && !use[i]) {
      use[i] = 1;
      ll now = i;
      while (1) {
        ll next = -1;
        for (int x : G[now]) {
          if (disto[x] == distn[x] && disto[now] - 1 == disto[x]) {
            next = x;
            use[x] = 1;
            break;
          }
        }
        if (next == -1) break;
        now = next;
      }
      chmax(ans, disto[now]);
    }
  }
  for (int i = 0; i < (int)N; ++i) {
    if (disto[i] < distn[i])
      continue;
    else if (disto[i] > distn[i]) {
      chmax(ans, disto[i] - 1);
    }
  }
  cout << ans << "\n";
}
