#include <bits/stdc++.h>

using namespace std;

const int OO = 1e9;
const double EPS = 1e-9;

#define ndl cout << '\n'
#define sz(v) int(v.size())
#define pb push_back
#define mp make_pair
#define fs first
#define sc second
#define present(a, x) (a.find(x) != a.end())
#ifdef LOCAL
#define db(...) ({cout << "> Line " << __LINE__  \
		<< ": "; _db(#__VA_ARGS__, __VA_ARGS__);})
#define RNG() rng()
#else
#define db(...) true
#define RNG() true
#endif

template<class T>
void _db(const char *dbStr, T e) {
	cout << dbStr << " = " << e << endl;
}
template<class T, class... L>
void _db(const char *dbStr, T e, L... r) {
  while(*dbStr != ',') cout << *dbStr++;
  cout << " = " << e << ','; _db(dbStr + 1, r...);
}
template<class S, class T>
ostream& operator<<(ostream& o, const map<S, T>& v) {
	o << "["; int i = 0;
	for (const pair<S, T>& pr : v) o << (!i++ ? "" : ", ") << "{"
	<< pr.fs << " : " << pr.sc << "}"; return o << "]";
}
template<template <class, class...> class S, class T, class... L>
ostream& operator<<(ostream& o, const S<T, L...>& v) {
	o << "["; int i = 0;
	for (const auto& e : v) o << (!i++ ? "" : ", ") << e;
	return o << "]";
}
template<class S, class T>
ostream& operator<<(ostream& o, const pair<S, T>& pr) {
	return o << "(" << pr.fs << ", " << pr.sc << ")";
}
ostream& operator<<(ostream& o, const string& s) {
	for (const char& c : s) o << c;
	return o;
}

template<class T> using V = vector<T>;
template<class T> using VV = V<V<T>>;
template<class T> using VVV = VV<V<T>>;
using ll = long long;
using pii = pair<int, int>;
using vi = V<int>;
using vii = V<pii>;
using vvi = VV<int>;
using mii = map<int, int>;
using umii = unordered_map<int, int>;
using si = set<int>;
using usi = unordered_set<int>;


int N, u, v;
vvi adj;

struct LCA {
	int n, LOGN;
	vi lvl, par;	// lvl[root] = 0, par[root] = -1
	vvi P, F;
	int combine(int x, int y) {
		// if x corresponds to path u -> v, y to path v -> w
		// we should return value corresponding to path u -> w
	}
	LCA(int _n, int root) {
		n = _n;
		LOGN = log2(n) + 1;
		lvl.assign(n + 1, 0);
		par.assign(n + 1, -1);
		// P[i][j] = 2^j'th ancestor of i
		P.assign(n + 1, vi(LOGN, -1));
		// F[i][j] = value of some function F corresponding
		// to the path from i to it's 2^j'th ancestor
		F.assign(n + 1, vi(LOGN, -1));
		dfs(root, 0, -1);

		for (int i = 1; i <= n; ++i) {
			P[i][0] = par[i];
			F[i][0] = 0;	// put a value corresponding to
					// a consisting edge par[i]->i
		}

		for (int j = 1; (1 << j) <= n; ++j)
			for (int i = 1; i <= n; ++i)
				if (P[i][j - 1] != -1) {
					P[i][j] = P[P[i][j - 1]][j - 1];
					F[i][j] = combine(F[i][j - 1], F[P[i][j - 1]][j - 1]);
				}
	}
	void dfs(int u, int level, int parent) {
		lvl[u] = level, par[u] = parent;
		for (auto& v : adj[u])
			if (v != parent)
				dfs(v, level + 1, u);
	}
	int query(int u, int v) {
		if (lvl[u] < lvl[v])
			swap(u, v);
		int log = 1;
		while ((1 << log) <= lvl[u])
			++log;
		--log;
		for (int i = log; i >= 0; --i)
			if (lvl[u] - (1 << i) >= lvl[v])
				u = P[u][i];
		if (u == v)
			return u;
		for (int i = log; i >= 0; --i)
			if (P[u][i] != -1 && P[u][i] != P[v][i])
				u = P[u][i], v = P[v][i];
		return par[u];
	}
	int pathQuery(int u, int v) {
		int w = query(u, v);
		int ret = 0;
		int log = 1;
		while ((1 << log) <= lvl[u])
			++log;
		--log;
		for (int i = log; i >= 0; --i)
			if (lvl[u] - (1 << i) >= lvl[w]) {
				// append path P[u][i] -> u
				ret = combine(ret, F[u][i]);
				u = P[u][i];
			}
		log = 1;
		while ((1 << log) <= lvl[v])
			++log;
		--log;
		for (int i = log; i >= 0; --i)
			if (lvl[v] - (1 << i) >= lvl[w]) {
				// append path P[v][i] -> v
				ret = combine(ret, F[v][i]);
				v = P[v][i];
			}
		return ret;
	}
};


int main() {
	#ifdef LOCAL
	auto stTime = clock();
//	freopen("in.txt", "r", stdin);
	mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
	#endif
	ios::sync_with_stdio(false);
	cout.precision(10);
	cin.tie(0);

	cin >> N >> u >> v;

	adj.assign(N + 1, vi());

	for (int i = 1; i <= N - 1; ++i) {
		int A, B;

		cin >> A >> B;

		adj[A].pb(B);
		adj[B].pb(A);
	}

	LCA lca(N, v);

	int mx = -1, steps = -1;

	for (int i = 1; i <= N; ++i) {
		if (i != v && sz(adj[i]) == 1) {
			int w = lca.query(u, i);
			if (lca.lvl[u] - lca.lvl[w] < lca.lvl[w] - lca.lvl[v])
				mx = max(mx, lca.lvl[i]), steps = lca.lvl[u] + lca.lvl[i] - 2 * lca.lvl[w];
		}
	}

	db(mx);

	int curr = mx, oth = steps;

	int ans = steps;

	while (true) {

		if (curr == oth)
			break;

		if (curr == mx)
			--curr;
		else
			++curr;

		if (curr == oth)
			break;

		++oth;

		++ans;

	}


	cout << ans << '\n';

	#ifdef LOCAL
	cout << "\n\n\nExecution time: " <<
		(clock() - stTime) * 1e3 / CLOCKS_PER_SEC << " ms" << endl;
	#endif
    return 0;
}


Measured memory_bytes: 29312