import java.util.*;

public class inorder {
    final static int N_SIZE = 500010;
    final static int DO_NOT_EXIST = -1;
    final static int NOT_GIVEN = 0;
    final static int INFINITE_DEPTH = 500010;
    final static int PRIME_MODULUS = 999999937;

    static int n;
    static int[] preOrder = new int[N_SIZE];
    static int[] postOrder = new int[N_SIZE];
    static int[] inOrder = new int[N_SIZE];
    static int[] indexInPreOrder = new int[N_SIZE];
    static int[] indexInPostOrder = new int[N_SIZE];
    static int[] indexInInOrder = new int[N_SIZE];
    static int givenNodes;
    static int[] parent = new int[N_SIZE];
    static int[] leftChild = new int[N_SIZE];
    static int[] rightChild = new int[N_SIZE];
    static int[] singleChild = new int[N_SIZE];
    static int[] subtreeSize = new int[N_SIZE];
    static int[] depth = new int[N_SIZE];
    static int topNode;
    static int topNodeLeftmostIndex;
    static int singleLines;
    static long quantity;
    static boolean[] determinate = new boolean[N_SIZE];
    static int pending;

    static void constructTree(
            int preOrderStart,
            int preOrderEnd,
            int postOrderStart,
            int postOrderEnd,
            int currentDepth) {
        assert(preOrderEnd - preOrderStart == postOrderEnd - postOrderStart);
        int root = preOrder[preOrderStart];
        subtreeSize[root] = preOrderEnd - preOrderStart + 1;
        depth[root] = currentDepth;
        if (preOrderStart == preOrderEnd) {
            leftChild[root] = DO_NOT_EXIST;
            rightChild[root] = DO_NOT_EXIST;
            singleChild[root] = DO_NOT_EXIST;
            return;
        }
        assert(preOrderStart + 1 <= n);
        assert(postOrderEnd - 1 >= 1);
        if (preOrder[preOrderStart + 1] == postOrder[postOrderEnd - 1]) {
            leftChild[root] = DO_NOT_EXIST;
            rightChild[root] = DO_NOT_EXIST;
            singleChild[root] = preOrder[preOrderStart + 1];
            parent[singleChild[root]] = root;
            constructTree(
                    preOrderStart + 1,
                    preOrderEnd,
                    postOrderStart,
                    postOrderEnd - 1,
                    currentDepth + 1);
            return;
        }
        leftChild[root] = preOrder[preOrderStart + 1];
        int leftSubtreeLength = indexInPostOrder[leftChild[root]] - postOrderStart + 1;
        rightChild[root] = preOrder[preOrderStart + leftSubtreeLength + 1];
        singleChild[root] = DO_NOT_EXIST;
        parent[leftChild[root]] = root;
        parent[rightChild[root]] = root;
        constructTree(
                preOrderStart + 1,
                preOrderStart + leftSubtreeLength,
                postOrderStart,
                postOrderStart + leftSubtreeLength - 1,
                currentDepth + 1);
        constructTree(
                preOrderStart + leftSubtreeLength + 1,
                preOrderEnd,
                postOrderStart + leftSubtreeLength,
                postOrderEnd - 1,
                currentDepth + 1);
    }

    static void getTopNode() {
        int minDepth = INFINITE_DEPTH;
        topNode = DO_NOT_EXIST;
        for (int i = 1; i <= n; i++) {
            if (inOrder[i] == 0) {
                continue;
            }
            if (minDepth > depth[inOrder[i]]) {
                minDepth = depth[inOrder[i]];
                topNode = inOrder[i];
            }
        }
    }

    static void topNodeToRoot() {
        topNodeLeftmostIndex = 1;
        singleLines = 0;
        if (leftChild[topNode] != DO_NOT_EXIST) {
            topNodeLeftmostIndex += subtreeSize[leftChild[topNode]];
        }
        int currentNode = topNode;
        int currentParent = parent[currentNode];
        while (currentParent != DO_NOT_EXIST) {
            if (rightChild[currentParent] == currentNode) {
                topNodeLeftmostIndex += subtreeSize[leftChild[currentParent]] + 1;
            } else if (singleChild[currentParent] == currentNode) {
                singleLines++;
            }
            currentNode = currentParent;
            currentParent = parent[currentNode];
        }
    }

