#include <bits/stdc++.h>
using namespace std;
inline void YesNo(bool b) { cout << (b ? "Yes" : "No") << endl; }
inline void YESNO(bool b) { cout << (b ? "YES" : "NO") << endl; }
inline void Yay(bool b) { cout << (b ? "Yay!" : ":(") << endl; }
int N_MAX = 1e5 + 10;
vector<vector<int> > T(N_MAX);
vector<bool> isleaf(N_MAX, false);
vector<int> dist(N_MAX, false);
map<int, int> mp;
void leafcheck(int cur, int v, vector<vector<int> > &Tree) {
  dist[v] = cur;
  if (Tree[v].size() == 0) isleaf[v] = true;
  for (const int &u : Tree[v]) {
    leafcheck(cur + 1, u, Tree);
  }
}
template <typename G>
struct DoublingLowestCommonAncestor {
  const int LOG;
  vector<int> dep;
  const G &g;
  vector<vector<int> > table;
  DoublingLowestCommonAncestor(const G &g)
      : g(g), dep(g.size()), LOG(32 - __builtin_clz(g.size())) {
    table.assign(LOG, vector<int>(g.size(), -1));
  }
  void dfs(int idx, int par, int d) {
    table[0][idx] = par;
    dep[idx] = d;
    for (auto &to : g[idx]) {
      if (to != par) dfs(to, idx, d + 1);
    }
  }
  void build() {
    dfs(0, -1, 0);
    for (int k = 0, k_max = (LOG - 1); k < k_max; ++k) {
      for (int i = 0, i_max = (table[k].size()); i < i_max; ++i) {
        if (table[k][i] == -1)
          table[k + 1][i] = -1;
        else
          table[k + 1][i] = table[k][table[k][i]];
      }
    }
  }
  int query(int u, int v) {
    if (dep[u] > dep[v]) swap(u, v);
    for (int i = (LOG)-1; i >= 0; --i)
      if (((dep[v] - dep[u]) >> i) & 1) v = table[i][v];
    if (u == v) return u;
    for (int i = (LOG)-1; i >= 0; --i) {
      if (table[i][u] != table[i][v]) {
        u = table[i][u];
        v = table[i][v];
      }
    }
    return table[0][u];
  }
};
vector<vector<int> > makeTree(int s, const vector<vector<int> > &G) {
  vector<vector<int> > Tree(N_MAX);
  set<int> st;
  queue<int> que;
  que.push(0);
  map<int, int> MP;
  MP[mp.size()] = s;
  mp[s] = mp.size();
  while (!que.empty()) {
    int cur = que.front();
    que.pop();
    for (const int &v : G[MP[cur]]) {
      if (mp.count(v)) continue;
      MP[mp.size()] = v;
      mp[v] = mp.size();
      que.push(mp[v]);
      Tree[cur].push_back(mp[v]);
    }
  }
  return Tree;
}
int main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << setprecision(15);
  int N;
  cin >> N;
  int v, u;
  cin >> u >> v;
  for (int i = 0, i_max = (N - 1); i < i_max; ++i) {
    int a, b;
    cin >> a >> b;
    T[a].emplace_back(b);
    T[b].emplace_back(a);
  }
  vector<vector<int> > Tree = makeTree(v, T);
  leafcheck(0, 0, Tree);
  vector<pair<int, int> > w;
  for (int t = 0, t_max = (N); t < t_max; ++t)
    if (isleaf[t]) w.emplace_back(pair<int, int>(dist[t], t));
  sort((w).begin(), (w).end(), greater<pair<int, int> >());
  DoublingLowestCommonAncestor<vector<vector<int> > > lca(Tree);
  lca.build();
  v = mp[v];
  u = mp[u];
  for (const pair<int, int> &p : w) {
    int t = lca.query(p.second, u);
    if (t == v) continue;
    int d1 = lca.dep[t];
    int d2 = lca.dep[u] - d1;
    if (d1 <= d2) continue;
    cout << p.first - 1 << endl;
    break;
  }
  return 0;
}
