Problem:
Score : 600 points

Problem Statement

Given are an integer N and arrays S, T, U, and V, each of length N.
Construct an N×N matrix a that satisfy the following conditions:

a_{i,j} is an integer.

0 \leq a_{i,j} \lt 2^{64}.

If S_{i} = 0, the bitwise AND of the elements in the i-th row is U_{i}.

If S_{i} = 1, the bitwise OR of the elements in the i-th row is U_{i}.

If T_{i} = 0, the bitwise AND of the elements in the i-th column is V_{i}.

If T_{i} = 1, the bitwise OR of the elements in the i-th column is V_{i}.

However, there may be cases where no matrix satisfies the conditions.

Constraints

All values in input are integers.

1 \leq N \leq 500

0 \leq S_{i} \leq 1

0 \leq T_{i} \leq 1

0 \leq U_{i} \lt 2^{64}

0 \leq V_{i} \lt 2^{64}

Input

Input is given from Standard Input in the following format:

N
S_{1} S_{2} ... S_{N}
T_{1} T_{2} ... T_{N}
U_{1} U_{2} ... U_{N}
V_{1} V_{2} ... V_{N}

Output

If there exists a matrix that satisfies the conditions, print one such matrix in the following format:

a_{1,1} ... a_{1,N}
:
a_{N,1} ... a_{N,N}

Note that any matrix satisfying the conditions is accepted.

If no matrix satisfies the conditions, print -1.

Sample Input 1

2
0 1
1 0
1 1
1 0

Sample Output 1

1 1
1 0

In Sample Input 1, we need to find a matrix such that:

the bitwise AND of the elements in the 1-st row is 1;

the bitwise OR of the elements in the 2-nd row is 1;

the bitwise OR of the elements in the 1-st column is 1;

the bitwise AND of the elements in the 2-nd column is 0.

Sample Input 2

2
1 1
1 0
15 15
15 11

Sample Output 2

15 11
15 11

Solution in Rust (1.42.0) (judge verdict: Accepted)

use proconio::input;

fn solve_inner(row: &Vec<u64>, col: &Vec<u64>) -> Option<Vec<Vec<u64>>> {
    let n = row.len();
    let mut row_cnt = [0; 4];
    let mut col_cnt = [0; 4];
    for i in 0..n {
        row_cnt[row[i] as usize] += 1;
        col_cnt[col[i] as usize] += 1;
    }
    if row_cnt[1] == n || (n == 1 && row_cnt[3] == n) {
        if col_cnt[1] + col_cnt[3] == n { return Some(vec![vec![1; n]; n]) }
    } else if row_cnt[2] == n || (n == 1 && row_cnt[0] == n) {
        if col_cnt[0] + col_cnt[2] == n { return Some(vec![vec![0; n]; n]) }
    } else if col_cnt[1] == n || (n == 1 && col_cnt[3] == n) {
        if row_cnt[1] + row_cnt[3] == n { return Some(vec![vec![1; n]; n]) }
    } else if col_cnt[2] == n || (n == 1 && col_cnt[0] == n) {
        if row_cnt[0] + row_cnt[2] == n { return Some(vec![vec![0; n]; n]) }
    } else if (row_cnt[1] == 0 || col_cnt[2] == 0) && (row_cnt[2] == 0 || col_cnt[1] == 0) {
        let mut res = vec![vec![0; n]; n];
        if (row_cnt[1] > 0 && row_cnt[2] == 0 && col_cnt[1] > 0 && col_cnt[2] == 0) ||
            (row_cnt[1] == n-1 && row_cnt[0] == 1 && col_cnt[1] + col_cnt[2] == 0) ||
            (col_cnt[1] == n-1 && col_cnt[0] == 1 && row_cnt[1] + row_cnt[2] == 0)
        {
            for i in 0..n {
                for j in 0..n {
                    res[i][j] = if row[i] == 1 || col[j] == 1 { 1 } else { 0 }
                }
            }
        } else if (row_cnt[2] > 0 && row_cnt[1] == 0 && col_cnt[2] > 0 && col_cnt[1] == 0) ||
            (row_cnt[2] == n-1 && row_cnt[3] == 1 && col_cnt[1] + col_cnt[2] == 0) ||
            (col_cnt[2] == n-1 && col_cnt[3] == 1 && row_cnt[1] + row_cnt[2] == 0)
        {
            for i in 0..n {
                for j in 0..n {
                    res[i][j] = if row[i] == 2 || col[j] == 2 { 0 } else { 1 }
                }
            }
        } else if row_cnt[1] == n-1 && row_cnt[3] == 1 {
            if col_cnt[0] == n { return None; }
            for i in 0..n {
                for j in 0..n {
                    res[i][j] = if row[i] == 1 || col[j] != 0  { 1 } else { 0 }
                }
            }
        } else if col_cnt[1] == n-1 && col_cnt[3] == 1 {
            if row_cnt[0] == n { return None; }
            for i in 0..n {
                for j in 0..n {
                    res[i][j] = if col[j] == 1 || row[i] != 0  { 1 } else { 0 }
                }
            }
        } else if row_cnt[2] == n-1 && row_cnt[0] == 1 {
            if col_cnt[3] == n { return None; }
            for i in 0..n {
                for j in 0..n {
                    res[i][j] = if row[i] == 2 || col[j] != 3  { 0 } else { 1 }
                }
            }
        } else if col_cnt[2] == n-1 && col_cnt[0] == 1 {
            if row_cnt[3] == n { return None; }
            for i in 0..n {
                for j in 0..n {
                    res[i][j] = if col[j] == 2 || row[i] != 3  { 0 } else { 1 }
                }
            }
        } else {
            let mut ci = 0;
            for i in 0..n {
                let mut cj = 0;
                for j in 0..n {
                    res[i][j] = if row[i] == 1 || col[j] == 1 { 1 } else if row[i] == 2 || col[j] == 2 { 0 } else { cj += 1; (ci+cj)%2 }
                }
                if row[i] == 0 || row[i] == 3 { ci += 1; }
            }
        }
        return Some(res);
    }
    None
}

fn solve(s: &Vec<u64>, t: &Vec<u64>, u: &Vec<u64>, v: &Vec<u64>) -> Option<Vec<Vec<u64>>> {
    let n = s.len();
    let mut res = vec![vec![0; n]; n];
    let mut row = vec![0; n];
    let mut col = vec![0; n];
    for i in 0..64 {
        for j in 0..n {
            row[j] = 2 * s[j] + (u[j] >> i) % 2;
            col[j] = 2 * t[j] + (v[j] >> i) % 2;
        }
        if let Some(part_res) = solve_inner(&row, &col) {
            for j in 0..n {
                for k in 0..n {
                    res[j][k] |= part_res[j][k] << i;
                }
            }
        } else {
            return None;
        }
    }
    Some(res)
}

fn main(){
    input! {
        n : usize,
        s : [u64; n],
        t : [u64; n],
        u : [u64; n],
        v : [u64; n]
    };
    if let Some(res) = solve(&s, &t, &u, &v) {
        for a in res {
            print!("{}", a[0]);
            for i in 1..n { print!(" {}", a[i]); }
            println!("");
        }
    } else {
        println!("-1");
    }
}