    static void visit() {
        for (int i = 1; i <= n; i++) {
            determinate[i] = false;
        }

        int currentNode = topNode;
        while (currentNode != DO_NOT_EXIST) {
            determinate[currentNode] = true;
            currentNode = parent[currentNode];
        }

        for (int i = 1; i <= n; i++) {
            currentNode = inOrder[i];
            if (currentNode == DO_NOT_EXIST) {
                continue;
            }
            while (!determinate[currentNode]) {
                determinate[currentNode] = true;
                currentNode = parent[currentNode];
            }
        }
    }

    static void calculatePending() {
        pending = 0;
        for (int i = 1; i <= n; i++) {
            if (singleChild[i] != DO_NOT_EXIST && !determinate[i]) {
                pending++;
            }
        }
    }

    static long power(long a, long b, long p) {
        long result = 1;
        a = a % p;
        while (b > 0) {
            if (b % 2 == 1) {
                result = (result * a) % p;
            }
            b = b / 2;
            a = (a * a) % p;
        }
        return result;
    }

    static long combination(long a, long b, long p) {
        if (a < 0 || b > a || b < 0) {
            return 0;
        }
        long result = 1;
        for (int i = 1; i <= b; i++) {
            result = result * (a - i + 1) % p;
            result = result * modInverse(i, p) % p;
        }
        return result;
    }

    static long modInverse(long a, long p) {
        return power(a, p - 2, p);
    }

    static void calculateQuantity(long p) {
        quantity = power(2, pending, p);
        if (givenNodes == 0) {
            return;
        }
        assert(topNode != DO_NOT_EXIST);
        int topIndex = indexInInOrder[topNode];
        long candidate1 = singleLines;
        long chosen1 = topIndex - topNodeLeftmostIndex;
        long candidate2 = -1;
        long chosen2 = topIndex - topNodeLeftmostIndex;
        if (leftChild[topNode] != DO_NOT_EXIST) {
            ;
        } else if (singleChild[topNode] != DO_NOT_EXIST) {
            if (topIndex < n && inOrder[topIndex + 1] != NOT_GIVEN) {
                ;
            } else if (topIndex > 1 && inOrder[topIndex - 1] != NOT_GIVEN) {
                chosen1 -= subtreeSize[singleChild[topNode]];
            } else {
                assert(givenNodes == 1);
                candidate2 = singleLines;
                chosen2 -= subtreeSize[singleChild[topNode]];
            }
        } else {
            ;
        }
        long aboveTopNode = (combination(candidate1, chosen1, p) +
                             combination(candidate2, chosen2, p)) % p;
        quantity = quantity * aboveTopNode % p;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        n = scanner.nextInt();
        for (int i = 1; i <= n; i++) {
            preOrder[i] = scanner.nextInt();
            indexInPreOrder[preOrder[i]] = i;
        }
        for (int i = 1; i <= n; i++) {
            postOrder[i] = scanner.nextInt();
            indexInPostOrder[postOrder[i]] = i;
        }
        givenNodes = 0;
        for (int i = 1; i <= n; i++) {
            inOrder[i] = scanner.nextInt();
            indexInInOrder[inOrder[i]] = i;
            if (inOrder[i] != NOT_GIVEN) {
                givenNodes++;
            }
        }
        parent[preOrder[1]] = DO_NOT_EXIST;
        constructTree(1, n, 1, n, 1);

        getTopNode();
        if (topNode != DO_NOT_EXIST) {
            topNodeToRoot();
        }
        visit();
        calculatePending();
        calculateQuantity(PRIME_MODULUS);
        System.out.println(quantity);
    }
}
