#include <bits/stdc++.h>

using namespace std;

void solveA(){
    int n, m ;
    scanf("%d%d", &n, &m);
    char k[n][m];
    int ra_n[n], ra_m[m];
    int factor_delete[n][m];
    for(int i = 0; i < n; ++i)ra_n[i] = 0;
    for(int j = 0; j < m; ++j)ra_m[j] = 0;
    for(int i = 0; i < n; ++i){
        scanf("\n");
        for(int j = 0; j < m; ++j){
            scanf("%c", &k[i][j]);
            //cerr << k[i][j];
        }
    }
    int new_i, new_j;
    int ans = 0;
    int curr = 0;
    for(int i = 0; i < n; ++i){
        for(int j = 0; j < m; ++j){
            new_i = i;
            new_j = j;
            ++new_i;
            ++new_j;
            if(new_i == n)new_i = 0;
            if(new_j == m)new_j = 0;
            if(k[i][j] == k[new_i][new_j] && k[i][j] == k[new_i][j] && k[i][j] == k[i][new_j]){
                ++ra_n[new_i];
                ++ra_m[new_j];
                ++curr;
                factor_delete[i][j] = 1;
            }
            else factor_delete[i][j] = 0;
        }
    }
    for(int i = 0; i < n; ++i){
        new_i = i;
        ++new_i;
        if(new_i == n)new_i = 0;
        curr -= ra_n[new_i];
        for(int j = 0; j < m; ++j){
            new_j = j;
            ++new_j;
            if(new_j == m)new_j = 0;
            curr -= ra_m[new_j];
            ans = max(curr + factor_delete[i][j], ans);
            curr += ra_m[new_j];

        }

        curr += ra_n[new_i];
    }
    cout << ans << endl;
}

inline int ask(int from, int to){
    printf("? %d %d\n", from, to);
    fflush(stdout);
    int ans;
    scanf("%d", &ans);
    return ans;
}

void solveB(){
    int n;
    scanf("%d", &n);
    int k;
    k = ask(1, n);
    int u = 1, l = 1, r = n, mid;
    int ans[n + 1];
    memset(ans, 0, n * sizeof(int));
    ans[0] = k;
    while(u <= n){
            if(u == n){
                ans[n] = k;
                break;
            }
        l = u;
        r = n;
        while(l != r){
            mid = (l + r + 1) / 2;
            if(ask(l, mid) == 1){
                l = mid;
            }
            else r = mid - 1;
            mid = (l + r + 1) / 2;
        }
        //cerr << "MID!:" << mid << endl;
        for(; u <= mid; ++u){
            ans[u] = k;
        }
        --k;
    }
    printf("Ready!\n%d\n", ans[0]);
    fflush(stdout);
    for(int i = 1; i <= n; ++i){
        printf("%d ", ans[i]);
        fflush(stdout);
    }
}

const int MAXK = 5000;

struct worker{
    int STACK;
    vector<int> KR;
    int pred;
    vector<int> PD;
    set<int> child;
};

void solveC(){
    int n, k;
    cin >> n >> k;
    worker m[n+1];
    m[0].pred = -1;
    int up;
    for(int i = 1; i < n; ++i){
        cin >> m[i].pred;
        --m[i].pred;
        m[i].child.insert(i);
        //m[m[i].pred].PD.push_back(i);

    }
    for(int i = 1; i < n; ++i){
        up = m[i].pred;
        while(up != -1){
            m[up].child.insert(i);
            up = m[up].pred;
        }
    }
    int a, b;
    for(int i = 0; i < k; ++i){
        cin >> a >> b;
        --a;
        --b;
        m[a].KR.push_back(i);
        //cerr << a + 1 << " GET : " << i << endl;
        while(/*a != 0 && */m[a].child.find(b) == m[a].child.end()){
            a = m[a].pred;
            //cerr << a + 1 << " GET : " << i << endl;
            m[a].KR.push_back(i);
        }
        //cerr << a << ' ' << b << endl;
        while(a != b){
            //cerr << b << endl;
            //cerr << b + 1 << " GET : " << i << endl;
            m[b].KR.push_back(i);
            b = m[b].pred;
        }
    }
    //cerr << "NB\n";
    int pars[k][k];
    memset(pars, 0, k * k * sizeof(int) );
    for(int i = 0; i < n; ++i){
        for(int j = 0; j < m[i].KR.size(); ++j){
            for(int g = j + 1; g < m[i].KR.size(); ++g){
                    //cerr << "DUPL: in:" << i << " are: ";
                ++pars[m[i].KR[j]][m[i].KR[g]];
                ++pars[m[i].KR[g]][m[i].KR[j]];
            }
        }
    }
    int max_i = 0,max_j = 1;
    for(int i = 0; i < k; ++i){
        for(int j = 0; j < k; ++j){
            if(pars[max_i][max_j] < pars[i][j]){
                max_i = i;
                max_j = j;
            }
        }
    }
    cout << max(pars[max_i][max_j] - 1,0) << endl << max_i + 1 << ' ' << max_j + 1;
}

