#include <algorithm>
#include <fstream>
#include <iostream>
#include <vector>
#include <cassert>
#include <unordered_set>
#include <string>
#include <map>
#include <set>

using namespace std;

vector<int> tin;

int t = 0;

struct que
{
	int a, lca, id;
	que(int a, int lca, int id)
		: a(a), lca(lca), id(id)
	{}
};

struct cmp_tin
{
	bool operator()(que a, que b)
	{
		if (tin[a.a] != tin[b.a])
			return tin[a.a] < tin[b.a];
		//assert(a.id != b.id);
		return a.id < b.id;
	}
};

vector<vector<que>> ques;

vector<vector<int>> children;

vector<int> d;

void dfs(int u)
{
	for (int v : children[u])
		d[v] = d[u] + 1, dfs(v);
	tin[u] = t++; // haha, it is tout, not tin
}

vector<vector<int>> ups;

int SZ = 20;

int go_up(int a, int cnt)
{
	for (int i = SZ - 1; i >= 0; --i)
		if (d[a] - (1 << i) >= cnt)
			a = ups[i][a];
	return a;
}

int get_lca(int a, int b)
{
	if (d[a] < d[b])
		swap(a, b);
	for (int i = SZ - 1; i >= 0; --i)
		if (d[a] - (1 << i) >= d[b])
			a = ups[i][a];
	for (int i = SZ - 1; i >= 0; --i)
		if (ups[i][a] != ups[i][b])
			a = ups[i][a], b = ups[i][b];
	return a == b ? a : ups[0][a];
}

int mx = -1, mxi = -1, mxj = -1;

vector<int> as, bs;

vector<int> lcas;


struct cmp_tin_b
{
	bool operator ()(int a, int b)
	{
		if (lcas[a] != lcas[b])
			return lcas[a] < lcas[b];
		if (tin[bs[a]] != tin[bs[b]])
			return tin[bs[a]] < tin[bs[b]];
		return a < b;
	}
};
set<que, cmp_tin> st;

vector<vector<int>> witha;

set<int, cmp_tin_b> subtree;

void solve_dfs(int u)
{
	//for (auto x : witha[u])
		//subtree.erase(x);
	/*for (auto x : witha[u])
	{
		auto it = subtree.lower_bound(x);
		if (it != subtree.end() && lcas[*it] == lcas[x])
		{
			int y = *it;
			int lca = get_lca(bs[x], bs[y]);
			int ans = d[as[x]] + d[lca] - d[lcas[x]] * 2;
			if (ans > mx)
				mx = ans, mxi = x, mxj = y;
		}
		if (it != subtree.begin() && lcas[*(--it)] == lcas[x])
		{
			int y = *it;
			int lca = get_lca(bs[x], bs[y]);
			int ans = d[as[x]] + d[lca] - d[lcas[x]] * 2;
			if (ans > mx)
				mx = ans, mxi = x, mxj = y;
		}
	}*/
	//And now this hacking part;
	for (int i = 0; i < ques[u].size(); ++i)
		for (int j = 0; j < i; ++j)
		{
			if (ques[u][i].id == ques[u][j].id)
				continue;
			int lca1 = get_lca(as[ques[u][i].id], as[ques[u][j].id]);
			int lca2 = get_lca(bs[ques[u][i].id], bs[ques[u][j].id]);
			if (d[lca1] + d[lca2] - 2 * d[u] > mx)
				mx = d[lca1] + d[lca2] - 2 * d[u], mxi = ques[u][i].id, mxj = ques[u][j].id;
		}
	for (que q : ques[u])
	{
		auto it = st.lower_bound(q);
		if (it != st.end())
		{
			int lca = get_lca(q.a, it->a);
			if (d[lca] - d[u] > mx)
				mx = d[lca] - d[u], mxi = q.id, mxj = it->id;
		}
		if (it != st.begin())
		{
			--it;
			int lca = get_lca(q.a, it->a);
			if (d[lca] - d[u] > mx)
				mx = d[lca] - d[u], mxi = q.id, mxj = it->id;
		}
	}
	for (que q : ques[u])
		st.insert(q);
	for (auto v : children[u])
		solve_dfs(v);
	for (que q : ques[u])
		st.erase(q);
}


