// グラフ
#include <bits/stdc++.h>
using namespace std;
#define int long long
using P = pair<int, int>;
constexpr array<int, 4> dx = {1, 0, -1, 0};
constexpr array<int, 4> dy = {0, 1, 0, -1};
constexpr int INF = 1010101010;
constexpr int MOD = 1000000000 + 7;
// constexpr int MOD = 998244353;
template <class T>
bool chmax(T &a, const T &b)
{
    if (a < b)
    {
        a = b;
        return 1;
    }
    return 0;
}
template <class T>
bool chmin(T &a, const T &b)
{
    if (b < a)
    {
        a = b;
        return 1;
    }
    return 0;
}
constexpr int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
constexpr int fact(int n) { return n > 1 ? n * fact(n - 1) % MOD : 1; }
int modinv(int a)
{
    int b = MOD, u = 1, v = 0;
    while (b)
    {
        int t = a / b;
        a -= t * b;
        swap(a, b);
        u -= t * v;
        swap(u, v);
    }
    u %= MOD;
    if (u < 0)
        u += MOD;
    return u;
}
constexpr int modpow(int a, int n)
{
    int rtn = 1;
    while (n > 0)
    {
        if (n & 1)
            rtn = rtn * a % MOD;
        a = a * a % MOD;
        n >>= 1;
    }
    return rtn;
}

int tkhs, aoki;

// 升目マップを探索する
class Graph
{
private:
    int _n;
    // エッジ（ノードとノードをつなぐ辺）
    struct Edge
    {
        int to;       // 終点のノード番号
        int cost = 1; // エッジのコスト
    };
    vector<vector<Edge>> _edges; // _edges[i] ノードiから伸びるエッジの集合
    vector<int> _dist;           // ノードの距離を記録

public:
    // コンストラクタ ノード数nを渡す
    Graph(int n);
    ~Graph();
    void uniteNodes(int one, int another, int cost);
    // スタック使用深さ優先探索する 木ならtrue
    int depthFirstSearch(const int start);
    int maxDist(); // 木（閉路を持たない）の数を返す
};

Graph::Graph(int n) : _n(n)
{
    _edges.resize(_n);
    _dist.resize(_n, INF);
}

Graph::~Graph()
{
}

void Graph::uniteNodes(int one, int another, int cost = 1)
{
    _edges[one].push_back({another, cost});
    _edges[another].push_back({one, cost});
}

int Graph::depthFirstSearch(const int start)
{
    // 今後探索するノードを記録するスタック
    stack<int> destination;

    int dist_tkhs_aoki;

    // 最初にスタートを探索した
    destination.push(start);
    _dist[start] = 0;

    // 全てのノードを探索
    while (!destination.empty())
    {
        // スタックから調べる升を取り出す
        const int p = destination.top();
        destination.pop();

        for (auto &&edge : _edges[p])
        {
            // np: 今探索している隣接ノードのノード番号
            const int np = edge.to;
            // npをすでに探索していない
            if (_dist[np] == INF)
            {
                destination.push(np);
                _dist[np] = _dist[p] + 1;
                if (np == tkhs)
                {
                    stack<int> stemp;
                    destination = stemp;
                    dist_tkhs_aoki = _dist[p] + 1;
                    destination.push(np);
                    break;
                }
                // npを今後調べるノードとしてスタックに積む
                // npを探索したと記録する
            }
        }
    }

    const int dist_max = maxDist();
    return dist_max - 1;
}

int Graph::maxDist()
{
    int max_dist = -1;
    for (int i = 0; i < _n; i++)
        if (_dist[i] != INF)
            chmax(max_dist, _dist[i]);

    return max_dist;
}

signed main()
{
    cin.tie(0);
    ios::sync_with_stdio(0);
    cout << setprecision(10);

    int n;
    cin >> n;
    cin >> tkhs >> aoki;
    tkhs--;
    aoki--;
    Graph g(n);
    for (int i = 0; i < n; i++)
    {
        int u, v;
        cin >> u >> v;
        g.uniteNodes(u - 1, v - 1);
    }

    cout << g.depthFirstSearch(aoki) << endl;
}