void deltaa(){
int m, n, l, cost;
    cin >> m >> n >> l;
    string str, buf, buff;
    map<string, int> c;
    set<string> usabl;
    cin >> str;
    int dp[m + 2];
    memset(dp, 127, sizeof(int) * m + sizeof(long long));
    for(int i = 0; i < n; ++i){
        cin >> cost >> buf;
        buff.clear();
        for(int j = 0; j < buf.size(); ++j){
            buff.push_back(buf[j]);
            if(usabl.find(buff) == usabl.end()){
                c[buff] = cost;
                usabl.insert(buff);
                //cerr << buff << endl;
            }
            else{
                c[buff] = min(cost, c[buff]);
                }
        }
        buff.clear();
        for(int j = buf.size() - 1; j >= 0; --j){
            buff = buf[j] + buff;
            if(usabl.find(buff) == usabl.end()){
                c[buff] = cost;
                usabl.insert(buff);
                //cerr << buff << endl;
            }
            else{
                c[buff] = min(cost, c[buff]);
            }
        }
    }
    //for(map<string, int> :: iterator i = c.begin(); i != c.end(); ++i)cerr << (*i).first << " :: " << (*i).second << endl;
    buff.clear();
    cerr << "BUF : " << buff << endl;
    for(int i = 0; i < m; ++i){
        buff.push_back(str[i]);
        if(usabl.find(buff) != usabl.end())dp[i] = c[buff];
    }
    for(int i = 0; i < m; ++i ){
        buff.clear();
        for(int j = i+1; j < m; ++j){
            buff.push_back(str[j]);
            //cerr << i <<  " : str & buf:" << buff << " vl : " << c[buff] <<" &&&&& :" << (usabl.find(buff) != usabl.end()) <<endl;
            if(usabl.find(buff) != usabl.end()){
                //cerr << "UPD : " << j << "  TO : " << dp[j] << " FROM :" << i << " (val:" << dp[i] << ") BY :" << c[buff] << " \n NOW : " << min(dp[j], dp[i] + c[buff]) << endl;
                dp[j] = min(dp[j], dp[i] + c[buff]);
            }
        }
        //cerr << dp[i] << endl;
    }
    if(dp[m - 1] > 127<<24)cout << "-1";
    else cout << dp[m - 1];
}

void solveD(){
    int m, n, l, cost;
    cin >> m >> n >> l;
    scanf("%d%d%d",&m,&n,&l);
    string str, buf, buff;
    map<string, int> c;
    set<string> usabl;
    //cin >> str;
    scanf("%s",&str);
    long long dp[m + 2];
    memset(dp, 127, sizeof(long long) * m + sizeof(long long));
    for(int i = 0; i < n; ++i){
        //cin >> cost >> buf;
        scanf("%d%s",&cost, &buf);
        buff.clear();
        for(int j = 0; j < buf.size(); ++j){
            buff.push_back(buf[j]);
            if(usabl.find(buff) == usabl.end()){
                c[buff] = cost;
                usabl.insert(buff);
                //cerr << buff << endl;
            }
            else{
                c[buff] = min(cost, c[buff]);
                }
        }
        buff.clear();
        for(int j = buf.size() - 1; j >= 0; --j){
            buff = buf[j] + buff;
            if(usabl.find(buff) == usabl.end()){
                c[buff] = cost;
                usabl.insert(buff);
                //cerr << buff << endl;
            }
            else{
                c[buff] = min(cost, c[buff]);
            }
        }
    }
    for(map<string, int> :: iterator i = c.begin(); i != c.end(); ++i)cerr << (*i).first << " :: " << (*i).second << endl;
    buff.clear();
    buff += str[0];
    cerr << "BUF : " << buff << endl;
    if(usabl.find(buff) != usabl.end())dp[1] = c[buff];
    else{
        cout << "-1";
        return;
    }
    dp[0] = 0;
    for(int i = 0; i <= m; ++i ){
        buff.clear();
        for(int j = i + (i == 0); j <= m; ++j){
            buff.push_back(str[j]);
            //cerr << i <<  " : str & buf:" << buff << " vl : " << c[buff] <<" &&&&& :" << (usabl.find(buff) != usabl.end()) <<endl;
            if(usabl.find(buff) != usabl.end()){
                //cerr << "UPD : " << j << "  TO : " << dp[j] << " FROM :" << i << " (val:" << dp[i] << ") BY :" << c[buff] << " \n NOW : " << min(dp[j], dp[i] + c[buff]) << endl;
                dp[j] = min(dp[j], dp[i] + c[buff]);
            }
        }
        cerr << dp[i] << endl;
    }
    if(dp[m] > 127<<24)cout << "-1";
    else cout << dp[m];
}

int main(){
/*
    freopen("video.in", "r", stdin);
    freopen("video.out", "w", stdout);
    solveA();
*/
    //freopen("typing.in", "r", stdin);
    //freopen("typing.out", "w", stdout);

    freopen("twopaths.in", "r", stdin);
    freopen("twopaths.out", "w", stdout);
    solveC();
    return 0;
}
