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::{fastout, input};

fn check(s: Vec<u64>, t: Vec<u64>, u: Vec<u64>, v: Vec<u64>, mat: &Vec<Vec<u64>>) -> bool {
    let n: usize = s.len();
    let mut r_and = vec![!0; n];
    let mut r_or = vec![0; n];

    let mut c_and = vec![!0; n];
    let mut c_or = vec![0; n];

    for r in 0..n {
        for c in 0..n {
            r_and[r] &= mat[r][c];
            r_or[r] |= mat[r][c];
            c_and[c] &= mat[r][c];
            c_or[c] |= mat[r][c];
        }
    }

    for r in 0..n {
        match s[r] {
            0 => {
                if r_and[r] != u[r] {
                    return false;
                }
            }
            1 => {
                if r_or[r] != u[r] {
                    return false;
                }
            }
            _ => {}
        };
    }
    for c in 0..n {
        match t[c] {
            0 => {
                if c_and[c] != v[c] {
                    return false;
                }
            }
            1 => {
                if c_or[c] != v[c] {
                    return false;
                }
            }
            _ => {}
        };
    }
    return true;
}

#[fastout]
fn main() {
    input! {
        n: usize,
        s: [u64; n],
        t: [u64; n],
        u: [u64; n],
        v: [u64; n],
    }
    let mut mat: Vec<Vec<u64>> = vec![vec![0; n]; n];

    for i in 0..64 {
        //for i in 0..1 {
        let mut row_has: Vec<Vec<bool>> = vec![vec![false; 2]; n];
        let mut col_has: Vec<Vec<bool>> = vec![vec![false; 2]; n];
        let mut row_any: Vec<(usize, u64)> = Vec::new();
        let mut col_any: Vec<(usize, u64)> = Vec::new();
        for r in 0..n {
            let b = (u[r] >> i as u64) & 1 as u64;
            if (s[r] ^ b) == 0 {
                row_any.push((r, b));
            } else {
                let x = b;
                for c in 0..n {
                    mat[r][c] |= x << i as u64;
                    col_has[c][x as usize] = true;
                    row_has[r][x as usize] = true;
                }
            }
        }
        for c in 0..n {
            let b = (v[c] >> i as u64) & 1 as u64;
            if (t[c] ^ b) == 0 {
                col_any.push((c, b));
            } else {
                let x = b;
                for r in 0..n {
                    mat[r][c] |= x << i as u64;
                    row_has[r][x as usize] = true;
                    col_has[c][x as usize] = true;
                }
            }
        }
        if row_any.len() == 0 || col_any.len() == 0 {
            continue;
        }
        if row_any.len() >= 2 && col_any.len() >= 2 {
            for ri in 0..row_any.len() {
                let r = row_any[ri].0;
                for ci in 0..col_any.len() {
                    let c = col_any[ci].0;
                    let x = (ri + ci) % 2;
                    let x = x as u64;
                    mat[r][c] |= x << i as u64;
                }
            }
            for ci in 0..col_any.len() {
                let c = col_any[ci].0;
                for ri in 0..row_any.len() {
                    let r = row_any[ri].0;
                    let x = (ri + ci) % 2;
                    let x = x as u64;
                    mat[r][c] |= x << i as u64;
                }
            }
            continue;
        }
        {
            for ri in 0..row_any.len() {
                let r = row_any[ri].0;
                let x = row_any[ri].1;
                for ci in 0..col_any.len() {
                    let c = col_any[ci].0;
                    let y = col_any[ci].1;
                    if x == y {
                        mat[r][c] |= x << i as u64;
                        col_has[c][x as usize] = true;
                        row_has[r][x as usize] = true;
                    }
                }
            }
            for ri in 0..row_any.len() {
                let r = row_any[ri].0;
                let x = row_any[ri].1;
                for ci in 0..col_any.len() {
                    let c = col_any[ci].0;
                    let y = col_any[ci].1;
                    if x != y {
                        if row_has[r][x as usize] == false {
                            mat[r][c] |= x << i as u64;
                            col_has[c][x as usize] = true;
                            row_has[r][x as usize] = true;
                        } else {
                            mat[r][c] |= y << i as u64;
                            col_has[c][y as usize] = true;
                            row_has[r][y as usize] = true;
                        }
                    }
                }
            }
        }
    }

    let ok = check(s, t, u, v, &mat);
    if ok {
        for r in mat.iter() {
            for v in r.iter() {
                print!("{} ", v);
            }
            println!("");
        }
    } else {
        println!("-1");
    }
}