#include <iostream>
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <string>
#include <tuple>
#include <time.h>

using namespace std;

#define vec vector
#define ALL(x) (x).begin(), (x).end()
#define mp make_pair

typedef pair< int, int > pii;

const int LOG = 21;
const int inf = 1000 * 1000 * 1000;

int n, k, timer = 0;
vec< int > p, pid, h, tin, tout, _lca, euler, first, _log;
vec< vec< pii > > g;
vec< pii > que, rmq[LOG];

void dfs(int v, int par = -1, int H = 0) {
	h[v] = H;
	tin[v] = timer++;
	euler.push_back(v);
	for (auto to : g[v]) {
		if (to.first != par) {
			dfs(to.first, v, H + 1);
			euler.push_back(v);
		}
	}
	tout[v] = timer++;
}

void read() {
	scanf("%d %d", &n, &k);
	p.resize(n + 1, -1);
	g.resize(n + 1);
	pid.resize(n + 1, -1);

	for (int cur = 0, i = 2; i <= n; i++) {
		scanf("%d", &p[i]);
		g[i].push_back(mp(p[i], cur));
		g[p[i]].push_back(mp(i, cur));
		pid[i] = cur;
		cur++;
	}

	for (int u, v, i = 0; i < k; i++) {
		scanf("%d %d", &u, &v);
		que.push_back(mp(u, v));
	}



	h.resize(n + 1);
	tin.resize(n + 1);
	tout.resize(n + 1);
	dfs(1);

	for (int i = 0; i < LOG; i++) {
		rmq[i].resize((int)euler.size(), mp(inf, -1));
	}

	first.resize(n + 1, -1);
	for (int i = 0; i < (int)euler.size(); i++) {
		int u = euler[i];
		if (first[u] == -1) first[u] = i;
		rmq[0][i] = mp(h[u], u);
	}

	for (int i = 1; i < LOG; i++) {
		for (int j = 0; j + (1 << (i - 1)) < (int)euler.size(); j++) {
			rmq[i][j] = min(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]);
		}
	}

	_log.resize((int)euler.size() + 1);
	
	int cur = 0;
	while ((1 << cur) <= (int)euler.size()) cur++;
	for (int i = (int)euler.size(); i >= 1; i--) {
		if ((1 << cur) > i) cur--;
		_log[i] = cur;
	}
}

int lca(int u, int v) {
	int l, r;
	l = first[u];
	r = first[v];
	if (l > r) swap(l, r);
	pii res = mp(inf, -1);
	int LG = _log[r - l + 1];
	res = min(res, rmq[LG][l]);
	res = min(res, rmq[LG][r - (1 << LG) + 1]);
	return res.second;
}

int dist(int u, int v) {
	return h[u] + h[v] - 2 * h[lca(u, v)];
}

bool inTree(int root, int son) {
	return tin[root] <= tin[son] && tout[son] <= tout[root];
}

int check(int i, int j) {
	int u1, v1, u2, v2, lca1, lca2, tmp, U, V;
	u1 = que[i].first;
	v1 = que[i].second;
	lca1 = _lca[i];
	u2 = que[j].first;
	v2 = que[j].second;
	lca2 = _lca[j];

	if (!inTree(lca1, lca2) && !inTree(lca2, lca1)) return 0;

	tmp = 0;

	// u1 u2

	int maslca[2] = { lca1, lca2 };
	vec< int > way[2];

	way[0].push_back(u1);
	way[0].push_back(v1);
	way[1].push_back(u2);
	way[1].push_back(v2);

	int F, S;
	F = lca1;
	S = lca2;

	if (h[F] > h[S]) swap(F, S);

	for (int k1 = 0; k1 < 2; k1++) {
		for (int k2 = 0; k2 < 2; k2++) {
			int big = lca(way[0][k1], way[1][k2]);
			if (inTree(S, big) && inTree(F, S)) tmp += h[big] - h[S];
		}
	}

	return tmp;
}

void sol() {
	int res = -1, a1, a2;

	for (int tmp, i = 0; i < k; i++) {
		for (int j = i + 1; j < k; j++) {
			tmp = check(i, j);
			if (res < tmp) {
				res = tmp;
				a1 = i + 1;
				a2 = j + 1;
			}
		}
	}
	printf("%d\n%d %d", res, a1, a2);
}

void precalc() {
	for (int i = 0; i < k; i++) {
		_lca.push_back(lca(que[i].first, que[i].second));
	}
}

bool bambook() {
	for (auto it : que) {
		if (!inTree(it.first, it.second) && !inTree(it.second, it.first))
			return 0;
	}
	return 1;
}

void solbambook() {
	vec< pii > seg;

}

const int delt = 1000;

void randomsolve() {
	int res = -1;
	int a1, a2;

	vec< int > perm(k);
	for (int i = 0; i < k; i++) perm[i] = i;
	random_shuffle(ALL(perm));
	for (int i = 0; i < k; i++) {
		int u = perm[i];
		for (int c = 0, j = 0; c < delt; c++, j = (j + 1) % k) {
			if (i == j) continue;
			int v = perm[j];
			int tmp = check(u, v);
			if (tmp > res) {
				res = tmp;
				a1 = u + 1;
				a2 = v + 1;
			}
		}
	}
	printf("%d\n%d %d", res, a1, a2);
}

bool solve() {

	srand(time(NULL));

	freopen("twopaths.in", "r", stdin);
	freopen("twopaths.out", "w", stdout);

	read();
	precalc();

	randomsolve();

	if (bambook()) {
		solbambook();
		return true;
	}

	return true;
}

int main() {

	//while (solve());
	solve();

	return 0;
}