#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

const int MOD = 998244353;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int N;
    cin >> N;
    vector<int> C(2*N);
    for(auto &x: C) cin >> x;
    vector<int> R(N);
    for(auto &x: R) cin >> x;
    vector<int> B(N);
    for(auto &x: B) cin >> x;
    
    // Create S = {1,...,2N} \ B
    vector<bool> is_B(2*N +1, false);
    for(int i=0;i<N;i++) is_B[B[i]] = true;
    vector<int> S;
    for(int x=1;x<=2*N;x++) if(!is_B[x]) S.push_back(x);
    // Sort S
    sort(S.begin(), S.end());
    
    // Map from B_i to i
    vector<int> map_b(2*N +1, -1);
    for(int i=0;i<N;i++) map_b[B[i]] = i;
    
    // Initialize x_fixed
    vector<int> x_fixed(N, -1);
    // Initialize used_S
    vector<bool> used_S_flag(2*N +1, false);
    
    bool invalid = false;
    
    for(int p=0; p<2*N && !invalid; p++){
        if(C[p] == -1) continue;
        int v = C[p];
        if(v >=1 && v <= 2*N && is_B[v]){
            // v ∈ B
            int i = map_b[v];
            if(i == -1){
                invalid = true;
                break;
            }
            if(p == 2*i){
                // p == 2i+1 in 0-based index
                // A_{2i} = B_i
                // Thus, A_{2i-1} = x_i
                if(C[2*i -1] != -1){
                    int x_i = C[2*i -1];
                    // Check x_i ∈ S
                    if(x_i <1 || x_i >2*N || is_B[x_i]){
                        invalid = true;
                        break;
                    }
                    // Check if x_i is already used
                    if(used_S_flag[x_i]){
                        invalid = true;
                        break;
                    }
                    // Check R_i constraints
                    if(R[i] ==0 && x_i <= B[i]){
                        invalid = true;
                        break;
                    }
                    if(R[i] ==1 && x_i >= B[i]){
                        invalid = true;
                        break;
                    }
                    x_fixed[i] = x_i;
                    used_S_flag[x_i] = true;
                }
            }
            else{
                // p ==2i-1
                // A_{2i-1} = B_i
                // Thus, A_{2i} = x_i
                if(C[2*i] != -1){
                    int x_i = C[2*i];
                    // Check x_i ∈ S
                    if(x_i <1 || x_i >2*N || is_B[x_i]){
                        invalid = true;
                        break;
                    }
                    // Check if x_i is already used
                    if(used_S_flag[x_i]){
                        invalid = true;
                        break;
                    }
                    // Check R_i constraints
                    if(R[i] ==0 && x_i <= B[i]){
                        invalid = true;
                        break;
                    }
                    if(R[i] ==1 && x_i >= B[i]){
                        invalid = true;
                        break;
                    }
                    x_fixed[i] = x_i;
                    used_S_flag[x_i] = true;
                }
            }
        }
        else if(v >=1 && v <= 2*N){
            // v ∈ S
            // Assign x_i = v to pair i
            int i = (p /2);
            if(i >= N){
                invalid = true;
                break;
            }
            if(p == 2*i){
                // A_{2i} = x_i = v
                if(R[i] ==0 && v <= B[i]){
                    invalid = true;
                    break;
                }
                if(R[i] ==1 && v >= B[i]){
                    invalid = true;
                    break;
                }
                if(used_S_flag[v]){
                    invalid = true;
                    break;
                }
                x_fixed[i] = v;
                used_S_flag[v] = true;
            }
            else{
                // p ==2i-1
                // A_{2i-1} = x_i = v
                if(R[i] ==0 && v <= B[i]){
                    invalid = true;
                    break;
                }
                if(R[i] ==1 && v >= B[i]){
                    invalid = true;
                    break;
                }
                if(used_S_flag[v]){
                    invalid = true;
                    break;
                }
                x_fixed[i] = v;
                used_S_flag[v] = true;
            }
        }
        else{
            // Invalid value
            invalid = true;
            break;
        }
    }
    
    if(invalid){
        cout << "0";
        return 0;
    }
    
    // Collect group0 and group1 pairs
    vector<int> group0_pairs;
    vector<int> group1_pairs;
    for(int i=0;i<N;i++){
        if(R[i] ==0 && x_fixed[i] == -1){
            group0_pairs.push_back(i);
        }
        if(R[i] ==1 && x_fixed[i] == -1){
            group1_pairs.push_back(i);
        }
    }
    int K = group0_pairs.size();
    int L = group1_pairs.size();
    
    // Collect S_remaining
    vector<int> S_remaining;
    for(auto x: S){
        if(!used_S_flag[x]){
            S_remaining.push_back(x);
        }
    }
    
    // Assign group0
    // Sort group0_pairs in decreasing B_j
    sort(group0_pairs.begin(), group0_pairs.end(), [&](const int a, const int b)->bool{
        return B[a] > B[b];
    });
    // Sort S_remaining in increasing order
    sort(S_remaining.begin(), S_remaining.end());
    
    ll group0_assign =1;
    for(int j=0; j<K; j++){
        int b_j = B[group0_pairs[j]];
        // Find number of S_remaining > b_j
        // Using upper_bound
        int cnt = S_remaining.end() - upper_bound(S_remaining.begin(), S_remaining.end(), b_j);
        ll term = (ll)cnt - (K - j -1);
        if(term <0){
            invalid = true;
            break;
        }
        group0_assign = (group0_assign * term) % MOD;
    }
    if(invalid){
        cout << "0";
        return 0;
    }
    
    // Assign group1
    // Sort group1_pairs in increasing B_j
    sort(group1_pairs.begin(), group1_pairs.end(), [&](const int a, const int b)->bool{
        return B[a] < B[b];
    });
    // S_remaining is still sorted in increasing order
    ll group1_assign =1;
    for(int j=0; j<L; j++){
        int d_j = B[group1_pairs[j]];
        // Find number of S_remaining < d_j
        // Using lower_bound
        int cnt = lower_bound(S_remaining.begin(), S_remaining.end(), d_j) - S_remaining.begin();
        ll term = (ll)cnt - j;
        if(term <0){
            invalid = true;
            break;
        }
        group1_assign = (group1_assign * term) % MOD;
    }
    if(invalid){
        cout << "0";
        return 0;
    }
    
    ll assignments_count = (group0_assign * group1_assign) % MOD;
    
    // Now, compute arrangements_count
    ll arrangements_count =1;
    for(int i=0;i<N;i++){
        if(C[2*i] != -1 && C[2*i+1] != -1){
            // Both positions fixed
            if( (C[2*i] == B[i] && C[2*i+1] == x_fixed[i]) || (C[2*i] == x_fixed[i] && C[2*i+1] == B[i]) ){
                // arrangements_count *=1
                continue;
            }
            else{
                invalid = true;
                break;
            }
        }
        else if(C[2*i] != -1 || C[2*i+1] != -1){
            bool ok = false;
            if(C[2*i] != -1){
                if(C[2*i] == B[i] || C[2*i] == x_fixed[i]){
                    ok = true;
                }
            }
            if(C[2*i+1] != -1){
                if(C[2*i+1] == B[i] || C[2*i+1] == x_fixed[i]){
                    ok = true;
                }
            }
            if(ok){
                // arrangements_count *=1
                continue;
            }
            else{
                invalid = true;
                break;
            }
        }
        else{
            // Neither position fixed
            arrangements_count = (arrangements_count * 2) % MOD;
        }
    }
    
    if(invalid){
        cout << "0";
        return 0;
    }
    
    ll total = (assignments_count * arrangements_count) % MOD;
    cout << total;
}
