#include <bits/stdc++.h>
#define TASK "twopaths"

#define sz(x) ((int)((x).size()))

using namespace std;

typedef pair < int , int > ipair;

const int N = 200179;
const int D = 18;
const int IINF = 0x3f3f3f3f;

int n, k;
int ansN = 0, ansA = 0, ansB = 1;

struct Person
{
    int dep;
    int up[D];
    ipair maxUp = {0, -1}, maxUp1 = {0, -1};
    vector < int > e;
    vector < int > ht;
    int tin;
} a[N];

struct Crr
{
    int a, b;
} c[N];

void dfs1(int v, int dep = 0)
{
    static int ctin = 0;
    a[v].dep = dep;
    a[v].tin = ctin++;
    for (int i = 1; i < D; ++i)
    {
        int prv = a[v].up[i - 1];
        if (prv == -1)
            a[v].up[i] = -1;
        else
            a[v].up[i] = a[prv].up[i - 1];
    }
    for (int nv : a[v].e)
        dfs1(nv, dep + 1);
}

int lcp(int x, int y)
{
    if (a[x].dep < a[y].dep)
        swap(x, y);
    int ost = a[x].dep - a[y].dep;
    for (int d = D - 1; d >= 0; --d)
        if (ost >= (1 << d))
        {
            ost -= (1 << d);
            x = a[x].up[d];
        }
    if (x == y)
        return x;
    for (int d = D - 1; d >= 0; --d)
    {
        int nx = a[x].up[d];
        int ny = a[y].up[d];
        if (nx != ny)
        {
            x = nx;
            y = ny;
        }
    }
    return a[x].up[0];
}

ipair dfs2(int v)
{
    ipair res = a[v].maxUp, res1 = a[v].maxUp1;
    for (int nv : a[v].e)
    {
        ipair q = dfs2(nv);
        if (q.first <= 1)
            q = {0, -1};
        else
            --q.first;
        if (q > res)
        {
            res1 = res;
            res = q;
        } else if (q > res1)
            res1 = q;
    }
    if (res1.first > ansN)
    {
        ansN = res1.first;
        ansA = res.second;
        ansB = res1.second;
    }
    return res;
}

int stlen[N];
class SparseTable
{
    vector < ipair > t[N];
public:
    void init(int n, int * a)
    {
        t[0].clear();
        for (int i = 0; i < n; ++i)
            t[0].emplace_back(a[i], i);
        for (int d = 1; d < D; ++d)
        {
            t[d].clear();
            for (int i = 0; i + (1 << d) <= n; ++i)
                t[d].push_back(min(t[d-1][i], t[d-1][i + (1 << (d-1))]));
        }
    }

    ipair getMin(int l, int r)
    {
        int len = r - l + 1;
        int ss = stlen[len];
        return min(t[ss][l], t[ss][r - (1 << ss) + 1]);
    }
} st;

struct MCrr
{
    int pos1, pos2, num;
    bool operator < (const MCrr & b) const
    {
        return pos1 < b.pos1;
    }
};
vector < MCrr > mcs;

void go(int cl, int cr)
{
    if (cl == cr)
        return;
    ipair mid = st.getMin(cl, cr - 1);
    int midPos = mid.second;
    go(cl, midPos);
    go(midPos + 1, cr);

    int k1l = lower_bound(mcs.begin(), mcs.end(), MCrr({cl, 0, 0})) - mcs.begin();
    int k1r = lower_bound(mcs.begin(), mcs.end(), MCrr({midPos + 1, 0, 0})) - mcs.begin();
    int k2l = k1r;
    int k2r = lower_bound(mcs.begin(), mcs.end(), MCrr({cr + 1, 0, 0})) - mcs.begin();

    if (k1r - k1l > k2r - k2l)
    {
        swap(k1l, k2l);
        swap(k1r, k2r);
    }

    for (int i = k1l; i < k1r; ++i)
    {
        int j = lower_bound(mcs.begin() + k2l, mcs.begin() + k2r, mcs[i]) - mcs.begin();
        if (j != k2r)
        {
            int r1 = mcs[i].pos2;
            int r2 = mcs[j].pos2;
            if (r1 > r2)
                swap(r1, r2);
            int cans = mid.first + st.getMin(r1, r2 - 1).first;
            if (cans > ansN)
            {
                ansN = cans;
                ansA = mcs[i].num;
                ansB = mcs[j].num;
            }
        }
    }
}

