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)

// SNIPPET read
pub trait Readable {
    type Output;
    fn words_count() -> usize;
    fn read_words(words: &[&str]) -> Result<Self::Output, String>;
}
#[macro_export]
macro_rules! readable {
    ( $t:ty, $words_count:expr, |$words:ident| $read_words:expr ) => {
        impl Readable for $t {
            type Output = $t;
            fn words_count() -> usize { $words_count }
            fn read_words($words: &[&str]) -> Result<$t, String> {
                Ok($read_words)
            }
        }
    };
}
readable!((), 1, |_ss| ());
readable!(String, 1, |ss| ss[0].to_string());
impl Readable for char {
    type Output = char;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<char, String> {
        let chars: Vec<char> = words[0].chars().collect();
        if chars.len() == 1 {
            Ok(chars[0])
        } else {
            Err(format!("cannot parse `{}` as a char", words[0]))
        }
    }
}
pub struct Chars();
impl Readable for Chars {
    type Output = Vec<char>;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<Vec<char>, String> {
        Ok(words[0].chars().collect())
    }
}
impl Readable for i8 {
    type Output = Self;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<i8, String> {
        use std::str::FromStr;
        i8::from_str(words[0]).map_err(|_| {
            format!("cannot parse `{}` as i8", words[0])
        })
    }
}
impl Readable for u8 {
    type Output = Self;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<u8, String> {
        use std::str::FromStr;
        u8::from_str(words[0]).map_err(|_| {
            format!("cannot parse `{}` as u8", words[0])
        })
    }
}
impl Readable for i16 {
    type Output = Self;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<i16, String> {
        use std::str::FromStr;
        i16::from_str(words[0]).map_err(|_| {
            format!("cannot parse `{}` as i16", words[0])
        })
    }
}
impl Readable for u16 {
    type Output = Self;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<u16, String> {
        use std::str::FromStr;
        u16::from_str(words[0]).map_err(|_| {
            format!("cannot parse `{}` as u16", words[0])
        })
    }
}
impl Readable for i32 {
    type Output = Self;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<i32, String> {
        use std::str::FromStr;
        i32::from_str(words[0]).map_err(|_| {
            format!("cannot parse `{}` as i32", words[0])
        })
    }
}
impl Readable for u32 {
    type Output = Self;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<u32, String> {
        use std::str::FromStr;
        u32::from_str(words[0]).map_err(|_| {
            format!("cannot parse `{}` as u32", words[0])
        })
    }
}
impl Readable for i64 {
    type Output = Self;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<i64, String> {
        use std::str::FromStr;
        i64::from_str(words[0]).map_err(|_| {
            format!("cannot parse `{}` as i64", words[0])
        })
    }
}
impl Readable for u64 {
    type Output = Self;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<u64, String> {
        use std::str::FromStr;
        u64::from_str(words[0]).map_err(|_| {
            format!("cannot parse `{}` as u64", words[0])
        })
    }
}
impl Readable for isize {
    type Output = Self;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<isize, String> {
        use std::str::FromStr;
        <isize>::from_str(words[0]).map_err(|_| {
            format!("cannot parse `{}` as isize", words[0])
        })
    }
}
impl Readable for usize {
    type Output = Self;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<usize, String> {
        use std::str::FromStr;
        <usize>::from_str(words[0]).map_err(|_| {
            format!("cannot parse `{}` as usize", words[0])
        })
    }
}
impl Readable for f32 {
    type Output = Self;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<f32, String> {
        use std::str::FromStr;
        f32::from_str(words[0]).map_err(|_| {
            format!("cannot parse `{}` as f32", words[0])
        })
    }
}
impl Readable for f64 {
    type Output = Self;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<f64, String> {
        use std::str::FromStr;
        f64::from_str(words[0]).map_err(|_| {
            format!("cannot parse `{}` as f64", words[0])
        })
    }
}
#[allow(non_camel_case_types)]
pub struct u8_;
impl Readable for u8_ {
    type Output = u8;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<Self::Output, String> {
        u8::read_words(words).map(|n| n-1)
    }
}
#[allow(non_camel_case_types)]
pub struct u16_;
impl Readable for u16_ {
    type Output = u16;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<Self::Output, String> {
        u16::read_words(words).map(|n| n-1)
    }
}
#[allow(non_camel_case_types)]
pub struct u32_;
impl Readable for u32_ {
    type Output = u32;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<Self::Output, String> {
        u32::read_words(words).map(|n| n-1)
    }
}
#[allow(non_camel_case_types)]
pub struct u64_;
impl Readable for u64_ {
    type Output = u64;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<Self::Output, String> {
        u64::read_words(words).map(|n| n-1)
    }
}
#[allow(non_camel_case_types)]
pub struct usize_;
impl Readable for usize_ {
    type Output = usize;
    fn words_count() -> usize { 1 }
    fn read_words(words: &[&str]) -> Result<Self::Output, String> {
        <usize>::read_words(words).map(|n| n-1)
    }
}
impl<T1: Readable, T2: Readable> Readable for (T1, T2) {
    type Output = (T1::Output, T2::Output);
    fn words_count() -> usize {
        T1::words_count() + T2::words_count()
    }
    fn read_words(words: &[&str]) -> Result<Self::Output, String> {
        assert_eq!(words.len(), Self::words_count());
        let mut start = 0;
        let count1 = T1::words_count();
        let val1 = T1::read_words(&words[start .. start+count1])?;
        start += count1;
        let val2 = T2::read_words(&words[start..])?;
        Ok((val1, val2))
    }
}
impl<T1: Readable, T2: Readable, T3: Readable> Readable for (T1, T2, T3) {
    type Output = (T1::Output, T2::Output, T3::Output);
    fn words_count() -> usize {
        T1::words_count() + T2::words_count() + T3::words_count()
    }
    fn read_words(words: &[&str]) -> Result<Self::Output, String> {
        assert_eq!(words.len(), Self::words_count());
        let mut start = 0;
        let count1 = T1::words_count();
        let val1 = T1::read_words(&words[start .. start+count1])?;
        start += count1;
        let count2 = T2::words_count();
        let val2 = T2::read_words(&words[start .. start+count2])?;
        start += count2;
        let val3 = T3::read_words(&words[start..])?;
        Ok((val1, val2, val3))
    }
}
impl<T1: Readable, T2: Readable, T3: Readable, T4: Readable> Readable for (T1, T2, T3, T4) {
    type Output = (T1::Output, T2::Output, T3::Output, T4::Output);
    fn words_count() -> usize {
        T1::words_count() + T2::words_count() + T3::words_count() + T4::words_count()
    }
    fn read_words(words: &[&str]) -> Result<Self::Output, String> {
        assert_eq!(words.len(), Self::words_count());
        let mut start = 0;
        let count1 = T1::words_count();
        let val1 = T1::read_words(&words[start .. start+count1])?;
        start += count1;
        let count2 = T2::words_count();
        let val2 = T2::read_words(&words[start .. start+count2])?;
        start += count2;
        let count3 = T3::words_count();
        let val3 = T3::read_words(&words[start .. start+count3])?;
        start += count3;
        let val4 = T4::read_words(&words[start..])?;
        Ok((val1, val2, val3, val4))
    }
}
impl<T1: Readable, T2: Readable, T3: Readable, T4: Readable, T5: Readable> Readable for (T1, T2, T3, T4, T5) {
    type Output = (T1::Output, T2::Output, T3::Output, T4::Output, T5::Output);
    fn words_count() -> usize {
        T1::words_count() + T2::words_count() + T3::words_count() + T4::words_count() + T5::words_count()
    }
    fn read_words(words: &[&str]) -> Result<Self::Output, String> {
        assert_eq!(words.len(), Self::words_count());
        let mut start = 0;
        let count1 = T1::words_count();
        let val1 = T1::read_words(&words[start .. start+count1])?;
        start += count1;
        let count2 = T2::words_count();
        let val2 = T2::read_words(&words[start .. start+count2])?;
        start += count2;
        let count3 = T3::words_count();
        let val3 = T3::read_words(&words[start .. start+count3])?;
        start += count3;
        let count4 = T4::words_count();
        let val4 = T4::read_words(&words[start .. start+count4])?;
        start += count4;
        let val5 = T5::read_words(&words[start..])?;
        Ok((val1, val2, val3, val4, val5))
    }
}
impl<T1: Readable, T2: Readable, T3: Readable, T4: Readable, T5: Readable, T6: Readable> Readable for (T1, T2, T3, T4, T5, T6) {
    type Output = (T1::Output, T2::Output, T3::Output, T4::Output, T5::Output, T6::Output);
    fn words_count() -> usize {
        T1::words_count() + T2::words_count() + T3::words_count() + T4::words_count() + T5::words_count() + T6::words_count()
    }
    fn read_words(words: &[&str]) -> Result<Self::Output, String> {
        assert_eq!(words.len(), Self::words_count());
        let mut start = 0;
        let count1 = T1::words_count();
        let val1 = T1::read_words(&words[start .. start+count1])?;
        start += count1;
        let count2 = T2::words_count();
        let val2 = T2::read_words(&words[start .. start+count2])?;
        start += count2;
        let count3 = T3::words_count();
        let val3 = T3::read_words(&words[start .. start+count3])?;
        start += count3;
        let count4 = T4::words_count();
        let val4 = T4::read_words(&words[start .. start+count4])?;
        start += count4;
        let count5 = T5::words_count();
        let val5 = T5::read_words(&words[start .. start+count5])?;
        start += count5;
        let val6 = T6::read_words(&words[start..])?;
        Ok((val1, val2, val3, val4, val5, val6))
    }
}
pub trait ReadableFromLine {
    type Output;
    fn read_line(line: &str) -> Result<Self::Output, String>;
}
fn split_into_words(line: &str) -> Vec<&str> {
    line.trim_end_matches('\n').split_whitespace().collect()
}
impl<T: Readable> ReadableFromLine for T {
    type Output = T::Output;
    fn read_line(line: &str) -> Result<T::Output, String> {
        let words = split_into_words(line);
        if words.len() != T::words_count() {
            return Err(format!("line `{}` has {} words, expected {}",
                               line, words.len(), T::words_count()));
        }
        T::read_words(&words)
    }
}
pub fn read_words_into_vec<T: Readable>(words: &[&str], line: &str) -> Result<Vec<T::Output>, String> {
    let n = T::words_count();
    assert_eq!(words.len() % n, 0);
    let mut result = Vec::new();
    for chunk in words.chunks(n) {
        match T::read_words(chunk) {
            Ok(v) => result.push(v),
            Err(msg) => {
                let fragment_msg = if n == 1 {
                    format!("word {}", result.len())
                } else {
                    let l = result.len();
                    format!("words {}-{}", n*l + 1, (n+1) * l)
                };
                return Err(format!(
                    "{} of line `{}`: {}", fragment_msg, line, msg
                ));
            }
        }
    }
    Ok(result)
}
pub fn split_into_words_for_collection<T: Readable>(
    line: &str, prefix_words_count: usize
) -> Result<Vec<&str>, String> {
    let n = T::words_count();
    let words = split_into_words(line);
    if words.len() < prefix_words_count {
        return Err(
            format!("line `{}` has {} words, expected at least {}",
                    line, words.len(), prefix_words_count)
        );
    }
    if (words.len() - prefix_words_count) % T::words_count() != 0 {
        return Err(
            format!("line `{}` has {} words, expected {} + {}",
                    line, words.len(), prefix_words_count, n)
        );
    }
    Ok(words)
}
#[macro_export]
macro_rules! readable_collection {
    ($u:ident => $collection_in:ty, $collection_out:ty) => {
        readable_collection!($u: => $collection_in, $collection_out);
    };
    ($u:ident : $( $bound:path ),* => $collection_in:ty, $collection_out:ty) => {
        impl<$u: Readable> ReadableFromLine for $collection_in
        where
            <$u as Readable>::Output: Sized $(+ $bound)*
        {
            type Output = $collection_out;
            fn read_line(line: &str) -> Result<Self::Output, String> {
                let words = split_into_words_for_collection::<$u>(line, 0)?;
                Ok(read_words_into_vec::<$u>(&words, line)?.into_iter().collect())
            }
        }
        impl<T1: Readable, $u: Readable> ReadableFromLine for (T1, $collection_in)
        where
            <$u as Readable>::Output: Sized $(+ $bound)*
        {
            type Output = (T1::Output, $collection_out);
            fn read_line(line: &str) -> Result<Self::Output, String> {
                let prefix_len = T1::words_count();
                let words = split_into_words_for_collection::<$u>(line, prefix_len)?;
                let val1 = T1::read_words(&words[..prefix_len])?;
                let rest = read_words_into_vec::<$u>(&words[prefix_len..], line)?;
                Ok((val1, rest.into_iter().collect()))
            }
        }
        impl<T1: Readable, T2: Readable, $u: Readable> ReadableFromLine for (T1, T2, $collection_in)
        where
            <$u as Readable>::Output: Sized $(+ $bound)*
        {
            type Output = (T1::Output, T2::Output, $collection_out);
            fn read_line(line: &str) -> Result<Self::Output, String> {
                let prefix_len = <(T1, T2)>::words_count();
                let words = split_into_words_for_collection::<$u>(line, prefix_len)?;
                let mut start = 0;
                let count1 = T1::words_count();
                let val1 = T1::read_words(&words[start .. start+count1])?;
                start += count1;
                let count2 = T2::words_count();
                let val2 = T2::read_words(&words[start .. start+count2])?;
                let rest = read_words_into_vec::<$u>(&words[prefix_len..], line)?;
                Ok((val1, val2, rest.into_iter().collect()))
            }
        }
        impl<T1: Readable, T2: Readable, T3: Readable, $u: Readable> ReadableFromLine for (T1, T2, T3, $collection_in)
        where
            <$u as Readable>::Output: Sized $(+ $bound)*
        {
            type Output = (T1::Output, T2::Output, T3::Output, $collection_out);
            fn read_line(line: &str) -> Result<Self::Output, String> {
                let prefix_len = <(T1, T2, T3)>::words_count();
                let words = split_into_words_for_collection::<$u>(line, prefix_len)?;
                let mut start = 0;
                let count1 = T1::words_count();
                let val1 = T1::read_words(&words[start .. start+count1])?;
                start += count1;
                let count2 = T2::words_count();
                let val2 = T2::read_words(&words[start .. start+count2])?;
                start += count2;
                let count3 = T3::words_count();
                let val3 = T3::read_words(&words[start .. start+count3])?;
                let rest = read_words_into_vec::<$u>(&words[prefix_len..], line)?;
                Ok((val1, val2, val3, rest.into_iter().collect()))
            }
        }
        impl<T1: Readable, T2: Readable, T3: Readable, T4: Readable, $u: Readable> ReadableFromLine for (T1, T2, T3, T4, $collection_in)
        where
            <$u as Readable>::Output: Sized $(+ $bound)*
        {
            type Output = (T1::Output, T2::Output, T3::Output, T4::Output, $collection_out);
            fn read_line(line: &str) -> Result<Self::Output, String> {
                let prefix_len = <(T1, T2, T3, T4)>::words_count();
                let words = split_into_words_for_collection::<$u>(line, prefix_len)?;
                let mut start = 0;
                let count1 = T1::words_count();
                let val1 = T1::read_words(&words[start .. start+count1])?;
                start += count1;
                let count2 = T2::words_count();
                let val2 = T2::read_words(&words[start .. start+count2])?;
                start += count2;
                let count3 = T3::words_count();
                let val3 = T3::read_words(&words[start .. start+count3])?;
                start += count3;
                let count4 = T4::words_count();
                let val4 = T4::read_words(&words[start .. start+count4])?;
                let rest = read_words_into_vec::<$u>(&words[prefix_len..], line)?;
                Ok((val1, val2, val3, val4, rest.into_iter().collect()))
            }
        }
    };
}
readable_collection!(U => Vec<U>, Vec<U::Output>);
pub fn read<T: ReadableFromLine>() -> T::Output {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).unwrap();
    T::read_line(&line).unwrap()
}
#[macro_export]
macro_rules! read {
    () => {
        let mut line = String::new();
        std::io::stdin().read_line(&mut line).unwrap();
    };
    ( $pat:pat = $t:ty $(,)* ) => {
        let $pat = read::<$t>();
    };
    ( ! $(,)* ) => {
        let _ = read::<()>();
    };
    ( $pat:pat = $t:ty, $( $rest:tt )+ ) => {
        read_inner!($pat = $t; $($rest)+);
    };
    ( !, $( $rest:tt )+ ) => {
        read_inner!(_ = (); $($rest)+);
    };
}
#[macro_export]
#[doc(hidden)]
macro_rules! read_inner {
    ( $( $acc_pat:pat = $acc_t:ty ),+ ; $pat:pat = $t:ty, $( $rest:tt )* ) => {
        read_inner!($( $acc_pat = $acc_t ),+ , $pat = $t ; $($rest)*);
    };
    ( $( $acc_pat:pat = $acc_t:ty ),+ ; !, $( $rest:tt )* ) => {
        read_inner!($( $acc_pat = $acc_t ),+ , _ = () ; $($rest)*);
    };
    ( $( $acc_pat:pat = $acc_t:ty ),+ ; $pat:pat = $t:ty ) => {
        read_inner!($( $acc_pat = $acc_t ),+ , $pat = $t ;);
    };
    ( $( $acc_pat:pat = $acc_t:ty ),+ ; ! ) => {
        read_inner!($( $acc_pat = $acc_t ),+ , _ = () ;);
    };
    ( $( $pat:pat = $t:ty ),+ ; ) => {
        let ($($pat),+) = read::<($($t),+)>();
    };
}
pub trait ReadableFromChunk {
    type Output;
    fn lines_count() -> usize;
    fn read_chunk(lines: &[String]) -> Result<Self::Output, String>;
}
impl<T1: ReadableFromLine, T2: ReadableFromLine> ReadableFromChunk for (T1, T2) {
    type Output = (T1::Output, T2::Output);
    fn lines_count() -> usize { 2 }
    fn read_chunk(lines: &[String]) -> Result<Self::Output, String> {
        let out1 = T1::read_line(&lines[0])?;
        let out2 = T2::read_line(&lines[1])?;
        Ok((out1, out2))
    }
}
impl<T1: ReadableFromLine, T2: ReadableFromLine, T3: ReadableFromLine> ReadableFromChunk for (T1, T2, T3) {
    type Output = (T1::Output, T2::Output, T3::Output);
    fn lines_count() -> usize { 3 }
    fn read_chunk(lines: &[String]) -> Result<Self::Output, String> {
        let out1 = T1::read_line(&lines[0])?;
        let out2 = T2::read_line(&lines[1])?;
        let out3 = T3::read_line(&lines[2])?;
        Ok((out1, out2, out3))
    }
}
impl<T1: ReadableFromLine, T2: ReadableFromLine, T3: ReadableFromLine, T4: ReadableFromLine> ReadableFromChunk for (T1, T2, T3, T4) {
    type Output = (T1::Output, T2::Output, T3::Output, T4::Output);
    fn lines_count() -> usize { 4 }
    fn read_chunk(lines: &[String]) -> Result<Self::Output, String> {
        let out1 = T1::read_line(&lines[0])?;
        let out2 = T2::read_line(&lines[1])?;
        let out3 = T3::read_line(&lines[2])?;
        let out4 = T4::read_line(&lines[3])?;
        Ok((out1, out2, out3, out4))
    }
}
pub fn read_chunk<T: ReadableFromChunk>() -> T::Output {
    let stdin = std::io::stdin();
    let mut handle = stdin.lock();
    read_chunk_from_handle::<T>(&mut handle).unwrap()
}
fn read_chunk_from_handle<T: ReadableFromChunk>(handle: &mut std::io::StdinLock) -> Option<T::Output> {
    use std::io::BufRead;
    let mut lines = vec![String::new(); T::lines_count()];
    let mut first = true;
    for line in &mut lines {
        if handle.read_line(line).unwrap() == 0 && first {
            return None;
        }
        first = false;
    }
    Some(T::read_chunk(&lines).unwrap())
}
#[macro_export]
macro_rules! read_chunk {
    ( $( $pat:pat = $t:ty ),+ ) => {
        let ($($pat),+) = read_chunk::<($($t),+)>();
    };
}
static mut STDIN: Option<std::io::Stdin> = None;
pub struct ReadLines<T: ReadableFromLine> {
    lock: std::io::StdinLock<'static>,
    phantom: std::marker::PhantomData<T>
}
impl<T: ReadableFromLine> Iterator for ReadLines<T> {
    type Item = T::Output;
    fn next(&mut self) -> Option<T::Output> {
        use std::io::BufRead;
        let mut line = String::new();
        if self.lock.read_line(&mut line).unwrap() > 0 {
            Some(T::read_line(&line).unwrap())
        } else {
            None
        }
    }
}
pub fn read_lines<T: ReadableFromLine>() -> ReadLines<T> {
    unsafe {
        if STDIN.is_none() {
            STDIN = Some(std::io::stdin());
        }
    }
    ReadLines {
        lock: unsafe { STDIN.as_ref().unwrap().lock() },
        phantom: std::marker::PhantomData::<T>
    }
}
pub struct ReadChunks<T: ReadableFromChunk> {
    lock: std::io::StdinLock<'static>,
    phantom: std::marker::PhantomData<T>
}
impl<T: ReadableFromChunk> Iterator for ReadChunks<T> {
    type Item = T::Output;
    fn next(&mut self) -> Option<T::Output> {
        read_chunk_from_handle::<T>(&mut self.lock)
    }
}
pub fn read_chunks<T: ReadableFromChunk>() -> ReadChunks<T> {
    unsafe {
        if STDIN.is_none() {
            STDIN = Some(std::io::stdin());
        }
    }
    ReadChunks {
        lock: unsafe { STDIN.as_ref().unwrap().lock() },
        phantom: std::marker::PhantomData::<T>
    }
}
pub trait Words {
    fn read<T: Readable>(&self) -> T::Output;
}
impl<'a> Words for [&'a str] {
    fn read<T: Readable>(&self) -> T::Output {
        T::read_words(self).unwrap()
    }
}
impl<'a> Words for &'a str {
    fn read<T: Readable>(&self) -> T::Output {
        T::read_words(&[self]).unwrap()
    }
}

