#include <bits/stdc++.h>
using i64 = int64_t;
using namespace std;
template <size_t I, class H, class... T>
struct TupleReaderWriter {
  static tuple<H, T...> r(istream& i) {
    H v;
    i >> v;
    return tuple_cat(tuple<H>(v),
                     TupleReaderWriter<sizeof...(T) - 1, T...>::r(i));
  }
  static void w(ostream& o, tuple<H, T...>& t, string d) {
    TupleReaderWriter<I - 1, H, T...>::w(o, t, d);
    o << d << get<I>(t);
  }
};
template <class H, class... T>
struct TupleReaderWriter<0, H, T...> {
  static tuple<H, T...> r(istream& i) {
    H v;
    i >> v;
    return tuple<H>(v);
  }
  static void w(ostream& o, tuple<H, T...>& t, string d) { o << get<0>(t); }
};
template <class... T>
istream& operator>>(istream& i, tuple<T...>& t) {
  t = TupleReaderWriter<sizeof...(T), T...>::r(i);
  return i;
}
template <class... T>
ostream& operator<<(ostream& o, tuple<T...>& t) {
  string delim = " ";
  TupleReaderWriter<sizeof...(T) - 1, T...>::w(o, t, delim);
  return o;
}
template <class T>
istream& operator>>(istream& i, vector<T>& v) {
  for (auto& x : v) i >> x;
  return i;
}
template <class T>
ostream& operator<<(ostream& o, vector<T>& v) {
  string delim = "";
  for (auto& x : v) o << delim << x, delim = " ";
  return o;
}
template <class T>
using rev_priority_queue = priority_queue<T, vector<T>, greater<T>>;
template <class T>
using vector2d = vector<vector<T>>;
struct fixprec {
  int x;
  fixprec(int d) : x(d) {}
};
ostream& operator<<(ostream& o, fixprec f) {
  return o << fixed << setprecision(f.x);
}
void R_YESNO(bool p) { cout << (p ? "YES" : "NO") << endl; }
void R_YesNo(bool p) { cout << (p ? "Yes" : "No") << endl; }
vector<set<int>> edge;
set<int> s_uv;
int64_t divceil(int64_t a, int64_t b) {
  return a / b + (a > 0 && a % b ? 1 : 0);
}
bool recursive(int x, int u) {
  if (x == u) return true;
  for (int y : edge[x]) {
    if (recursive(y, u)) {
      s_uv.insert(y);
      return true;
    }
  }
  return false;
}
int main() {
  int N, u, v;
  cin >> N >> u >> v;
  u--, v--;
  edge = vector<set<int>>(N);
  for (int i = 0; i < N - 1; i++) {
    int a, b;
    cin >> a >> b;
    a--, b--;
    edge[a].insert(b);
    edge[b].insert(a);
  }
  queue<tuple<int, int, int>> q;
  vector<int> depth(N, 0), part_depth(N, 0);
  q.push({v, -1, 0});
  while (q.size()) {
    int cur, prev, d;
    tie(cur, prev, d) = q.front();
    q.pop();
    depth[cur] = d;
    if (prev >= 0) edge[cur].erase(prev);
    for (int nxt : edge[cur]) {
      q.push({nxt, cur, d + 1});
    }
  }
  {
    vector<bool> used(N, false);
    stack<pair<int, int>> st, tmp;
    st.push({v, -1});
    while (st.size()) {
      int cur, prev;
      tie(cur, prev) = st.top();
      if (used[cur]) {
        st.pop();
        if (prev >= 0)
          part_depth[prev] = max(part_depth[prev], part_depth[cur] + 1);
        continue;
      }
      for (int nxt : edge[cur]) {
        st.push({nxt, cur});
      }
      used[cur] = true;
    }
  }
  recursive(v, u);
  s_uv.insert(v);
  int ans = 0;
  int D = depth[u] - depth[v];
  for (int w : s_uv) {
    if (u == w) continue;
    int d_u = depth[u] - depth[w];
    int d_v = depth[w] - depth[v];
    int d = part_depth[w];
    int cand = 0;
    if (d_u >= d_v)
      cand = (d_u + d_v) / 2;
    else {
      cand = d_v + d - 1;
    }
    ans = max(ans, cand);
  }
  cout << ans << endl;
  return 0;
}
