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: Time Limit Exceeded)

#![allow(unused)]

use std::io::{Read, Stdin, StdinLock};
use std::iter::{FromIterator, Iterator};
use std::str::{FromStr};
use std::string::String;
use itertools::Itertools;
use std::cmp::{min, max};

macro_rules! debug {
    ($($a:expr),*) => {
	eprintln!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);
    }
}

struct TokenReader<'a> {
    lock: StdinLock<'a>,
}

impl<'a> TokenReader<'a> {
    fn new(s: &'a Stdin) -> TokenReader<'a> {
        TokenReader { lock: s.lock() }
    }

    fn read_chars<T: FromIterator<char>>(&mut self) -> T {
        self.lock
            .by_ref()
            .bytes()
            .map(|c| c.unwrap() as char)
            .skip_while(|c| c.is_whitespace())
            .take_while(|c| !c.is_whitespace())
            .collect::<T>()
    }

    fn read_str(&mut self) -> String {
        self.read_chars::<String>()
    }

    fn read<T: FromStr>(&mut self) -> T {
        self.read_str().parse().ok().unwrap()
    }
}

//==============================================================================
//
// Problem specific code
//
//==============================================================================

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
enum C {
    Must,
    Never,
    Some,
    NotAll,
    Free,
}

fn bit_get(x: u64, k: usize) -> bool {
    x & (1 << k) != 0
}

fn bit_set(x: &mut u64, k: usize, b: bool) {
    *x = (*x & !(1 << k)) | (if b { 1 << k } else { 0 });
}

fn undetermined(c: C) -> bool {
    c == C::Some || c == C::NotAll
}

fn to_constraints(flags: &Vec<i32>, vals: &Vec<u64>) -> Vec<[C; 64]> {
    let mut vec = vec![[C::Free; 64]; flags.len()];

    for i in 0..flags.len() {
        if flags[i] == 0 {
            for k in 0..64 {
                vec[i][k] = if bit_get(vals[i], k) {
                    C::Must
                } else {
                    C::NotAll
                };
            }
        } else {
            for k in 0..64 {
                vec[i][k] = if bit_get(vals[i], k) {
                    C::Some
                } else {
                    C::Never
                };
            }
        }
    }

    vec
}

fn verify(
    ans: &Vec<Vec<u64>>,
    n: usize,
    ss: &Vec<i32>,
    ts: &Vec<i32>,
    us: &Vec<u64>,
    vs: &Vec<u64>,
) {
    for i in 0..n {
        if ss[i] == 0 {
            assert_eq!(ans[i].iter().fold(!0, |a, &x| a & x), us[i]);
        } else {
            assert_eq!(ans[i].iter().fold(0, |a, &x| a | x), us[i]);
        }
    }
    for j in 0..n {
        if ts[j] == 0 {
            assert_eq!((0..n).map(|i| ans[i][j]).fold(!0, |a, x| a & x), vs[j]);
        } else {
            assert_eq!((0..n).map(|i| ans[i][j]).fold(0, |a, x| a | x), vs[j]);
        }
    }
}

fn main() {
    let sin = std::io::stdin();
    let mut tr = TokenReader::new(&sin);

    let n = tr.read();
    let ss: Vec<i32> = (0..n).map(|_| tr.read()).collect();
    let ts: Vec<i32> = (0..n).map(|_| tr.read()).collect();
    let us: Vec<u64> = (0..n).map(|_| tr.read()).collect();
    let vs: Vec<u64> = (0..n).map(|_| tr.read()).collect();

    let mut row = to_constraints(&ss, &us);
    let mut col = to_constraints(&ts, &vs);
    
    let mut ntbdrow = vec![[0usize; 64]; n];
    let mut ntbdcol = vec![[0usize; 64]; n];
    let mut ans = vec![vec![0u64; n]; n];

    //let mut tbds = vec![[vec![]; 64]; n]; // i -> k -> [j]
    let mut tbds: Vec<[Vec<usize>; 64]> =
        vec![[
            vec![], vec![], vec![], vec![], vec![], vec![], vec![], vec![],
            vec![], vec![], vec![], vec![], vec![], vec![], vec![], vec![],
            vec![], vec![], vec![], vec![], vec![], vec![], vec![], vec![],
            vec![], vec![], vec![], vec![], vec![], vec![], vec![], vec![],
            vec![], vec![], vec![], vec![], vec![], vec![], vec![], vec![],
            vec![], vec![], vec![], vec![], vec![], vec![], vec![], vec![],
            vec![], vec![], vec![], vec![], vec![], vec![], vec![], vec![],
            vec![], vec![], vec![], vec![], vec![], vec![], vec![], vec![]
        ]; n];

    //
    // Is this satisfiable?
    //
    for i in 0..n {
        for k in 0..64 {
            let mut nmust = 0;
            let mut nnever = 0;
            for j in 0..n {
                match col[j][k] {
                    C::Must => nmust += 1,
                    C::Never => nnever += 1,
                    _ => (),
                }
            }

            if (row[i][k] == C::Must && nnever > 0)
                || (row[i][k] == C::Never && nmust > 0)
                || (row[i][k] == C::Some && nnever == n)
                || (row[i][k] == C::NotAll && nmust == n)
            {
                println!("-1");
                return;
            }
        }
    }

    for i in 0..n { for j in 0..n { for k in 0..64 {
        let b = match (min(row[i][k], col[j][k]), max(row[i][k], col[j][k])) {
            (C::Must, C::Never) => unreachable!(),
            (C::Must,  _) => true,
            (C::Never, _) => false,
            (C::Free, C::Free) => false, // true is also OK
            (C::Some, C::NotAll) => {
                tbds[i][k].push(j);
                false // true is also OK
            },
            (C::Some, C::Some) | (C::Some, C::Free) => {
                row[i][k] = C::Free;
                col[j][k] = C::Free;
                true
            },
            (C::NotAll, C::NotAll) | (C::NotAll, C::Free) => {
                row[i][k] = C::Free;
                col[j][k] = C::Free;
                false
            },
            _ => unreachable!()
        };

        bit_set(&mut ans[i][j], k, b);
    }}}

    let mut tbdexists = true;

    while tbdexists {
        tbdexists = false;
        for i in 0..n { for k in 0..64 {
            if tbds[i][k].is_empty() {
                continue;
            }
            tbdexists = true;

            if row[i][k] == C::Some {
                if tbds[i][k].iter().any(|&j| col[j][k] == C::Free) {
                    for &j in &tbds[i][k] {
                        let b = match col[j][k] {
                            C::NotAll => { col[j][k] = C::Free; false },
                            C::Free => true,
                            _ => unreachable!(),
                        };
                        bit_set(&mut ans[i][j], k, b);
                    }
                    row[i][k] = C::Free;
                    tbds[i][k].clear();
                }
            } else if row[i][k] == C::NotAll {
                if tbds[i][k].iter().any(|&j| col[j][k] == C::Free) {
                    for &j in &tbds[i][k] {
                        let b = match col[j][k] {
                            C::Some => { col[j][k] = C::Free; true },
                            C::Free => false,
                            _ => unreachable!(),
                        };
                        bit_set(&mut ans[i][j], k, b);
                    }
                    row[i][k] = C::Free;
                    tbds[i][k].clear();
                }
            }
        }}
    }

    for i in 0..n {
        println!("{}", ans[i].iter().map(|&x| x.to_string()).join(" "));
    }

    verify(&ans, n, &ss, &ts, &us, &vs);
}