// SNIPPET utils
pub fn yn(result: bool) {
    if result {
        println!("Yes");
    } else {
        println!("No");
    }
}
#[allow(non_snake_case)]
pub fn YN(result: bool) {
    if result {
        println!("YES");
    } else {
        println!("NO");
    }
}
pub fn exit(msg: impl std::fmt::Display) -> ! {
    println!("{}", msg);
    std::process::exit(0)
}
#[macro_export]
#[cfg(local)]
macro_rules! dbg {
    () => {
        {
            use std::io::{self, Write};
            writeln!(io::stderr(), "{}: dbg", line!()).unwrap();
        }
    };
    ($e: expr) => {
        {
            use std::io::{self, Write};
            let result = $e;
            writeln!(io::stderr(), "{}: {} = {:?}",
                     line!(), stringify!($e), result)
                .unwrap();
            result
        }
    }
}
#[macro_export]
#[cfg(not(local))]
macro_rules! dbg {
    () => {};
    ($e: expr) => {
        { $e }
    }
}

// SNIPPET option
pub trait BoolExt {
    fn then<T>(self, value: T) -> Option<T>;
    fn then_with<T, F>(self, f: F) -> Option<T> where F: FnOnce() -> T;
    fn and<T>(self, option: Option<T>) -> Option<T>;
    fn and_then<T, F>(self, f: F) -> Option<T> where F: FnOnce() -> Option<T>;
}
impl BoolExt for bool {
    fn then<T>(self, value: T) -> Option<T> {
        if self { Some(value) } else { None }
    }
    fn then_with<T, F>(self, f: F) -> Option<T> where F: FnOnce() -> T {
        if self { Some(f()) } else { None }
    }
    fn and<T>(self, option: Option<T>) -> Option<T> {
        if self { option } else { None }
    }
    fn and_then<T, F>(self, f: F) -> Option<T> where F: FnOnce() -> Option<T> {
        if self { f() } else { None }
    }
}
pub trait OptionExt<T> {
    fn to_string_or<U: std::fmt::Display>(&self, default: U) -> String
    where
        T: std::fmt::Display;
}
impl<T> OptionExt<T> for Option<T> {
    fn to_string_or<U: std::fmt::Display>(&self, default: U) -> String
    where
        T: std::fmt::Display
    {
        self.as_ref().map(|x| x.to_string()).unwrap_or(default.to_string())
    }
    /*
    fn get_or_insert_with<F: FnOnce() -> T>(&mut self, f: F) -> &mut T {
        match *self {
            None => *self = Some(f()),
            _ => ()
        }
        self.as_mut().unwrap()
    }
    */
}
pub trait Guard: Sized {
    fn guard(self, pred: impl FnOnce(&Self) -> bool) -> Option<Self>;
}
impl<T> Guard for T {
    fn guard(self, pred: impl FnOnce(&T) -> bool) -> Option<T> {
        if pred(&self) { Some(self) } else { None }
    }
}

