#include <bits/stdc++.h>
using namespace std;
using lint = long long int;
using pint = pair<int, int>;
using plint = pair<lint, lint>;
struct fast_ios { fast_ios(){ cin.tie(0); ios::sync_with_stdio(false); cout << fixed << setprecision(20); }; } fast_ios_;
#define FOR(i, begin, end) for(int i=(begin),i##_end_=(end);i<i##_end_;i++)
#define IFOR(i, begin, end) for(int i=(end)-1,i##_begin_=(begin);i>=i##_begin_;i--)
#define REP(i, n) FOR(i,0,n)
#define IREP(i, n) IFOR(i,0,n)
template<typename T> istream &operator>>(istream &is, vector<T> &vec){ for (auto &v : vec) is >> v; return is; }
template<typename T> ostream &operator<<(ostream &os, const vector<T> &vec){ os << "["; for (auto v : vec) os << v << ","; os << "]"; return os; }
template<typename T> ostream &operator<<(ostream &os, const deque<T> &vec){ os << "deq["; for (auto v : vec) os << v << ","; os << "]"; return os; }
template<typename T> ostream &operator<<(ostream &os, const set<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template<typename T> ostream &operator<<(ostream &os, const unordered_set<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template<typename T> ostream &operator<<(ostream &os, const multiset<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template<typename T> ostream &operator<<(ostream &os, const unordered_multiset<T> &vec){ os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template<typename T1, typename T2> ostream &operator<<(ostream &os, const pair<T1, T2> &pa){ os << "(" << pa.first << "," << pa.second << ")"; return os; }
template<typename TK, typename TV> ostream &operator<<(ostream &os, const map<TK, TV> &mp){ os << "{"; for (auto v : mp) os << v.first << "=>" << v.second << ","; os << "}"; return os; }
template<typename TK, typename TV> ostream &operator<<(ostream &os, const unordered_map<TK, TV> &mp){ os << "{"; for (auto v : mp) os << v.first << "=>" << v.second << ","; os << "}"; return os; }
template<typename T> void ndarray(vector<T> &vec, int len) { vec.resize(len); }
template<typename T, typename... Args> void ndarray(vector<T> &vec, int len, Args... args) { vec.resize(len); for (auto &v : vec) ndarray(v, args...); }
template<typename T> void mmax(T &m, const T q) { if (m < q) m = q; }
template<typename T> void mmin(T &m, const T q) { if (m > q) m = q; }
template<typename T1, typename T2> pair<T1, T2> operator+(pair<T1, T2> &l, pair<T1, T2> &r) { return make_pair(l.first + r.first, l.second + r.second); }
template<typename T1, typename T2> pair<T1, T2> operator-(pair<T1, T2> &l, pair<T1, T2> &r) { return make_pair(l.first - r.first, l.second - r.second); }
#define dbg(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ") " << __FILE__ << endl;

int N, X, Y;
map<int, vector<int>> ab, cd;

vector<int> gen_parent(int N, int root, map<int, vector<int>> &to)
{
    vector<int> res(N, -1);
    queue<pint> q;
    q.push(pint(root, -1));
    while (!q.empty())
    {
        pint pa = q.front();
        q.pop();
        for (auto nxt : to[pa.first]) if (nxt != pa.second)
        {
            res[nxt] = pa.first;
            q.push(pint(nxt, pa.first));
        }
    }
    return res;
}

// 世代をつくる
vector<int> generation(int N, int root, map<int, vector<int>> &to)
{
    vector<int> res(N); // res[root] = 0;
    queue<pint> q;
    q.push(pint(root, -1));
    while(!q.empty())
    {
        pint pa = q.front();
        q.pop();
        if (pa.second >= 0) res[pa.first] = res[pa.second] + 1;
        for (auto nxt : to[pa.first]) if (nxt != pa.second) q.push(pint(nxt, pa.first));
    }
    return res;
}

vector<vector<int>> doubling_parent(const vector<int> &par)
{
    int V = par.size();
    int lnV = 1;
    while ((1 << (lnV - 1)) < V) lnV++;

    vector<vector<int>> res(lnV, vector<int>(V, -1));
    res[0] = par;
    FOR(d, 1, lnV) REP(i, V) if (res[d - 1][i] >= 0) res[d][i] = res[d - 1][res[d - 1][i]];
    return res;
}

pint lowest_common_ancestor(int s, int t, const vector<int> &gen, const vector<vector<int>> &doubling_par)
{
    pint res;
    int d = 0, diff = gen[s] - gen[t];
    if (diff < 0)
    {
        res = lowest_common_ancestor(t, s, gen, doubling_par);
        return pint(res.second, res.first);
    }
    res.first = diff;
    while (diff)
    {
        if (diff & 1) s = doubling_par[d][s];
        d++, diff >>= 1;
    }

    if (s != t)
    {
        int oya = 1;
        IREP(d, doubling_par.size()) if (doubling_par[d][s] != doubling_par[d][t])
        {
            oya += 1 << d;
            s = doubling_par[d][s], t = doubling_par[d][t];
        }
        res.first += oya;
        res.second += oya;
    }
    return res;
}

int nth_parent(int now, int k, const vector<vector<int>> &doubling_par)
{
    int d = 0;
    while (k)
    {
        if (k & 1) now = doubling_par[d][now];
        k >>= 1; d++;
    }
    return now;
}

void minus1()
{
    cout << -1 << endl;
    exit(0);
}

vector<int> gen_cd, par_cd;
vector<vector<int>> doubling_par_cd;
bool is_safe(int x)
{
    for (auto nxt : ab[x])
    {
        pint pa = lowest_common_ancestor(x, nxt, gen_cd, doubling_par_cd);
        if (pa.first + pa.second >= 3) return true;
    }
    return false;
}

int main()
{
    cin >> N >> X >> Y;
    X--;
    Y--;
    REP(_, N - 1)
    {
        int a, b;
        cin >> a >> b;
        ab[a - 1].push_back(b - 1);
        ab[b - 1].push_back(a - 1);
    }
    REP(_, N - 1)
    {
        int c, d;
        cin >> c >> d;
        cd[c - 1].push_back(d - 1);
        cd[d - 1].push_back(c - 1);
    }

    gen_cd = generation(N, Y, cd);
    par_cd = gen_parent(N, Y, cd);
    doubling_par_cd = doubling_parent(par_cd);

    set<int> ni, ni_tmp, Ys;
    ni.insert(X);
    ni_tmp.insert(X);
    Ys.insert(Y);

    int T = 0;
    while (true)
    {
        T += 2;
        set<int> ni_tmptmp;
        for (auto now : ni_tmp)
        {
            if (is_safe(now)) minus1();
            for (auto nxt : ab[now]) if (!ni.count(nxt)) ni.insert(nxt), ni_tmptmp.insert(nxt);
        }
        swap(ni_tmp, ni_tmptmp);

        for (auto y : Ys)
        {
            ni.erase(y), ni_tmp.erase(y);
            for (auto t : cd[y]) ni.erase(t), ni_tmp.erase(t);
        }

        if (ni.empty())
        {
            cout << T << endl;
            return 0;
        }

        set<int> Ys_tmp;
        for (auto y : Ys) for (auto nxt : cd[y]) if (nxt != par_cd[y]) Ys_tmp.insert(nxt);
        swap(Ys, Ys_tmp);
    }
    return 0;
}


Measured memory_bytes: 80180