#include <bits/stdc++.h>
using namespace std;
struct UnionFind {
  vector<int> par, sz;
  int n_tree;
  explicit UnionFind(int n) : par(n), sz(n, 1), n_tree(n) {
    iota(par.begin(), par.end(), 0);
  }
  int n_cluster() const { return n_tree; }
  int size(int x) { return sz[root(x)]; }
  int root(int x) { return x == par[x] ? x : par[x] = root(par[x]); }
  bool unite(int x, int y) {
    int rx = root(x), ry = root(y);
    if (rx != ry) {
      par[rx] = ry;
      --n_tree;
      sz[ry] += sz[rx];
      return true;
    }
    return false;
  }
  bool same(int x, int y) { return root(x) == root(y); }
  bool is_root(int x) const { return par[x] == x; }
};
int gcd(int x, int y) { return y == 0 ? x : gcd(y, x % y); }
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int n, u, v;
  cin >> n >> u >> v;
  --u, --v;
  vector<vector<int>> g(n);
  for (int i = 0; i < n - 1; ++i) {
    int x, y;
    cin >> x >> y;
    --x, --y;
    g[x].push_back(y);
    g[y].push_back(x);
  }
  vector<int> depth(n);
  vector<int> max_leaf_depth(n);
  function<void(int, int)> dfs = [&](int x, int fa) {
    for (int y : g[x]) {
      if (y != fa) {
        depth[y] = depth[x] + 1;
        max_leaf_depth[y] = depth[y];
        dfs(y, x);
        max_leaf_depth[x] = max(max_leaf_depth[x], max_leaf_depth[y]);
      }
    }
  };
  dfs(v, v);
  int d = depth[u] - (depth[u] - 1) / 2;
  int max_depth = 0;
  for (int i = 0; i < n; ++i) {
    if (depth[i] == d) {
      max_depth = max(max_depth, max_leaf_depth[i]);
    }
  }
  cout << max_depth - 1 << endl;
  return 0;
}