// SNIPPET range
pub trait UsizeRangeBoundsExt {
    fn to_range(&self, len: usize) -> Option<std::ops::Range<usize>>;
}
impl<T: std::ops::RangeBounds<usize>> UsizeRangeBoundsExt for T {
    #[allow(unstable_name_collisions)]
    fn to_range(&self, len: usize) -> Option<std::ops::Range<usize>> {
        use std::ops::Bound::*;
        let start = match self.start_bound() {
            Included(&i) => i,
            Excluded(&i) => i+1,
            Unbounded => 0
        };
        let end = match self.end_bound() {
            Included(&i) => i+1,
            Excluded(&i) => i,
            Unbounded => len,
        };
        (start <= end && end <= len).then(start..end)
    }
}
pub trait BoundCloned<T> {
    fn cloned(self) -> std::ops::Bound<T>;
}
impl<T: Clone> BoundCloned<T> for std::ops::Bound<&T> {
    fn cloned(self) -> std::ops::Bound<T> {
        match self {
            std::ops::Bound::Included(x) => std::ops::Bound::Included(x.clone()),
            std::ops::Bound::Excluded(x) => std::ops::Bound::Excluded(x.clone()),
            std::ops::Bound::Unbounded => std::ops::Bound::Unbounded
        }
    }
}
pub trait BoundExt<T> {
    fn map<U>(self, f: impl FnOnce(T) -> U) -> std::ops::Bound<U>;
}
impl<T> BoundExt<T> for std::ops::Bound<T> {
    fn map<U>(self, f: impl FnOnce(T) -> U) -> std::ops::Bound<U> {
        match self {
            std::ops::Bound::Included(x) => std::ops::Bound::Included(f(x)),
            std::ops::Bound::Excluded(x) => std::ops::Bound::Excluded(f(x)),
            std::ops::Bound::Unbounded => std::ops::Bound::Unbounded
        }
    }
}

