#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;
}