#include <bits/stdc++.h>
using namespace std;
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) begin(v),end(v)
#define fi first
#define se second
template<typename A, typename B> inline bool chmax(A &a, B b) { if (a<b) { a=b; return 1; } return 0; }
template<typename A, typename B> inline bool chmin(A &a, B b) { if (a>b) { a=b; return 1; } return 0; }
using ll = long long;
using pii = pair<int, int>;
constexpr ll INF = 1ll<<30;
constexpr ll longINF = 1ll<<60;
constexpr ll MOD = 1000000007;
constexpr bool debug = 0;
//---------------------------------//

/*
last-updated: 2019/12/14

LowestCommonAncestor(size_t)
LowestCommonAncestor(vector<vector<int>>, bool isper = true) : isper=falseでbuildしない

void add_edge(int u, int v) : u -> v O(1)
void clear() : クリア
void build(int rootNode) : 構築 O(N log N)
int find(int a, int b) : 頂点 a , 頂点 b の LCA を求める O(log N)
int query(int a, int b) : パス a - b の長さを求める O(log N)
*/

struct LowestCommonAncestor {
public:
	LowestCommonAncestor(std::size_t _size) : _size(_size) {
		g.resize(_size);
		isbuilt = false;
	}
	LowestCommonAncestor(std::vector<std::vector<int> > g, bool isper = true) : g(g) {
		_size = g.size();
		if (isper) build();
	};
	
	void add_edge(int s, int t) {
		g[s].push_back(t);
	}
	
	void clear() {
		_size = 0;
		g.clear();
		par.clear();
		depth.clear();
		isbuilt = false;
	}
	
	void build(int rootNode = 0) {
		logsize = 1;
		while (1<<logsize < _size) ++logsize;
		depth.resize(_size, -1);
		par.resize(logsize, std::vector<int>(_size, -1));
		
		depth[rootNode] = 0;
		dfs(rootNode, -1);
		for (int i = 1; i < logsize; ++i) {
			for (int j = 0; j < _size; ++j) {
				if (~par[i - 1][j]) par[i][j] = par[i - 1][ par[i - 1][j] ];
			}
		}
		isbuilt = true;
	}
	
	int find(int a, int b) {
		assert(isbuilt);
		if (depth[a] < depth[b]) std::swap(a, b);
		
		int up = depth[a] - depth[b];
		for (int i = 0; i < logsize; ++i) if (up >> i & 1) a = par[i][a];
		if (a == b) return a;
		for (int i = logsize - 1; i >= 0; i--) {
			if (par[i][a] != par[i][b]) {
				a = par[i][a];
				b = par[i][b];
			}
		}
		return par[0][a];
	}
	
	int query(int a, int b) {
		assert(isbuilt);
		return depth[a] + depth[b] - 2 * depth[find(a, b)];
	}
	
private:
	std::size_t _size, logsize;
	std::vector<std::vector<int> > g, par;
	std::vector<int> depth;
	bool isbuilt;
	
	void dfs(int u, int p) {
		for (int v : g[u]) {
			if (v == p) continue;
			depth[v] = depth[u] + 1;
			par[0][v] = u;
			dfs(v, u);
		}
	}
};

int N, U, V;
std::vector<std::vector<int> > g;
int depth[212345];

int dfs(int u, int par) {
	int &res = depth[u];
	res = 0;
	for (int v : g[u]) if (v != par) {
		chmax(res, dfs(v, u) + 1);
	}
	return res;
}

int solve(int d, int u) {
	if (d == 0) return 0;
	int res = depth[u];
	// 上
	if (d <= 1) return res;
	res++;
	d -= 2;
	
	// 下, 上
	int x = d / 2;
	res += x * 2;
	return res;
}

int main() {
	cin >> N >> U >> V;
	U--; V--;
	g.resize(N);
	
	REP(i, N - 1) {
		int A, B;
		scanf("%d %d", &A, &B);
		A--; B--;
		g[A].push_back(B);
		g[B].push_back(A);
	}
	
	LowestCommonAncestor lca(g, false);
	lca.build(V);
	dfs(V, -1);
	
	int curD = lca.query(U, V);
	int ans = solve(curD, U), cur = 0;
	
	while (curD > 0) {
		for (int v : g[U]) {
			if (lca.find(v, U) == v) {
				U = v;
				break;
			}
		}
		--curD;
		if (curD == 0) break;
		
		for (int v : g[V]) {
			int lc = lca.find(U, v);
			if (lc == v) {
				V = v;
				break;
			}
		}
		--curD;
		++cur;
		
		chmax(ans, cur + solve(curD, U));
	}
	cout << ans << endl;
	
	
	return 0;
}


Measured memory_bytes: 23256