// SNIPPET table
pub struct Table<T> {
    inner: Vec<Vec<T>>
}
pub struct TableIndicesIterator {
    height: usize,
    width: usize,
    y: usize,
    x: usize
}
impl Iterator for TableIndicesIterator {
    type Item = (usize, usize);
    fn next(&mut self) -> Option<(usize, usize)> {
        if self.x < self.width {
            self.x += 1;
            return Some((self.y, self.x-1))
        }
        if self.y+1 < self.height {
            self.y += 1;
            self.x = 1;
            return Some((self.y, 0))
        }
        None
    }
}
pub struct TableRows<'a, T> {
    table: &'a Table<T>,
    index: usize
}
impl<'a, T> Iterator for TableRows<'a, T> {
    type Item = &'a [T];
    fn next(&mut self) -> Option<&'a [T]> {
        if self.index < self.table.height() {
            let i = self.index;
            self.index += 1;
            Some(&self.table.inner[i])
        } else {
            None
        }
    }
}
pub trait TableRangeBounds {
    fn y_bounds(&self) -> (std::ops::Bound<usize>, std::ops::Bound<usize>);
    fn x_bounds(&self) -> (std::ops::Bound<usize>, std::ops::Bound<usize>);
}
/*
impl<T1: std::ops::RangeBounds<usize>, T2: std::ops::RangeBounds<usize>> TableRangeBounds for (T1, T2) {
    fn y_bounds(&self) -> (std::ops::Bound<usize>, std::ops::Bound<usize>) {
        (self.0.start_bound().cloned(), self.0.end_bound().cloned())
    }
    fn x_bounds(&self) -> (std::ops::Bound<usize>, std::ops::Bound<usize>) {
        (self.1.start_bound().cloned(), self.1.end_bound().cloned())
    }
}
*/
impl<T: std::ops::RangeBounds<(usize, usize)>> TableRangeBounds for T {
    fn y_bounds(&self) -> (std::ops::Bound<usize>, std::ops::Bound<usize>) {
        (self.start_bound().map(|&(y, _)| y), self.end_bound().map(|&(y, _)| y))
    }
    fn x_bounds(&self) -> (std::ops::Bound<usize>, std::ops::Bound<usize>) {
        (self.start_bound().map(|&(_, x)| x), self.end_bound().map(|&(_, x)| x))
    }
}
pub struct CumulativeTable<T, F1, F2> {
    op: F1,
    op_inv: F2,
    inner: Table<T>
}
impl<T> Table<T> {
    pub fn from_rows(rows: Vec<Vec<T>>) -> Option<Table<T>> {
        rows.windows(2).all(|window| window[0].len() == window[1].len())
            .then_with(|| Table { inner: rows })
    }
    pub unsafe fn from_rows_unchecked(rows: Vec<Vec<T>>) -> Table<T> {
        Table { inner: rows }
    }
    pub fn height(&self) -> usize {
        self.inner.len()
    }
    pub fn width(&self) -> usize {
        self.inner.first().map_or(0, |row| row.len())
    }
    pub fn shape(&self) -> (usize, usize) {
        (self.height(), self.width())
    }
    pub fn indices(&self) -> impl Iterator<Item=(usize, usize)> {
        TableIndicesIterator {
            height: self.height(),
            width: self.width(),
            y: if self.width() == 0 { self.height() } else { 0 },
            x: 0
        }
    }
    pub fn inside(&self, (y, x): (usize, usize)) -> bool {
        y < self.height() && x < self.width()
    }
    pub fn row(&self, y: usize) -> Option<&[T]> {
        self.inner.get(y).map(|vec| vec.as_slice())
    }
    pub fn row_mut(&mut self, y: usize) -> Option<&mut [T]> {
        self.inner.get_mut(y).map(|vec| vec.as_mut_slice())
    }
    pub fn get(&self, (y, x): (usize, usize)) -> Option<&T> {
        self.inner.get(y).and_then(|row| row.get(x))
    }
    pub fn get_mut(&mut self, (y, x): (usize, usize)) -> Option<&mut T> {
        self.inner.get_mut(y).and_then(|row| row.get_mut(x))
    }
    pub fn rows(&self) -> TableRows<T> {
        TableRows { table: self, index: 0 }
    }
    pub fn adjacent4_indices(&self, (y, x): (usize, usize)) -> Option<Vec<(usize, usize)>> {
        self.inside((y, x)).then_with(|| {
            let mut result = Vec::with_capacity(4);
            if y > 0 {
                result.push((y-1, x));
            }
            if x > 0 {
                result.push((y, x-1));
            }
            if x < self.width()-1 {
                result.push((y, x+1));
            }
            if y < self.height()-1 {
                result.push((y+1, x));
            }
            result
        })
    }
    pub fn adjacent8_indices(&self, (y, x): (usize, usize)) -> Option<Vec<(usize, usize)>> {
        self.inside((y, x)).then_with(|| {
            let mut result = Vec::with_capacity(8);
            let xs = x.saturating_sub(1) ..= std::cmp::min(x+1, self.width()-1);
            if y > 0 {
                for x in xs.clone() {
                    result.push((y-1, x));
                }
            }
            if x > 0 {
                result.push((y, x-1));
            }
            if x < self.width()-1 {
                result.push((y, x+1));
            }
            if y < self.height()-1 {
                for x in xs {
                    result.push((y+1, x));
                }
            }
            result
        })
    }
    pub fn accumulate<F1, F2>(&self, identity: T, op: F1, op_inv: F2)
                              -> CumulativeTable<T, F1, F2>
    where
        T: Clone,
        F1: Fn(&T, &T) -> T,
        F2: Fn(&T, &T) -> T
    {
        let mut inner = vec![vec![identity.clone(); self.width() + 1]];
        for table_row in self.rows() {
            let mut new_row = vec![identity.clone()];
            let last_row = inner.last().unwrap();
            for (x, acc1) in table_row.iter().zip(last_row.windows(2)) {
                let acc2 = new_row.last().unwrap();
                let tmp1 = op(x, &acc1[1]);
                let tmp2 = op(&tmp1, acc2);
                new_row.push(op_inv(&tmp2, &acc1[0]));
            }
            inner.push(new_row);
        }
        CumulativeTable { op, op_inv, inner: Table { inner } }
    }
}
impl<T> std::ops::Index<usize> for Table<T> {
    type Output = [T];
    fn index(&self, y: usize) -> &[T] {
        match self.row(y) {
            Some(row) => row,
            None => panic!(
                "index out of bounds: the table has {} rows but the row index is {}",
                self.height(), y
            )
        }
    }
}
impl<T> std::ops::IndexMut<usize> for Table<T> {
    fn index_mut(&mut self, y: usize) -> &mut [T] {
        let height = self.height();
        match self.row_mut(y) {
            Some(row) => row,
            None => panic!(
                "index out of bounds: the table has {} rows but the index is {}",
                height, y
            )
        }
    }
}
impl<T> std::ops::Index<(usize, usize)> for Table<T> {
    type Output = T;
    fn index(&self, index: (usize, usize)) -> &T {
        match self.get(index) {
            Some(result) => result,
            None => panic!(
                "index out of bounds: the table shape is {:?} but the index is {:?}",
                self.shape(), index
            )
        }
    }
}
impl<T> std::ops::IndexMut<(usize, usize)> for Table<T> {
    fn index_mut(&mut self, index: (usize, usize)) -> &mut T {
        let shape = self.shape();
        match self.get_mut(index) {
            Some(result) => result,
            None => panic!(
                "index out of bounds: the table shape is {:?} but the index is {:?}",
                shape, index
            )
        }
    }
}
impl<T, F1: Fn(&T, &T) -> T, F2: Fn(&T, &T) -> T> CumulativeTable<T, F1, F2> {
    pub fn query(&self, range: impl TableRangeBounds) -> Option<T> {
        self.query_yx(range.y_bounds(), range.x_bounds())
    }
    pub fn query_yx(&self, yrange: impl std::ops::RangeBounds<usize>, xrange: impl std::ops::RangeBounds<usize>) -> Option<T> {
        let y = yrange.to_range(self.inner.height() - 1)?;
        let x = xrange.to_range(self.inner.width() - 1)?;
        let val1 = &self.inner.inner[y.end][x.end];
        let val2 = &self.inner.inner[y.end][x.start];
        let val3 = &self.inner.inner[y.start][x.end];
        let val4 = &self.inner.inner[y.start][x.start];
        let tmp1 = (self.op)(val1, val4);
        let tmp2 = (self.op)(val2, val3);
        let result = (self.op_inv)(&tmp1, &tmp2);
        Some(result)
    }
}
pub fn backward2_indices((y, x): (usize, usize)) -> Vec<(usize, usize)> {
    let mut res = Vec::with_capacity(2);
    if y > 0 {
        res.push((y-1, x));
    }
    if x > 0 {
        res.push((y, x-1));
    }
    res
}
#[macro_export]
macro_rules! table {
    () => {
        unsafe { Table::from_rows_unchecked(Vec::new()) }
    };
    ($element:expr ; $rows:expr , $cols:expr) => {
        unsafe { Table::from_rows_unchecked(vec![vec![$element; $cols]; $rows]) }
    };
}
pub fn read_table<T: Readable>() -> Table<T::Output> {
    let res: Vec<Vec<T::Output>> = read_lines::<Vec<T>>().collect();
    Table::from_rows(res).unwrap()
}
pub fn read_table_rows<T: Readable>(height: usize) -> Table<T::Output> {
    let res: Vec<Vec<T::Output>> = read_lines::<Vec<T>>().take(height).collect();
    if res.len() < height {
        panic!(
            "tried reading {} rows for table, but stdin has only {} lines",
            height, res.len()
        );
    }
    Table::from_rows(res).unwrap()
}
pub fn read_char_table() -> Table<char> {
    let res: Vec<Vec<char>> = read_lines::<Chars>().collect();
    Table::from_rows(res).unwrap()
}
pub fn read_char_table_rows(height: usize) -> Table<char> {
    let res: Vec<Vec<char>> = read_lines::<Chars>().take(height).collect();
    if res.len() < height {
        panic!(
            "tried reading {} rows for table, but stdin has only {} lines",
            height, res.len()
        );
    }
    Table::from_rows(res).unwrap()
}