int c2mc[N];
void solve(int n, int * p, int * a)
{
    if (n == 0)
        return;
    for (int i = 0; i < n*2; ++i)
        if (c2mc[p[i]] == -1)
        {
            c2mc[p[i]] = sz(mcs);
            mcs.push_back({i, -1, p[i]});
        } else
            mcs[c2mc[p[i]]].pos2 = i;

    sort(mcs.begin(), mcs.end());
    st.init(n*2 - 1, a);

    go(0, n*2 - 1);

    for (int i = 0; i < n*2; ++i)
        c2mc[p[i]] = -1;
}

void dfs3(int v)
{
    for (int nv : a[v].e)
        dfs3(nv);
    static int qp[N*2], qa[N*2];
    int sht = sz(a[v].ht);
    for (int i = 0; i < sht; ++i)
        qp[i*2] = (qp[i*2+1] = a[v].ht[i]) + N;
    sort(qp, qp + sht*2, [](int x, int y)
    {
        return a[x >= N ? c[x - N].b : c[x].a].tin < a[y >= N ? c[y - N].b : c[y].a].tin;
    });
    for (int i = 0; i < sht*2 - 1; ++i)
        qa[i] = a[lcp(qp[ i ] >= N ? c[qp[ i ] - N].b : c[qp[ i ]].a,
                      qp[i+1] >= N ? c[qp[i+1] - N].b : c[qp[i+1]].a)].dep - a[v].dep;
    for (int i = 0; i < sht*2; ++i)
        if (qp[i] >= N)
            qp[i] -= N;
    solve(sht, qp, qa);
}

int main()
{
#ifndef LOCAL
    freopen(TASK".in", "r", stdin);
    freopen(TASK".out", "w", stdout);
#endif
    ios::sync_with_stdio(false);
    memset(c2mc, -1, sizeof(c2mc));

    for (int i = 1; i < N; ++i)
        for (int j = D - 1; j >= 0; --j)
            if (i >= (1 << j))
            {
                stlen[i] = j;
                break;
            }

    cin >> n >> k;
    a[0].up[0] = -1;
    for (int i = 1; i < n; ++i)
    {
        cin >> a[i].up[0];
        --a[i].up[0];
        a[a[i].up[0]].e.push_back(i);
    }
    for (int i = 0; i < k; ++i)
    {
        cin >> c[i].a >> c[i].b;
        --c[i].a;
        --c[i].b;
    }

    dfs1(0);
    for (int i = 0; i < k; ++i)
    {
        int ca = c[i].a;
        int cb = c[i].b;
        int p = lcp(ca, cb);
        ipair q;
        q = {a[ca].dep - a[p].dep, i};
        if (q > a[ca].maxUp)
        {
            a[ca].maxUp1 = a[ca].maxUp;
            a[ca].maxUp = q;
        } else if (q > a[ca].maxUp1)
            a[ca].maxUp1 = q;
        q = {a[cb].dep - a[p].dep, i};
        if (q > a[cb].maxUp)
        {
            a[cb].maxUp1 = a[cb].maxUp;
            a[cb].maxUp = q;
        } else if (q > a[cb].maxUp1)
            a[cb].maxUp1 = q;
        a[p].ht.push_back(i);
    }

    dfs2(0);
    dfs3(0);

    cout << ansN << "\n" << ansA + 1 << " " << ansB + 1 << "\n";


    return 0;
}
