#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>
class DFS {
 public:
  DFS(int node_size) : node_size_(node_size) { Initialize(); }
  void AddEdge(int from, int to) {
    graph_[from].emplace_back(to);
  }
  void Solve(int source, int prev = -1, int depth = 0) {
    distance_[source] = depth;
    for (int next : graph_[source]) {
      if (next == prev) continue;
      distance_[next] = distance_[source] + 1;
      Solve(next, source, depth + 1);
    }
  }
  T operator[](int to) const { return distance_[to]; }

 private:
  int node_size_;
  std::vector<T> distance_;
  std::vector<vector<int>> graph_;
  void Initialize() {
    distance_.assign(node_size_, std::numeric_limits<T>::max() / 2);
    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;

  DFS<int> bfs_t(n);
  DFS<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;
}

Measured memory_bytes: 14336