#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a, long long b) { return b ? gcd(b, a % b) : a; }
const long long dx[4] = {1, 0, -1, 0};
const long long dy[4] = {0, 1, 0, -1};
template <typename T>
istream& operator>>(istream& is, vector<T>& vec) {
  for (T& x : vec) is >> x;
  return is;
}
template <typename T, typename U>
ostream& operator<<(ostream& os, pair<T, U>& pair_var) {
  os << "(" << pair_var.first << ", " << pair_var.second << ")";
  return os;
}
template <typename T>
ostream& operator<<(ostream& os, const vector<T>& vec) {
  os << "{";
  for (long long i = 0; i < vec.size(); i++) {
    os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
  }
  os << "}";
  return os;
}
template <typename T, typename U>
ostream& operator<<(ostream& os, map<T, U>& map_var) {
  os << "{";
  for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
    os << *itr;
    itr++;
    if (itr != map_var.end()) os << ", ";
    itr--;
  }
  os << "}";
  return os;
}
template <typename T>
ostream& operator<<(ostream& os, set<T>& set_var) {
  os << "{";
  for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
    os << *itr;
    itr++;
    if (itr != set_var.end()) os << ", ";
    itr--;
  }
  os << "}";
  return os;
}
void dump_func() { cerr << endl; }
template <class Head, class... Tail>
void dump_func(Head&& head, Tail&&... tail) {
  cerr << head;
  if (sizeof...(Tail) > 0) {
    cerr << ", ";
  }
  dump_func(std::move(tail)...);
}
signed main() {
  long long N, U, V;
  cin >> N >> U >> V;
  U--;
  V--;
  vector<vector<long long>> G(N);
  for (long long i = 0, i_len = (N - 1); i < i_len; ++i) {
    long long a, b;
    cin >> a >> b;
    a--;
    b--;
    G[a].push_back(b);
    G[b].push_back(a);
  }
  vector<long long> dist(N, (1LL << 60));
  vector<bool> seen(N, false);
  queue<long long> q;
  vector<long long> par(N);
  q.push(U);
  seen[U] = true;
  dist[U] = 0;
  while (!q.empty()) {
    long long u = q.front();
    q.pop();
    for (auto v : G[u]) {
      if (seen[v])
        continue;
      else {
        if (dist[u] + 1 < dist[v]) {
          dist[v] = dist[u] + 1;
          par[v] = u;
        }
        if (v == V) continue;
        q.push(v);
        seen[v] = true;
      }
    }
  }
  long long d = dist[V];
  ;
  set<long long> uv;
  long long i = V;
  while (i != U && uv.size() <= d / 2 - 1) {
    i = par[i];
    uv.insert(i);
  }
  uv.insert(V);
  ;
  vector<long long> dist2(N, (1LL << 60));
  vector<bool> seen2(N, false);
  queue<long long> q2;
  vector<long long> par2(N);
  q2.push(U);
  seen2[U] = true;
  if (uv.find(U) != uv.end())
    dist2[U] = (1LL << 60);
  else
    dist2[U] = 0;
  while (!q2.empty()) {
    long long u = q2.front();
    q2.pop();
    for (auto v : G[u]) {
      if (uv.find(v) != uv.end()) continue;
      if (seen2[v])
        continue;
      else {
        if (dist2[u] + 1 < dist2[v]) {
          dist2[v] = dist2[u] + 1;
          par2[v] = u;
        }
        q2.push(v);
        seen2[v] = true;
      }
    }
  };
  long long dd = -(1LL << 60);
  vector<long long> dist_v;
  for (long long i = 0, i_len = (N); i < i_len; ++i) {
    if (dist2[i] == (1LL << 60)) continue;
    if (dist2[i] >= dd) {
      dd = dist2[i];
      dist_v.push_back(i);
    }
  }
  if (dd == -(1LL << 60)) {
    cout << 0 << endl;
    return 0;
  };
  vector<long long> dist3(N, (1LL << 60));
  vector<bool> seen3(N, false);
  queue<long long> q3;
  vector<long long> par3(N);
  q3.push(V);
  seen3[V] = true;
  dist3[V] = 0;
  while (!q3.empty()) {
    long long u = q3.front();
    q3.pop();
    for (auto v : G[u]) {
      if (seen3[v])
        continue;
      else {
        if (dist3[u] + 1 < dist3[v]) {
          dist3[v] = dist3[u] + 1;
          par3[v] = u;
        }
        q3.push(v);
        seen3[v] = true;
      }
    }
  }
  long long max_d = -(1LL << 60);
  for (auto i : dist_v) {
    max_d = max(max_d, dist3[i]);
  }
  cout << max_d - 1 << endl;
}
