#define NDEBUG

#include <unordered_map>
#include <functional>
#include <algorithm>
#include <iostream>
#include <cassert>
#include <cstring>
#include <iomanip>
#include <utility>
#include <numeric>
#include <string>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <tuple>
#include <set>
#include <map>

// [0, max)
#define FOR0(var, max) for (sl (var) = 0; (var) < (max); ++(var))
// [min, max)
#define FORi(var, min, max) for (sl (var) = (min); (var) < (max); ++(var))
// [min, max)
#define FORi_INV(var, min, max) for (sl (var) = (max) - 1; (var) + 1 > (min); --(var))

#define FORITER(var, iter) for (auto (iter) = (var).begin(); (iter) != (var).end(); (iter)++)
#define FORITER_INV(var, iter) for (auto (iter) = (var).rbegin(); (iter) != (var).rend(); (iter)++)

// a < b < c
#define LTLT(a, b, c) (((a) < (b)) && ((b) < (c)))
// a <= b < c
#define LELT(a, b, c) (((a) <= (b)) && ((b) < (c)))
// a < b <= c
#define LTLE(a, b, c) (((a) < (b)) && ((b) <= (c)))
// a <= b <= c
#define LELE(a, b, c) (((a) <= (b)) && ((b) <= (c)))

#ifndef NDEBUG
#  define MASSERT(cond) m_assert(cond, __LINE__, #cond);
#else
#  define MASSERT(...)
#endif

using namespace std;

using uc = unsigned char;
using ui = unsigned int;
using ul = unsigned long long int;

using sc = signed char;
using si = signed int;
using sl = signed long long int;

using ld = long double;

void m_assert(const bool& cond, const sl& line, const char *condstr) {
  if (!cond) {
    cerr << "Assertion Failed: " << condstr << " at line " << line << endl;
    exit(1);
  }
}

template <class T>
struct DirectedEdge {
  sl to;
  T cost;

  DirectedEdge(const sl& _to, const T& _cost) : to(_to), cost(_cost) {}
};

template <class T>
struct Dijkstra {
  constexpr static sl INF = numeric_limits<T>::max() >> 1;
  vector<T> distance;
  vector<sl> prev;

  Dijkstra(const sl& N, const sl& start, const vector<vector<DirectedEdge<T>>>& edges) {
    priority_queue<pair<T, sl>, vector<pair<T, sl>>, greater<pair<T, sl>>> que;
    distance.resize(N);
    prev.resize(N);
    FOR0(i, N) {
      if (i == start) {
        distance[start] = 0;
        prev[start] = start;
      } else {
        distance[i] = INF;
        prev[i] = numeric_limits<sl>::max();
      }
      que.emplace(distance[i], i);
    }
    while (!que.empty()) {
      auto u = que.top().second;
      que.pop();
      FORITER(edges[u], it) {
        sl v = it->to;
        T new_cost = distance[u] + it->cost;
        if (distance[v] > new_cost) {
          distance[v] = new_cost;
          prev[v] = u;
          que.emplace(new_cost, v);
        }
      }
    }
  }
};

static sl N, U, V;
vector<vector<DirectedEdge<sl>>> E;

void solve(void) {
  Dijkstra<sl> d(N, V, E); // from Aoki
  Dijkstra<sl> e(N, U, E); // from Takahashi
  if (U == V || (E[U].size() == 1 && E[U][0].to == V)) {
    cout << 0 << endl;
    return;
  }
  sl max_cost = 0;
  FOR0(i, N) {
    if (d.distance[i] > e.distance[i]) {
      max_cost = max(max_cost, d.distance[i]);
    }
  }
  cout << max_cost - 1 << endl;
}

int main(void) {
  cin >> N >> U >> V;
  U -= 1;
  V -= 1;
  E.resize(N);
  sl A, B;
  FOR0(i, N - 1) {
    cin >> A >> B;
    A -= 1;
    B -= 1;
    E[A].emplace_back(B, 1);
    E[B].emplace_back(A, 1);
  }
  solve();
  return 0;
}

Measured memory_bytes: 15380