// SNIPPET iter
pub struct Chunks<I: Iterator> {
    iter: I,
    size: usize
}
impl<I: Iterator> Iterator for Chunks<I> {
    type Item = Vec<I::Item>;
    fn next(&mut self) -> Option<Self::Item> {
        let first = self.iter.next();
        if first.is_none() {
            return None;
        }
        let mut chunk = Vec::with_capacity(self.size);
        chunk.push(first.unwrap());
        for _ in 0..self.size-1 {
            match self.iter.next() {
                Some(x) => chunk.push(x),
                None => break
            }
        }
        Some(chunk)
    }
}
#[derive(Clone)]
pub struct LScan<I: Iterator, S: Clone, F: FnMut(&S, I::Item) -> S> {
    iter: I,
    state: Option<S>,
    f: F,
}
impl<I: Iterator, S: Clone, F> Iterator for LScan<I, S, F>
where
    F: FnMut(&S, I::Item) -> S,
{
    type Item = S;
    fn next(&mut self) -> Option<S> {
        if self.state.is_none() {
            return None;
        }
        let state_inner = self.state.take().unwrap();
        if let Some(item) = self.iter.next() {
            self.state = Some((self.f)(&state_inner, item));
        }
        Some(state_inner)
    }
}
pub struct GroupBy<K: Eq, I: Iterator, F: FnMut(&I::Item) -> K> {
    cur: Option<(I::Item, K)>,
    iter: I,
    key_fn: F
}
impl<K: Eq, I: Iterator, F: FnMut(&I::Item) -> K> Iterator for GroupBy<K, I, F> {
    type Item = (K, Vec<I::Item>);
    fn next(&mut self) -> Option<(K, Vec<I::Item>)> {
        let cur = self.cur.take();
        cur.map(|(item, key)| {
            let mut group = vec![item];
            loop {
                let next = self.iter.next();
                match next {
                    Some(next_item) => {
                        let next_key = (self.key_fn)(&next_item);
                        if key == next_key {
                            group.push(next_item);
                        } else {
                            self.cur = Some((next_item, next_key));
                            break;
                        }
                    }
                    None => {
                        self.cur = None;
                        break;
                    }
                }
            }
            (key, group)
        })
    }
}
pub struct RunLength<I: Iterator> {
    cur: Option<I::Item>,
    iter: I
}
impl<I: Iterator> Iterator for RunLength<I> where I::Item: Eq {
    type Item = (I::Item, usize);
    fn next(&mut self) -> Option<(I::Item, usize)> {
        let cur = self.cur.take();
        cur.map(|value| {
            let mut length = 1;
            loop {
                let next = self.iter.next();
                match next {
                    Some(next_value) => {
                        if value == next_value {
                            length += 1;
                        } else {
                            self.cur = Some(next_value);
                            break;
                        }
                    }
                    None => {
                        self.cur = None;
                        break;
                    }
                }
            }
            (value, length)
        })
    }
}
pub trait IteratorExt: Iterator {
    fn chunks(self, size: usize) -> Chunks<Self> where Self: Sized {
        assert!(size > 0);
        Chunks {
            iter: self,
            size: size
        }
    }
    fn lscan<S: Clone, F>(self, state: S, f: F) -> LScan<Self, S, F>
    where
        Self: Sized,
        F: FnMut(&S, Self::Item) -> S,
    {
        LScan {
            iter: self,
            state: Some(state),
            f: f,
        }
    }
    fn lscan1<F>(mut self, f: F) -> Option<LScan<Self, Self::Item, F>>
    where
        Self: Sized,
        Self::Item: Clone,
        F: FnMut(&Self::Item, Self::Item) -> Self::Item
    {
        self.next().map(|first| self.lscan(first, f))
    }
    fn get_unique(mut self) -> Option<Self::Item> where Self: Sized, Self::Item: Eq {
        let first_opt = self.next();
        first_opt.and_then(|first| {
            if self.all(|item| item == first) { Some(first) } else { None }
        })
    }
    fn group_by<K: Eq, F: FnMut(&Self::Item) -> K>(mut self, mut f: F) -> GroupBy<K, Self, F> where Self: Sized {
        let next = self.next();
        GroupBy {
            cur: next.map(|item| {
                let key = f(&item);
                (item, key)
            }),
            iter: self,
            key_fn: f
        }
    }
    fn run_length(mut self) -> RunLength<Self> where Self: Sized, Self::Item: Eq {
        RunLength {
            cur: self.next(),
            iter: self
        }
    }
    fn join<T: std::fmt::Display>(mut self, sep: T) -> String
    where
        Self: Sized, Self::Item: std::fmt::Display
    {
        let mut result = String::new();
        if let Some(first) = self.next() {
            result.push_str(&format!("{}", first));
        }
        for s in self {
            result.push_str(&format!("{}{}", sep, s));
        }
        result
    }
    fn cat(self) -> String where Self: Sized, Self::Item: std::fmt::Display { self.join("") }
}
impl<I: Iterator> IteratorExt for I {}
pub trait IteratorInnerProduct<T, Rhs=T>: ExactSizeIterator<Item=T> {
    fn inner_product<I, J>(self, other: I) -> Option<<T as std::ops::Mul<Rhs>>::Output>
    where
        Self: Sized,
        I: IntoIterator<Item=Rhs, IntoIter=J>,
        J: Iterator<Item=Rhs> + ExactSizeIterator,
        T: std::ops::Mul<Rhs>,
        <T as std::ops::Mul<Rhs>>::Output: std::iter::Sum
    {
        let iter = other.into_iter();
        (self.len() == iter.len()).then_with(|| {
            self.zip(iter).map(|(a, b)| a * b).sum()
        })
    }
}
impl<T1, T2, I> IteratorInnerProduct<T1, T2> for I
where
    I: Iterator<Item=T1> + ExactSizeIterator,
    T1: std::ops::Mul<T2>
{}
pub struct Unfold<T, F> where F: FnMut(&T) -> Option<T> {
    state: Option<T>,
    f: F
}
impl<T, F> Iterator for Unfold<T, F> where F: FnMut(&T) -> Option<T> {
    type Item = T;
    fn next(&mut self) -> Option<T> {
        if self.state.is_none() {
            return None;
        }
        let state_inner = self.state.take().unwrap();
        self.state = (self.f)(&state_inner);
        Some(state_inner)
    }
}
pub fn unfold<T, F>(init: T, f: F) -> Unfold<T, F> where F: FnMut(&T) -> Option<T> {
    Unfold { state: Some(init), f: f }
}
pub struct Iterate<T, F> where F: FnMut(&T) -> T {
    state: T,
    f: F
}
impl<T, F> Iterator for Iterate<T, F> where F: FnMut(&T) -> T {
    type Item = T;
    fn next(&mut self) -> Option<T> {
        use std::mem::swap;
        let mut state = (self.f)(&self.state);
        swap(&mut state, &mut self.state);
        Some(state)
    }
}
pub fn iterate<T, F>(init: T, f: F) -> Iterate<T, F>
where
    F: FnMut(&T) -> T,
{
    Iterate { state: init, f: f }
}

