import std.algorithm;
import std.bigint;
import std.bitmanip;
import std.concurrency : generator = Generator, yield;
import std.container;
import std.conv;
import std.exception;
import std.functional;
import std.format;
import std.math;
import std.meta;
import std.numeric;
import std.random;
import std.range;
import std.stdio;
import std.string;
import std.traits;
import std.typecons;



auto solve(long N, long u, long v, long[] A, long[] B) {
    auto nodes = iota(0, N + 1).map!(i => new Node(i)).array;
    auto edges = chain(
        iota(N - 1).map!(i => new Edge(A[i], B[i])),
        iota(N - 1).map!(i => new Edge(B[i], A[i])),
    ).array;

    auto tree = new Graph!(Node, Edge)(nodes, edges);
    tree.constructTree(v);

    auto uDepth = tree.nodes[u].depth;

    auto n = tree.nodes[u];
    foreach (_; 0 .. (uDepth - 1) / 2) {
        n = n.parent;
    }

    long subTreeDepth = 0;

    void dig(Node node, long depth) {
        subTreeDepth = max(subTreeDepth, depth);
        foreach (c; tree.childrenFrom(node)) {
            dig(c, depth + 1);
        }
    }

    dig(n, 0);

    auto ans = subTreeDepth + (uDepth - 1) / 2;
    if (uDepth % 2 == 0)
        ans++;

    return ans;
}


void main() {
    auto input = stdin.byLine.map!split.joiner;

    long N;
    N = input.front.to!long;
    input.popFront;

    long u;
    u = input.front.to!long;
    input.popFront;

    long v;
    v = input.front.to!long;
    input.popFront;

    long[] A = new long[](cast(size_t) (N-1));
    long[] B = new long[](cast(size_t) (N-1));
    foreach (i; 0 .. cast(size_t) (N-1)) {
        A[i] = input.front.to!long;
        input.popFront;
        B[i] = input.front.to!long;
        input.popFront;
    }

    static if (is(ReturnType!solve == void))
        solve(N, u, v, A, B);
    else {
        auto ans = solve(N, u, v, A, B);

        static if (isFloatingPoint!(ReturnType!solve))
            writeln(format("%.9f", ans));
        else static if (is(ReturnType!solve == bool))
            writeln(ans ? YES : NO);
        else
            writeln(ans);
    }
}



class Edge {
    long from;
    long to;

    this(long from, long to) {
        this.from = from;
        this.to = to;
    }
}

class Node {
    alias id this;
    long id;
    Node parent;
    long depth;
    bool isRoot;

    this(long id) { this.id = id; }
}


class Graph(NodeT = Node, EdgeT = Edge) {
    // from range
    this(NodeT[] nodes, EdgeT[] edges) {
        this.nodes = nodes;
        this.edges = edges;
        this.adj = new AdjacencyList(nodes.length);

        foreach (ref dests; adj)
            dests = make!EdgeList;

        foreach (e; edges) {
            adj[e.from].insert(e);
        }
    }

    auto destsFrom(long from) {
        return adj[from][].map!(e => nodes[e.to]);
    }

    auto edgesFrom(long from) {
        return adj[from][];
    }

    enum isTree =
        __traits(hasMember, NodeT, "isRoot")
        && __traits(hasMember, NodeT, "parent")
        && __traits(hasMember, NodeT, "depth");

    static if (isTree) {
        NodeT root;
        long maxDepth;

        auto childrenFrom(long from) {
            return adj[from][]
                .map!(e => nodes[e.to])
                .filter!(n => n.id != nodes[from].parent.id);
        }

        void constructTree(long root) {
            auto visited = new bool[](nodes.length);

            void dig(NodeT parent) {
                visited[parent] = true;

                foreach (n; destsFrom(parent)) {
                    if (visited[n])
                        continue;
                    n.isRoot = false;
                    n.parent = parent;
                    n.depth = parent.depth + 1;
                    maxDepth = max(maxDepth, n.depth);
                    dig(n);
                }
            }

            auto rootNode = nodes[root];
            this.root = rootNode;
            maxDepth = 0;
            rootNode.isRoot = true;
            rootNode.parent = null;
            rootNode.depth = 0;
            dig(rootNode);
        }
    }

    private:
    alias EdgeList = SList!EdgeT;
    alias AdjacencyList = EdgeList[];
    NodeT[] nodes;
    EdgeT[] edges;
    AdjacencyList adj;
}
