import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

public class JumpingPath_sjz {

    public static final int MOD = 11092019;

    private BufferedReader in;
    public JumpingPath_sjz(BufferedReader input) {
        in = input;
    }

    public static class JumpingPath {
        public JumpingPath(int value, int len, int cnt) {
            largestValue = value;
            length = len;
            count = cnt;
            next = null;
        }
        
        int largestValue;
        int length;
        int count;
        JumpingPath next;
        
        public String toString() {
            return "v:" + largestValue + ",L:" + length + ",#:" + count;
        }
    }
    
    public static class Tree {
        int value;
        int parent;
        List<Integer> children;
        JumpingPath path;
        int height;
        int longestPath;
        int lowestValue;
        
        Tree () {
            children = new LinkedList<>();
            path = null;
            height = 0;
            longestPath = 0;
            lowestValue = Integer.MAX_VALUE;
        }

    }
    
    
    private int n;
    private Tree[] tree;
    
    
    
    private int longestPath;
    private int pathCount;
    
    
    
    
    public void add(JumpingPath jumpingPath, LinkedHashMap<Integer, JumpingPath> paths) {
        JumpingPath jp = paths.get(jumpingPath.largestValue);
        if (jp != null) {
            if (jp.length == jumpingPath.length) {
                jp.count = (jp.count + jumpingPath.count) % MOD;
            } else if (jp.length < jumpingPath.length) {
                jp.count = jumpingPath.count;
                jp.length = jumpingPath.length;
            }
        } else {
            paths.put(jumpingPath.largestValue, jumpingPath);
        }
    }


	public void solve() {
        read();

        countPaths();

        System.out.println (longestPath + " " + pathCount);
    }


	private void countPaths() {
	    longestPath = 1;
	    pathCount = 1;

	    tree[0].path = new JumpingPath(tree[0].value, 1, 1);
	    List<Integer> q = new LinkedList<>();
	    for (Integer child: tree[0].children) {
	        q.add(child);
	    }
	    while (!q.isEmpty()) {
	        int currentIdx = q.get(0);
	        q.remove(0);
	        Tree current = tree[currentIdx];
	        
	        // What is the longest path we will be able to form ending at
	        // the current node?
	        JumpingPath newPath = null;
	        
	        int ancestorIdx = current.parent;
	        while (ancestorIdx >= 0) {
	            Tree ancestor = tree[ancestorIdx];
	            
	            if (newPath != null && newPath.length > ancestor.longestPath+1)
	                break;
	            if (ancestor.lowestValue > current.value)
	                break;
	            
	            JumpingPath jp = ancestor.path;
	            if (jp != null) {
	                if (current.value >= jp.largestValue) {
	                    int pathLen = jp.length + 1;
	                    JumpingPath jp2 = new JumpingPath(current.value, pathLen, jp.count);
	                    if (pathLen > longestPath) {
	                        longestPath = pathLen;
	                        pathCount = jp2.count;
	                    } else if (pathLen == longestPath) {
	                        pathCount = (pathCount + jp2.count) % MOD;
	                    }
	                    if (newPath == null)
	                        newPath = jp2;
	                    else if (jp2.length == newPath.length)
	                        newPath.count = (newPath.count + jp2.count) % MOD;
	                    else if (jp2.length > newPath.length)
	                        newPath = jp2;
	                }
	            }
	            ancestorIdx = ancestor.parent;
	        }
                
	        if (newPath == null) {
                current.path = new JumpingPath(current.value, 1, 1);
                if (longestPath == 1)
                    pathCount = (pathCount + 1) % MOD;
            } else {
                current.path = newPath;
            }
	        Tree parent = tree[current.parent];
	        current.longestPath = Math.max(current.path.length, parent.longestPath);
	        q.addAll(current.children);
	    }
	}

    private void read() {
        Scanner input = new Scanner(in);
        n = input.nextInt();
        
        tree = new Tree[n];

        for (int i = 0; i < n; ++i) {
            tree[i] = new Tree();
            tree[i].value = input.nextInt();
        }
        tree[0].parent = -1;
        for (int i = 1; i < n; ++i) {
            tree[i].parent = input.nextInt()-1;
            tree[tree[i].parent].children.add(i);
        }

        input.close();
        
        for (int i = n-1; i > 0; --i) {
            Tree t = tree[i];
            Tree parent = tree[t.parent];
            parent.height = Math.max(parent.height, t.height+1);
        }
        tree[0].lowestValue = tree[0].value;
        for (int i = 1; i < n; ++i) {
            Tree t = tree[i];
            Tree parent = tree[t.parent];
            t.lowestValue = Math.min(t.value, parent.lowestValue);
        }
    }


    public static void main(String[] args) throws IOException {
        BufferedReader input;
        if (args.length > 0) {
            input = new BufferedReader(new FileReader(args[0]));
        } else {
            input = new BufferedReader (new InputStreamReader(System.in));
        }
        JumpingPath_sjz problem = new JumpingPath_sjz(input);
        problem.solve();
    }

}