// END SNIPPETS
// Here is the documentation: https://yoshrc.github.io/rust-atcoder-snippets/atcoder_snippets/index.html

trait SliceExt2<T> {
    fn fill(&mut self, val: T);
}

impl<T: Clone> SliceExt2<T> for [T] {
    fn fill(&mut self, val: T) {
        for x in self {
            *x = val.clone();
        }
    }
}

const END_BIT: u64 = 64;

#[derive(Clone, Copy, PartialEq, Eq, Debug)]
enum Constraint {
    Determined(u64),
    AtLeastOne(u64)
}
use Constraint::*;

fn solve(rows: &[Constraint], cols: &[Constraint]) -> Option<Table<u64>> {
    let n = rows.len();
    let mut res = table![0; n,n];

    let mut rows_contains = [false, false];
    let mut undetermined_rows = Vec::new();
    for (i, row) in rows.iter().enumerate() {
        match row {
            &Determined(x) => {
                rows_contains[x as usize] = true;
                res[i].fill(x)
            },
            &AtLeastOne(x) => {
                undetermined_rows.push((i, x));
            }
        }
    }

    let mut cols_contains = [false, false];
    let mut undetermined_cols = Vec::new();
    for (i, col) in cols.iter().enumerate() {
        match col {
            &Determined(x) => {
                if rows_contains[(x ^ 1) as usize] {
                    return None;
                }
                cols_contains[x as usize] = true;
                for j in 0..n {
                    res[j][i] = x;
                }
            },
            &AtLeastOne(x) => {
                undetermined_cols.push((i, (!rows_contains[x as usize]).then(x)));
            }
        }
    }

    let undetermined_rows: Vec<_> = undetermined_rows.into_iter()
        .map(|(i, x)| (i, (!cols_contains[x as usize]).then(x)))
        .collect();

    if undetermined_rows.len() == 0 || undetermined_cols.len() == 0 {
        (undetermined_rows.into_iter().all(|(_, x)| {
             x.map_or(true, |x| cols_contains[x as usize])
         }) &&
         undetermined_cols.into_iter().all(|(_, x)| {
             x.map_or(true, |x| rows_contains[x as usize])
         }))
            .then(res)
    } else if undetermined_rows.len() == 1 {
        let (i, at_least) = undetermined_rows[0];
        match at_least {
            None => {
                for (j, x) in undetermined_cols {
                    res[i][j] = x.unwrap_or(0);
                }
                Some(res)
            },
            Some(at_least) => {
                for (j, x) in undetermined_cols {
                    let x = x.unwrap_or(at_least);
                    res[i][j] = x;
                    cols_contains[x as usize] = true;
                }
                cols_contains[at_least as usize].then(res)
            }
        }
    } else if undetermined_cols.len() == 1 {
        let (j, at_least) = undetermined_cols[0];
        match at_least {
            None => {
                for (i, x) in undetermined_rows {
                    res[i][j] = x.unwrap_or(0);
                }
                Some(res)
            },
            Some(at_least) => {
                for (i, x) in undetermined_rows {
                    let x = x.unwrap_or(at_least);
                    res[i][j] = x;
                    rows_contains[x as usize] = true;
                }
                rows_contains[at_least as usize].then(res)
            }
        }
    } else {
        let mut init = 0;
        for (i, _) in undetermined_rows {
            let mut x = init;
            for &(j, _) in &undetermined_cols {
                res[i][j] = x;
                x ^= 1;
            }
            init ^= 1;
        }
        Some(res)
    }
}

