#include <bits/stdc++.h>
using namespace std;
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << "(" << p.first << "," << p.second << ")";
  return os;
}
#ifdef __LOCAL
#define debug(x) cerr << __LINE__ << ": " << #x << " = " << x << endl
#define debugArray(x, n)                           \
  cerr << __LINE__ << ": " << #x << " = {";        \
  for (long long hoge = 0; (hoge) < (n); ++(hoge)) \
    cerr << ((hoge) ? "," : "") << x[hoge];        \
  cerr << "}" << endl
#else
#define debug(x) (void(0))
#define debugArray(x, n) (void(0))
#endif

struct HeavyLightDecomposition {
  vector<vector<int>> adj;
  vector<int> sz, in, out, head, par;

  HeavyLightDecomposition(int n) : adj(n) {}
  void add_edge(int u, int v) {
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  void build(int rt = 0) {
    sz.assign(adj.size(), 1);
    in.assign(adj.size(), 0);
    out.assign(adj.size(), 0);
    head.assign(adj.size(), 0);
    par.assign(adj.size(), 0);
    dfs_sz(rt, -1);
    int t = 0;
    dfs_hld(rt, -1, t);
  }
  int lca(int u, int v) const {
    for (;; v = par[head[v]]) {
      if (in[u] > in[v]) swap(u, v);
      if (head[u] == head[v]) return u;
    }
  }
  template <typename T, typename Q, typename F>
  T query_path(int u, int v, const Q &q, const F &f, const T ti,
               bool edge = false) {
    T vl = ti, vr = ti;
    for (;; v = par[head[v]]) {
      if (in[u] > in[v]) swap(u, v), swap(vl, vr);
      if (head[u] == head[v]) break;
      vl = f(q(in[head[v]], in[v] + 1), vl);
    }
    return f(f(q(in[u] + edge, in[v] + 1), vl), vr);
  }
  template <typename T, typename Q>
  T query_subtree(int v, const Q &q, bool edge = false) {
    return q(in[v] + edge, out[v]);
  }

  template <typename Q>
  void update_path(int u, int v, const Q &q, bool edge = false) {
    for (;; v = par[head[v]]) {
      if (in[u] > in[v]) swap(u, v);
      if (head[u] == head[v]) break;
      q(in[head[v]], in[v] + 1);
    }
    q(in[u] + edge, in[v] + 1);
  }
  template <typename Q>
  void update_subtree(int v, const Q &q, bool edge = false) {
    q(in[v] + edge, out[v]);
  }

 private:
  void dfs_sz(int v, int p) {
    if (adj[v].size() && adj[v][0] == p) swap(adj[v][0], adj[v].back());
    for (auto &u : adj[v])
      if (u != p) {
        dfs_sz(u, v);
        sz[v] += sz[u];
        if (sz[adj[v][0]] < sz[u]) swap(adj[v][0], u);
      }
  }
  void dfs_hld(int v, int p, int &times) {
    par[v] = p;
    in[v] = times++;
    for (auto &u : adj[v])
      if (u != p) {
        head[u] = (adj[v][0] == u ? head[v] : u);
        dfs_hld(u, v, times);
      }
    out[v] = times;
  }
};

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int N, u, v;
  cin >> N >> u >> v;
  u--, v--;
  HeavyLightDecomposition hld(N);
  for (int i = 0; i < N - 1; i++) {
    int A, B;
    cin >> A >> B;
    A--, B--;
    hld.add_edge(A, B);
  }
  hld.build(0);
  int depth[N];
  function<void(int, int, int)> dfs = [&](int a, int p, int d) {
    depth[a] = d;
    for (int b : hld.adj[a])
      if (b != p) dfs(b, a, d + 1);
  };
  dfs(0, -1, 0);
  auto dist = [&](int a, int b) {
    return depth[a] + depth[b] - 2 * depth[hld.lca(a, b)];
  };
  int ans = 0;
  for (int i = 0; i < N; i++) {
    int du = dist(i, u), dv = dist(i, v);
    // debug(i);
    // debug(du);
    // debug(dv);
    if (du > dv) continue;
    ans = max(ans, dv - 1);
  }
  cout << ans << '\n';
  return 0;
}


Measured memory_bytes: 19012