#include <fstream>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <cstdlib>
#include <ctime>
#include <string>
#include <algorithm>
#include <queue>
using namespace std;

ifstream cin("twopaths.in");
ofstream cout("twopaths.out");

#define vec vector
#define pb push_back
#define rep(k, l, r) for (int k = (int)(l); k < (int)(r); k++)
typedef pair<int, int> PII;
typedef long long ll;

struct edge {
	int u, i;
	edge() : u(0) {}
	edge(int u, int i) : u(u), i(i) {}
	void print() {
		cout << "( " << u << "; " << i << ") ";
	}
};

int n, m;
vec<vec<edge> > g;
vec<PII> pairs;
vec<vec<int> > list;


int main() {
	ios_base::sync_with_stdio(false);
	cin >> n >> m;
	g.resize(n);
	rep(k, 0, n - 1) {
		int x;
		cin >> x; x--;
		g[k + 1].push_back(edge(x, pairs.size()));
		g[x].push_back(edge(k + 1, pairs.size()));
		pairs.push_back(PII(x, k + 1));
	}
	list.resize(pairs.size());
	vec<char> used;
	vec<int> pr, e;
	rep(k, 0, m) {
		int s, f;
		cin >> s >> f; s--; f--;
		used.assign(n, false);
		pr.assign(n, 0);
		e.assign(n, 0);
		queue<int> qu;
		used[s] = true;
		pr[s] = -1;
		qu.push(s);
		bool cont = true;
		while (!qu.empty() && cont) {
			int v = qu.front();
			qu.pop();
			rep(i, 0, g[v].size()) {
				int u = g[v][i].u;
				if (!used[u]) {
					qu.push(u);
					used[u] = true;
					pr[u] = v;
					e[u] = i;
					if (u == f) { cont = false; }
				}
			}
		}
		int cur = f;
		while (cur != s) {
			int i = e[cur];
			cur = pr[cur];
			list[g[cur][i].i].push_back(k);
		}
	}

	vec<vec<int> > res(m, vec<int>(m));
	int max_res = 0, max_v = 0, max_u = 1;
	rep(k, 0, pairs.size()) {
		rep(i, 0, list[k].size()) {
			rep(j, i + 1, list[k].size()) {
				int v = list[k][i], u = list[k][j];
				res[v][u]++;
				if (res[v][u] > max_res) {
					max_res = res[v][u];
					max_v = v;
					max_u = u;
				}
			}
		}
	}

	cout << max_res << '\n' << max_v + 1 << " " << max_u + 1 << '\n';
	return 0;
}