fn main() {
    read!(n = usize);
    read_chunk!(s = Vec<u8>, t = Vec<u8>, u = Vec<u64>, v = Vec<u64>);
    let mut ans = vec![vec![0u64; n]; n];
    for i in 0..END_BIT {
        let u: Vec<u64> = u.iter().map(|&x| (x >> i) & 1).collect();
        let v: Vec<u64> = v.iter().map(|&x| (x >> i) & 1).collect();
        let rows: Vec<Constraint> = s.iter().zip(u).map(|(&s, u)| match (s, u) {
            (0, 0) => AtLeastOne(0),
            (0, 1) => Determined(1),
            (1, 0) => Determined(0),
            _ => AtLeastOne(1)
        }).collect();
        let cols: Vec<Constraint> = t.iter().zip(v).map(|(&s, u)| match (s, u) {
            (0, 0) => AtLeastOne(0),
            (0, 1) => Determined(1),
            (1, 0) => Determined(0),
            _ => AtLeastOne(1)
        }).collect();
        match solve(&rows, &cols) {
            None => exit("-1"),
            Some(res) => {
                for y in 0..n {
                    for x in 0..n {
                        ans[y][x] |= res[y][x] << i;
                    }
                }
            }
        }
    }
    for row in ans {
        println!("{}", row.into_iter().join(" "));
    }
}