// Slower C++ solution:
/**

 *    author  : 𝒌𝒚𝒐𝒎𝒖𝒌𝒚𝒐𝒎𝒖𝒑𝒖𝒓𝒊𝒏

 *    created : 2019-12-23 17:24:58

**/



#include <iostream>

#include <deque>

#include <map>

#include <queue>

#include <set>

#include <stack>

#include <string>

#include <vector>

#include <algorithm>

#include <cmath>

#include <complex>

#include <numeric>

#include <bitset>

#include <cassert>

#include <cctype>

#include <iomanip>

#include <random>

#include <utility>

#include <chrono>



using namespace std;



using int64 = long long;

template<class T> ostream& operator<<(ostream& os, vector<T>& _) { os << '{'; for (T& x : _) { os << x; if (&x != &_.back()) os << ','; } os << '}'; return os; }

template<class T, class U> ostream& operator<<(ostream& os, pair<T, U>& p) { return os << '{' << p.first << " " << p.second << '}'; }



#ifdef LOCAL

#define debug(_) cerr << #_ << ": " << (_) << '\n'

#else

#define debug(_) 1728

#endif



template <class T>

class Dijkstra {

 public:

  Dijkstra(int node_size) : node_size_(node_size) { Initialize(); }

  void Add_Edge(int from, int to, T cost) {

    graph_[from].push_back({to, cost});

  }

  void Solve(int source) {

    std::priority_queue<std::pair<T, int>, std::vector<std::pair<T, int>>,

                        std::greater<std::pair<T, int>>> pq;

    distance_[source] = 0;

    pq.push({0, source});



    while (!pq.empty()) {

      std::pair<T, int> top = pq.top();

      pq.pop();

      int v = top.second;

      if (distance_[v] < top.first) continue;

      for (const auto& e : graph_[v]) {

        if (distance_[e.to] > distance_[v] + e.cost) {

          distance_[e.to] = distance_[v] + e.cost;

          pq.push({distance_[e.to], e.to});

        }

      }

    }

  }

  T operator[](int to) const { return distance_[to]; }



 private:

  struct edge {

    int to;

    T cost;

  };

  int node_size_;

  std::vector<T> distance_;

  std::vector<std::vector<edge>> graph_;

  void Initialize() {

    distance_.assign(node_size_, std::numeric_limits<T>::max() / 2);

    graph_.resize(node_size_);

  }

};



int main() {

  ios_base::sync_with_stdio(false);

  cin.tie(nullptr);



  int n, u, v; cin >> n >> u >> v;

  --u; --v;



  Dijkstra<int> dij_t(n);

  Dijkstra<int> dij_a(n);



  for (int i = 0; i < n - 1; ++i) {

    int a, b; cin >> a >> b;

    --a; --b;

    dij_a.Add_Edge(a, b, 1);

    dij_a.Add_Edge(b, a, 1);

    dij_t.Add_Edge(a, b, 1);

    dij_t.Add_Edge(b, a, 1);

  }



  dij_t.Solve(u);

  dij_a.Solve(v);



  int mx = -1;

  int ans = 0;



  for (int i = 0; i < n; ++i) {

    if (dij_t[i] < dij_a[i] && dij_a[i] > mx) {

      mx = dij_a[i];

      ans = dij_a[i] - 1;

    }

  }



  cout << ans << endl;



  return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.1092586671025886x):
#include <cstdio>

#include <queue>

#include <vector>

#include <algorithm>

#include <limits>

#include <utility>



using namespace std;



template <class T>

class Dijkstra {

 public:

  Dijkstra(int node_size) : node_size_(node_size) { Initialize(); }

  void Add_Edge(int from, int to, T cost) {

    graph_[from].push_back({to, cost});

  }

  void Solve(int source) {

    std::priority_queue<std::pair<T, int>, std::vector<std::pair<T, int>>,

                        std::greater<std::pair<T, int>>> pq;

    distance_[source] = 0;

    pq.push({0, source});



    while (!pq.empty()) {

      std::pair<T, int> top = pq.top();

      pq.pop();

      int v = top.second;

      if (distance_[v] < top.first) continue;

      for (const auto& e : graph_[v]) {

        if (distance_[e.to] > distance_[v] + e.cost) {

          distance_[e.to] = distance_[v] + e.cost;

          pq.push({distance_[e.to], e.to});

        }

      }

    }

  }

  T operator[](int to) const { return distance_[to]; }



 private:

  struct edge {

    int to;

    T cost;

  };

  int node_size_;

  std::vector<T> distance_;

  std::vector<std::vector<edge>> graph_;

  void Initialize() {

    distance_.assign(node_size_, std::numeric_limits<T>::max() / 2);

    graph_.resize(node_size_);

  }

};



template <class T>

class BFS {

 public:

  BFS(int node_size) : node_size_(node_size) { Initialize(); }

  void AddEdge(int from, int to) {

    graph_[from].emplace_back(to);

  }

  void Solve(int source) {

    std::queue<int> que;

    que.emplace(source);

    distance_[source] = 0;

    visited_[source] = 1;



    while (!que.empty()) {

      int top = que.front(); que.pop();

      for (int next : graph_[top]) {

        if (visited_[next]) continue;

        visited_[next] = 1;

        distance_[next] = distance_[top] + 1;

        que.emplace(next);

      }

    }

  }

  T operator[](int to) const { return distance_[to]; }



 private:

  int node_size_;

  std::vector<T> distance_;

  std::vector<int> visited_;

  std::vector<vector<int>> graph_;

  void Initialize() {

    distance_.assign(node_size_, std::numeric_limits<T>::max() / 2);

    visited_.assign(node_size_, 0);

    graph_.resize(node_size_);

  }

};



template<class T> inline void fastin(T &num) {

  bool negative = false;

  T c;

  num = 0;

  c = getchar_unlocked();

  if (c == '-') {

    negative = true;

    c = getchar_unlocked();

  }

  for (; (c > 47 && c < 58); c = getchar_unlocked()) num = (num << 3) + (num << 1) + c - 48;

  if (negative) num *= -1;

}



int main() {

  int n, u, v; fastin(n); fastin(u); fastin(v);

  --u; --v;



  BFS<int> bfs_t(n);

  BFS<int> bfs_a(n);



  for (int i = 0; i < n - 1; ++i) {

    int a, b; fastin(a); fastin(b);

    --a; --b;

    bfs_a.AddEdge(a, b);

    bfs_a.AddEdge(b, a);

    bfs_t.AddEdge(a, b);

    bfs_t.AddEdge(b, a);

  }



  bfs_t.Solve(u);

  bfs_a.Solve(v);



  int mx = -1;

  int ans = 0;



  for (int i = 0; i < n; ++i) {

    if (bfs_t[i] < bfs_a[i] && bfs_a[i] > mx) {

      mx = bfs_a[i];

      ans = bfs_a[i] - 1;

    }

  }



  printf("%d\n", ans);



  return 0;

}