struct cmp1
{
	bool operator()(int a, int b)
	{
		return d[bs[a]] < d[bs[b]];
	}
};

int main()
{
	ifstream cin("twopaths.in");
	ofstream cout("twopaths.out");
	int n, k; cin >> n >> k;
	vector<int> p(n);
	children.resize(n);
	d.resize(n);
	tin.resize(n);
	p[0] = 0;
	for (int i = 1; i < n; ++i)
		cin >> p[i], --p[i], children[p[i]].push_back(i);
	ups = vector<vector<int>>(20, vector<int>(n));
	ups[0] = p;
	for (int i = 1; i < SZ - 1; ++i)
		for (int j = 0; j < n; ++j)
			ups[i][j] = ups[i - 1][ups[i - 1][j]];
	dfs(0);
	vector<vector<que>> ques1(n);
	vector<vector<que>> ques2(n);
	lcas.resize(n);
	vector<vector<que>> ques3(n);
	as.resize(k);
	bs.resize(k);
	witha.resize(n);
	vector<vector<pair<int, int>>> ones(n);
	map<pair<int, int>, vector<int>> twos;
	for (int i = 0; i < k; ++i)
	{
		int a, b; cin >> a >> b;
		--a, --b;
		if (tin[a] > tin[b])
			swap(a, b);
		as[i] = a;
		bs[i] = b;
		witha[a].push_back(i);
		int lca = get_lca(a, b);
		lcas[i] = lca;
		ques1[lca].push_back(que(a, lca, i));
		ques2[lca].push_back(que(b, lca, i));
		ques3[lca].push_back(que(a, lca, i));
		ques3[lca].push_back(que(b, lca, i));
		int a1 = go_up(a, d[a] - d[lca] - 1);
		int b1 = go_up(b, d[b] - d[lca] - 1);
		/*
		ones[a1].push_back({ i, a });
		ones[b1].push_back({ i, b });
		if (a != lca && b != lca)
			twos[{a1, b1}].push_back(i);
		*/
	}
	//for (int i = 0; i < k; ++i)
		//subtree.insert(i);
	ques = ques1;
	solve_dfs(0);
	ques = ques2;
	st.clear();
	solve_dfs(0);
	ques = ques3;
	st.clear();
	solve_dfs(0);
	cerr << mx << endl;
	auto cmp = [&](pair<int, int> a, pair<int, int> b) 
	{
		return d[a.second] < d[b.second];
	};
	/*for (int i = 0; i < n; ++i)
	{
		if (ones[i].size() < 2)
			continue;
		auto it = max_element(ones[i].begin(), ones[i].end(), cmp);
		int iti = it->first;
		ones[i].erase(it);
		auto it1 = max_element(ones[i].begin(), ones[i].end(), cmp);
		int ans = d[it1->second] - d[i];
		if (ans > mx)
			mx = ans, mxi = iti, mxj = it1->first;
	}
	for (auto& p : twos)
	{
		int par = ups[0][p.first.first];
		vector<int> vec = p.second;
		sort(vec.begin(), vec.end(), [&](int a, int b) {return d[as[a]] < d[as[b]]; });
		int curmx = vec.back();
		for (int i = (int)vec.size() - 2; i >= 0; --i)
		{
			int ans = d[as[vec[i]]] + min(d[bs[curmx]], d[bs[vec[i]]]) - d[par] * 2;
			if (ans > mx)
				mx = ans, mxi = vec[i], mxj = curmx;
			if (d[bs[vec[i]]] > d[bs[curmx]])
				curmx = vec[i];
		}
	}*/
	cout << mx << endl;
	cout << mxi + 1 << ' ' << mxj + 1 << endl;

}