#define _CRT_SECURE_NO_WARNINGS
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<set>
#include<cassert>
#include<vector>
#include<map>
using namespace std;
const int MAXN = 100 * 1007, LOGMAX = 20;
const int INF = (int)1e9;
vector<int>g[MAXN];
bool used[MAXN];
int tin[MAXN], tout[MAXN];
int depth[MAXN];
int p[MAXN][LOGMAX + 1];
int timer = 1;
int pu[MAXN], pv[MAXN];
int ptype[MAXN];
vector<int>add[MAXN], del[MAXN];
vector<int>del2[MAXN];
vector<int>add2[MAXN];
void dfs(int v, int parent, int h)
{
	used[v] = true;
	tin[v] = timer;
	depth[v] = h;
	timer++;
	p[v][0] = parent;
	for (int i = 1; i <= LOGMAX; i++)
	{
		p[v][i] = p[p[v][i - 1]][i - 1];
	}
	for (int i = 0; i < (int)g[v].size(); i++)
	{
		int to = g[v][i];
		if (!used[to])
		{
			dfs(to, v, h + 1);
		}
	}
	tout[v] = timer;
	timer++;
}
bool isAncestor(int u, int v) // u - ancestor of v
{
	return tin[u] <= tin[v] && tout[u] >= tout[v];
}
int getLCA(int u, int v)
{
	if (isAncestor(u, v)) return u;
	if (isAncestor(v, u)) return v;
	for (int i = LOGMAX; i >= 0; i--)
	{
		if (!isAncestor(p[u][i], v))
		{
			u = p[u][i];
		}
	}
	return p[u][0];
}
int getoLCA(int u, int v)
{
	for (int i = LOGMAX; i >= 0; i--)
	{
		if (!isAncestor(p[u][i], v))
		{
			u = p[u][i];
		}
	}
	return u;
}
struct Path
{
	int gol, gor;
	int lenl, lenr;
	int id;
	void norm()
	{
		if (gol > gor)
		{
			swap(gol, gor);
			swap(lenl, lenr);
		}
	}
};
bool operator<(Path x, Path y)
{
	if (x.gol != y.gol) return x.gol < y.gol;
	if (x.gor != y.gor) return x.gor < y.gor;
	if (x.lenl != y.lenl) return x.lenl > y.lenl;
	return x.lenr > y.lenr;
}
struct Tdata
{
	set<pair<int, int> >have;
	Tdata()
	{
		have = set<pair<int, int> >();
	}
	void add(pair<int, int>a)
	{
		have.insert(a);
	}
	void del(pair<int, int>a)
	{
		have.erase(a);
	}
	pair<pair<int, int>, pair<int, int> >get()
	{
		if ((int)have.size() < 2) return make_pair(make_pair(INF, 1), make_pair(INF, 2));
		set<pair<int, int> >::iterator it = have.begin();
		pair<int, int>a = *it;
		it++;
		return make_pair(*it, a);
	}
};
int ans = 0, ansu = 1, ansv = 2;
Tdata* calc(int v)
{
	used[v] = true;
	vector<Tdata*> toMerge;
	Tdata* cur = new Tdata();
	for (int i = 0; i < (int)add[v].size(); i++)
	{
		int path = add[v][i];
		cur->add(make_pair(depth[pu[path]], path));
	}
	for (int i = 0; i < (int)add2[v].size(); i++)
	{
		int path = add2[v][i];
		int lca = getLCA(pu[path], pv[path]);
		cur->add(make_pair(depth[lca], path));
	}
	toMerge.push_back(cur);
	for (int i = 0; i < (int)g[v].size(); i++)
	{
		int to = g[v][i];
		if (!used[to])
		{
			toMerge.push_back(calc(to));
		}
	}
	for (int i = 1; i < (int)toMerge.size(); i++)
	{
		if (toMerge[i]->have.size()>toMerge[0]->have.size())
		{
			swap(toMerge[0], toMerge[i]);
		}
	}
	for (int i = 1; i < (int)toMerge.size(); i++)
	{
		for (set<pair<int, int> >::iterator it = toMerge[i]->have.begin(); it != toMerge[i]->have.end(); ++it)
		{
			toMerge[0]->add(*it);
		}
	}
	auto curans = toMerge[0]->get();
	for (int i = 0; i < (int)del[v].size(); i++)
	{
		int path = del[v][i];
		toMerge[0]->del(make_pair(depth[pu[path]], path));
	}
	vector<Path>goPath;
	for (int i = 0; i < (int)del2[v].size(); i++)
	{
		int path = del2[v][i];
		Path cur;
		cur.id = path;
		cur.gol = getoLCA(pu[path], v);
		cur.gor = getoLCA(pv[path], v);
		assert(cur.gol != cur.gor);
		cur.lenl = depth[pu[path]] - depth[v];
		cur.lenr = depth[pv[path]] - depth[v];
		cur.norm();
		goPath.push_back(cur);
	}
	for (int i = 0; i < (int)goPath.size(); i++)
	{
		for (int j = i + 1; j < (int)goPath.size(); j++)
		{
			int p1 = goPath[i].id, p2 = goPath[j].id;
			int tmp = calc(pu[p1], pv[p1], pu[p2], pv[p2]);
			if (tmp > ans)
			{
				ans = tmp;
				ansu = p1;
				ansv = p2;
			}

		}
	}
	sort(goPath.begin(), goPath.end());
	int maxRight = -1, maxId = -1;
	for (int i = 0; i < (int)goPath.size(); i++)
	{
		if (i == 0 || goPath[i].gol != goPath[i - 1].gol || goPath[i].gor != goPath[i - 1].gor)
		{
			maxRight = goPath[i].lenr;
			maxId = goPath[i].id;
		}
		else
		{
			int curAns = goPath[i].lenl + min(goPath[i].lenr, maxRight);
			if (curAns > ans)
			{
				//      ans = curAns;
				//      ansu = goPath[i].id;
				//      ansv = maxId;
			}
			if (goPath[i].lenr > maxRight)
			{
				maxRight = goPath[i].lenr;
				maxId = goPath[i].id;
			}
		}
	}
	for (int i = 0; i < (int)del2[v].size(); i++)
	{
		int path = del2[v][i];
		int lca = getLCA(pu[path], pv[path]);
		cur->del(make_pair(depth[lca], path));
	}
	assert(curans.first.second != curans.second.second);
	if (depth[v] - max(curans.first.first, curans.second.first) > ans)
	{
		ans = depth[v] - max(curans.first.first, curans.second.first);
		ansu = curans.first.second;
		ansv = curans.second.second;
	}
	return toMerge[0];
}
int len(int u, int v)
{
	int l = getLCA(u, v);
	return depth[u] + depth[v] - 2 * depth[l];
}
bool check(int u, int v, int x)
{
	if (isAncestor(u, x) && isAncestor(x, v)) return true;
	return isAncestor(v, x) && isAncestor(x, u);
}
bool checkPath(int u, int v, int l, int x)
{
	return check(l, u, x) || check(l, v, x);
}
int calc(int u, int v, int a, int b)
{
	int l1 = getLCA(u, v);
	int l2 = getLCA(a, b);
	vector<int>go = { l1,l2,u,v,a,b };
	go.push_back(getLCA(u, a));
	go.push_back(getLCA(u, b));
	go.push_back(getLCA(v, a));
	go.push_back(getLCA(v, b));
	sort(go.begin(), go.end());
	go.resize(unique(go.begin(), go.end()) - go.begin());
	vector<int>check;
	for (int i = 0; i < (int)go.size(); i++)
	{
		if (checkPath(u, v, l1, go[i]) && checkPath(a, b, l2, go[i]))
		{
			check.push_back(go[i]);
		}
	}
	int ans = 0;
	for (int i = 0; i < (int)check.size(); i++)
	{
		for (int j = i + 1; j < (int)check.size(); j++)
		{
			ans = max(ans, len(check[i], check[j]));
		}
	}
	return ans;
}
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	freopen("twopaths.in", "r", stdin);
	freopen("twopaths.out", "w", stdout);
	int n, m;
	scanf("%d %d", &n, &m);
	for (int i = 2; i <= n; i++)
	{
		int u;
		int v = i;
		scanf("%d", &u);
		g[u].push_back(v);
		g[v].push_back(u);
	}
	dfs(1, 1, 1);
	for (int i = 1; i <= m; i++)
	{
		scanf("%d %d", &pu[i], &pv[i]);
		if (isAncestor(pv[i], pu[i])) swap(pv[i], pu[i]);
		if (isAncestor(pu[i], pv[i]))
		{
			add[pv[i]].push_back(i);
			del[pu[i]].push_back(i);
		}
		else
		{
			int lca = getLCA(pu[i], pv[i]);
			add2[pv[i]].push_back(i);
			add2[pu[i]].push_back(i);
			del2[lca].push_back(i);
		}
	}
	for (int i = 1; i <= n; i++)
	{
		used[i] = false;
	}
	calc(1);	
	printf("%d\n", ans);
	printf("%d %d\n", ansu, ansv);
	return 0;

}