import java.io.*;
import java.util.*;

public class Pr7TwopathsLetsTry {
	public static void main(String[] args) throws IOException {
		new Pr7TwopathsLetsTry().run();
	}

	BufferedReader in;
	PrintWriter out;
	StringTokenizer st;

	String nextToken() throws IOException {
		while (st == null || !st.hasMoreTokens()) {
			st = new StringTokenizer(in.readLine());
		}
		return st.nextToken();
	}

	int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}

	void run() throws IOException {
		in = new BufferedReader(new FileReader("twopaths.in"));
		out = new PrintWriter("twopaths.out");
		int n = nextInt();
		int k = nextInt();
		if (n <= 4000 && k <= 1000) {
			solveSmall(n, k);
		} else {
			solveNice(n, k);
		}
		out.flush();
	}

	int[] par;
	ArrayList<Integer>[] children;
	int[] depth;
	int[][] fpar;

	void countDepths(int i, int curd) {
		depth[i] = curd;
		for (int j : children[i]) {
			countDepths(j, curd + 1);
		}
	}

	final int log = 20;

	int getLCA(int u, int v) {
		if (depth[u] < depth[v]) {
			int t = u;
			u = v;
			v = t;
		}
		for (int i = log - 1; i > -1 && depth[u] > depth[v]; i--) {
			if (fpar[i][u] != -1 && depth[fpar[i][u]] >= depth[v]) {

				u = fpar[i][u];
			}
		}
		if (u == v) {
			return u;
		}
		for (int i = log - 1; i > -1; i--) {
			if (fpar[i][u] != fpar[i][v]) {
				u = fpar[i][u];
				v = fpar[i][v];
			}
		}
		return par[u];
	}

	void solveSmall(int n1, int k1) throws IOException {
		int n = n1;
		int k = k1;
		par = new int[n];
		children = new ArrayList[n];
		for (int i = 0; i < n; i++) {
			children[i] = new ArrayList<Integer>();
		}
		par[0] = -1;
		for (int i = 1; i < n; i++) {
			par[i] = nextInt() - 1;
			children[par[i]].add(i);
		}
		long[] pows = new long[100000];
		pows[0] = 1;
		pows[1] = 31;
		for (int i = 2; i < pows.length; i++) {
			pows[i] = pows[i - 1] * pows[1];
		}
		depth = new int[n];
		countDepths(0, 0);
		fpar = new int[log][n];
		for (int i = 0; i < n; i++) {
			fpar[0][i] = par[i];
		}
		for (int i = 1; i < log; i++) {
			for (int j = 0; j < n; j++) {
				fpar[i][j] = fpar[i - 1][j] == -1 ? -1 : fpar[i - 1][fpar[i - 1][j]];
			}
		}
		BitSet[] codes = new BitSet[k];

		int[][] queries = new int[3][k];
		for (int i = 0; i < k; i++) {
			for (int j = 0; j < 2; j++) {
				queries[j][i] = nextInt() - 1;
			}
			if (queries[0][i] > queries[1][i]) {
				int t = queries[1][i];
				queries[1][i] = queries[0][i];
				queries[0][i] = t;
			}
			queries[2][i] = getLCA(queries[0][i], queries[1][i]);
			HashSet<Integer> path = new HashSet<>();
			int u = queries[0][i];
			while (u != queries[2][i]) {
				path.add(u);
				u = par[u];
			}
			u = queries[1][i];
			while (u != queries[2][i]) {
				path.add(u);
				u = par[u];
			}
			codes[i] = new BitSet(n);
			for (int j = 0; j < n; j++) {
				if (!path.contains(j)) {
					codes[i].set(j, false);
				} else {
					codes[i].set(j, true);
				}
			}
		}
		int best = 0;
		int besti = -1;
		int bestj = -1;
		for (int i = 0; i < k; i++) {
			for (int j = i + 1; j < k; j++) {
				BitSet temp = new BitSet(n);
				temp.or(codes[i]);
				temp.and(codes[j]);
				int ans = temp.cardinality();
				if (ans >= best) {
					best = ans;
					besti = i;
					bestj = j;
				}
			}
		}
		out.println(best);
		out.println((besti + 1) + " " + (bestj + 1));
	}

	void solveNice(int n1, int k1) throws IOException {
		int n = n1;
		int k = k1;
		par = new int[n];
		children = new ArrayList[n];
		for (int i = 0; i < n; i++) {
			children[i] = new ArrayList<Integer>();
		}
		par[0] = -1;
		for (int i = 1; i < n; i++) {
			par[i] = nextInt() - 1;
			children[par[i]].add(i);
		}
		depth = new int[n];
		countDepths(0, 0);
		int[][] queries = new int[2][k];
		col = new HashSet[n];
		for (int i = 0; i < n; i++) {
			col[i] = new HashSet<>();
		}
		for (int i = 0; i < k; i++) {
			for (int j = 0; j < 2; j++) {
				queries[j][i] = nextInt() - 1;
			}
			if (depth[queries[0][i]] < depth[queries[1][i]]) {
				int t = queries[1][i];
				queries[1][i] = queries[0][i];
				queries[0][i] = t;
			}
			int u = queries[0][i];
			while (u != queries[1][i]) {
				u = par[u];
				col[u].add(i);
			}
		}
		colDepth = new int[k];
		max = new TreeSet<Integer>(new Comparator<Integer>() {

			@Override
			public int compare(Integer o1, Integer o2) {
				if (colDepth[o1] != colDepth[o2]) {
					return -colDepth[o1] + colDepth[o2];
				}
				return o1 - o2;
			}
		});
		for (int i = 0; i < k; i++) {
			max.add(i);
		}
		findTwoMax(0);
		out.println(ans);
		out.println((ansi + 1) + " " + (ansj + 1));
	}

	int ans = 0;
	int ansi = -1;
	int ansj = -1;
	int[] colDepth;
	HashSet<Integer>[] col;
	TreeSet<Integer> max;

	void findTwoMax(int i) {
		for (int j : children[i]) {
			findTwoMax(j);
		}
		for (int c : col[i]) {
			max.remove(c);
			colDepth[c]++;
			max.add(c);
		}
		int max1 = max.first();
		int max2 = max.higher(max1);
		if (Math.min(max1, max2) >= ans) {
			ans = Math.min(max1, max2);
			ansi = max1;
			ansj = max2;
		}
	}
}
