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 C# (Mono-csc 3.5.0) (judge verdict: Accepted)

#region いつもの
using System;
using System.Collections.Generic;
using System.Linq;
using AtCoderProject;
using ConsoleReader = AtCoderProject.Reader.ConsoleReader;
using IEnumerable = System.Collections.IEnumerable;
using IEnumerator = System.Collections.IEnumerator;
using BigInteger = System.Numerics.BigInteger;
using TextReader = System.IO.TextReader;
using StringBuilder = System.Text.StringBuilder;
using static AtCoderProject.Global;
using static AtCoderProject.NumGlobal;
using System.Resources;
using System.Threading.Tasks;

namespace AtCoderProject
{
    public static class Global
    {
        public static T[] NewArray<T>(int len0, T value) => new T[len0].Fill(value);
        public static T[] NewArray<T>(int len0, Func<T> factory)
        {
            var arr = new T[len0];
            for (int i = 0; i < arr.Length; i++) arr[i] = factory();
            return arr;
        }
        public static T[][] NewArray<T>(int len0, int len1, T value) where T : struct
        {
            var arr = new T[len0][];
            for (int i = 0; i < arr.Length; i++) arr[i] = NewArray(len1, value);
            return arr;
        }
        public static T[][] NewArray<T>(int len0, int len1, Func<T> factory)
        {
            var arr = new T[len0][];
            for (int i = 0; i < arr.Length; i++) arr[i] = NewArray(len1, factory);
            return arr;
        }
        public static T[][][] NewArray<T>(int len0, int len1, int len2, T value) where T : struct
        {
            var arr = new T[len0][][];
            for (int i = 0; i < arr.Length; i++) arr[i] = NewArray(len1, len2, value);
            return arr;
        }
        public static T[][][] NewArray<T>(int len0, int len1, int len2, Func<T> factory)
        {
            var arr = new T[len0][][];
            for (int i = 0; i < arr.Length; i++) arr[i] = NewArray(len1, len2, factory);
            return arr;
        }
        public static T[][][][] NewArray<T>(int len0, int len1, int len2, int len3, T value) where T : struct
        {
            var arr = new T[len0][][][];
            for (int i = 0; i < arr.Length; i++) arr[i] = NewArray(len1, len2, len3, value);
            return arr;
        }
        public static T[][][][] NewArray<T>(int len0, int len1, int len2, int len3, Func<T> factory)
        {
            var arr = new T[len0][][][];
            for (int i = 0; i < arr.Length; i++) arr[i] = NewArray(len1, len2, len3, factory);
            return arr;
        }
        private class ComparerReverseImpl<T> : Comparer<T> where T : IComparable<T> { public override int Compare(T y, T x) => x.CompareTo(y); public override bool Equals(object obj) => obj != null && GetType() == obj.GetType(); public override int GetHashCode() => GetType().GetHashCode(); }
        public static IComparer<T> ComparerReverse<T>() where T : IComparable<T> => new ComparerReverseImpl<T>();
        public static string AllLines<T>(IEnumerable<T> source) => string.Join("\n", source);
        public static string AllJoin<T>(IEnumerable<T> source) => string.Join(" ", source);
    }
    public static class NumGlobal
    {
        public static int Pow(int x, int y)
        {
            int res = 1;
            for (; y > 0; y >>= 1)
            {
                if ((y & 1) == 1) res *= x;
                x *= x;
            }
            return res;
        }
        public static BigInteger ParseBigInteger(ReadOnlySpan<char> s)
        {
            // 自前実装の方が速い
            BigInteger res;
            if (s.Length % 9 == 0)
                res = 0;
            else
            {
                res = new BigInteger(int.Parse(s.Slice(0, s.Length % 9)));
                s = s.Slice(s.Length % 9);
            }

            while (s.Length > 0)
            {
                var sp = s.Slice(0, 9);
                res *= 1000_000_000;
                res += int.Parse(sp);
                s = s.Slice(9);
            }
            return res;
        }
        public static int BitCount(int x) { x -= (x >> 1) & 0x55555555; x = (x & 0x33333333) + ((x >> 2) & 0x33333333); x = (x + (x >> 4)) & 0x0f0f0f0f; x += x >> 8; x += x >> 16; return x & 0x3f; }
        public static int BitCount(long x) { x -= (x >> 1) & 0x5555555555555555; x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333); x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0f; x += x >> 8; x += x >> 16; x += x >> 32; return (int)(x & 0x0000007f); }
        public static int MSB(int x) { x |= x >> 1; x |= x >> 2; x |= x >> 4; x |= x >> 8; x |= x >> 16; return BitCount(x) - 1; }
        public static int MSB(long x) { x |= x >> 1; x |= x >> 2; x |= x >> 4; x |= x >> 8; x |= x >> 16; x |= x >> 32; return BitCount(x) - 1; }
        public static int LSB(int x) { x |= x << 1; x |= x << 2; x |= x << 4; x |= x << 8; x |= x << 16; return 32 - BitCount(x); }
        public static int LSB(long x) { x |= x << 1; x |= x << 2; x |= x << 4; x |= x << 8; x |= x << 16; x |= x << 32; return 64 - BitCount(x); }
    }
    public static class Ext
    {
        public static long ToLong(this int i) => i;
        public static T[] Fill<T>(this T[] arr, T value)
        {
            Array.Fill(arr, value);
            return arr;
        }
        public static T[] Sort<T>(this T[] arr) { Array.Sort(arr); return arr; }
        public static string[] Sort(this string[] arr) => Sort(arr, StringComparer.OrdinalIgnoreCase);
        public static T[] Sort<T, U>(this T[] arr, Func<T, U> selector) where U : IComparable<U> => Sort(arr, (a, b) => selector(a).CompareTo(selector(b)));
        public static T[] Sort<T>(this T[] arr, Comparison<T> comparison) { Array.Sort(arr, comparison); return arr; }
        public static T[] Sort<T>(this T[] arr, IComparer<T> comparer) { Array.Sort(arr, comparer); return arr; }
        public static T[] Reverse<T>(this T[] arr) { Array.Reverse(arr); return arr; }
        public static (int index, T max) MaxBy<T>(this T[] arr) where T : IComparable<T>
        {
            T max = arr[0];
            int maxIndex = 0;
            for (int i = 0; i < arr.Length; i++)
            {
                if (max.CompareTo(arr[i]) < 0)
                {
                    max = arr[i];
                    maxIndex = i;
                }
            }
            return (maxIndex, max);
        }
        public static (TSource item, TMax max) MaxBy<TSource, TMax>
            (this IEnumerable<TSource> source, Func<TSource, TMax> maxBySelector)
            where TMax : IComparable<TMax>
        {
            TMax max;
            TSource maxByItem;
            var e = source.GetEnumerator();
            e.MoveNext();
            maxByItem = e.Current;
            max = maxBySelector(maxByItem);
            while (e.MoveNext())
            {
                var item = e.Current;
                var next = maxBySelector(item);
                if (max.CompareTo(next) < 0)
                {
                    max = next;
                    maxByItem = item;
                }
            }
            return (maxByItem, max);
        }
        public static (int index, T min) MinBy<T>(this T[] arr) where T : IComparable<T>
        {
            T min = arr[0];
            int minIndex = 0;
            for (int i = 0; i < arr.Length; i++)
            {
                if (min.CompareTo(arr[i]) > 0)
                {
                    min = arr[i];
                    minIndex = i;
                }
            }
            return (minIndex, min);
        }
        public static (TSource item, TMin min) MinBy<TSource, TMin>
            (this IEnumerable<TSource> source, Func<TSource, TMin> minBySelector)
            where TMin : IComparable<TMin>
        {
            TMin min;
            TSource minByItem;

            var e = source.GetEnumerator();
            e.MoveNext();
            minByItem = e.Current;
            min = minBySelector(minByItem);
            while (e.MoveNext())
            {
                var item = e.Current;
                var next = minBySelector(item);
                if (min.CompareTo(next) > 0)
                {
                    min = next;
                    minByItem = item;
                }
            }
            return (minByItem, min);
        }
        public static IComparer<T> Reverse<T>(this IComparer<T> comparer) => Comparer<T>.Create((x, y) => comparer.Compare(y, x));
        public static Dictionary<TKey, int> GroupCount<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) => source.GroupBy(keySelector).ToDictionary(g => g.Key, g => g.Count());
        public static Dictionary<TKey, int> GroupCount<TKey>(this IEnumerable<TKey> source) => source.GroupCount(i => i);
        public static TValue Get<TKey, TValue>(this Dictionary<TKey, TValue> dic, TKey key)
        {
            dic.TryGetValue(key, out var v);
            return v;
        }
        public static TValue GetOrInit<TKey, TValue>(this Dictionary<TKey, TValue> dic, TKey key, TValue value)
        {
            if (dic.TryGetValue(key, out var v))
                return v;
            return dic[key] = value;
        }
    }
    public class ΔDebugView<T> { private IEnumerable<T> collection; public ΔDebugView(IEnumerable<T> collection) { this.collection = collection ?? throw new ArgumentNullException(nameof(collection)); }[System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)] public T[] Items => collection.ToArray(); }
}
namespace AtCoderProject.Reader
{
    using System.IO;
    using System.Text;
    using System.Diagnostics;
    using System.Runtime.CompilerServices;
#pragma warning disable CA1819
    [DebuggerNonUserCode]
    public class ConsoleReader
    {
        const int BufSize = 1 << 12;
        private readonly byte[] buffer = new byte[BufSize];
        private readonly Stream input;
        private readonly Encoding encoding;
        private int pos = 0;
        private int len = 0;
        public ConsoleReader(Stream input, Encoding encoding) { this.input = input; this.encoding = encoding; }
        public ConsoleReader(Stream input) : this(input, Encoding.UTF8) { }
        public ConsoleReader(string text) : this(new MemoryStream(Encoding.UTF8.GetBytes(text))) { }
        private void MoveNext() { if (++pos >= len) { len = input.Read(buffer, 0, buffer.Length); if (len == 0) { buffer[0] = 10; } pos = 0; } }

        public int Int
        {
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            get
            {
                int res = 0;
                bool neg = false;
                while (buffer[pos] < 48) { neg = buffer[pos] == 45; MoveNext(); }
                do { res = res * 10 + (buffer[pos] ^ 48); MoveNext(); } while (48 <= buffer[pos]);
                return neg ? -res : res;
            }
        }
        public int Int0 => this.Int - 1;
        public ulong Long
        {
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            get
            {
                ulong res = 0;
                while (buffer[pos] < 48) { MoveNext(); }
                do { res = res * 10 + (buffer[pos] ^ 48U); MoveNext(); } while (48 <= buffer[pos]);
                return res;
            }
        }
        public string String
        {
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            get
            {
                var sb = new List<byte>();
                while (buffer[pos] <= 32) MoveNext();
                do { sb.Add(buffer[pos]); MoveNext(); } while (32 < buffer[pos]);
                return this.encoding.GetString(sb.ToArray());
            }
        }
        public string Ascii
        {
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            get
            {
                var sb = new StringBuilder();
                while (buffer[pos] <= 32) MoveNext();
                do { sb.Append((char)buffer[pos]); MoveNext(); } while (32 < buffer[pos]);
                return sb.ToString();
            }
        }
        public string Line
        {
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            get
            {
                var sb = new List<byte>();
                while (buffer[pos] < 32) MoveNext();
                do { sb.Add(buffer[pos]); MoveNext(); } while (buffer[pos] != 10 && buffer[pos] != 13);
                return this.encoding.GetString(sb.ToArray());
            }
        }
        public double Double => double.Parse(this.Ascii);

        [DebuggerNonUserCode]
        public struct RepeatReader
        {
            ConsoleReader cr;
            int count;
            public RepeatReader(ConsoleReader cr, int count) { this.cr = cr; this.count = count; }
            public T[] Select<T>(Func<ConsoleReader, T> factory) { var arr = new T[count]; for (var i = 0; i < count; i++) arr[i] = factory(cr); return arr; }
            public string[] Line { get { var arr = new string[count]; for (var i = 0; i < count; i++) arr[i] = cr.Line; return arr; } }
            public string[] String { get { var arr = new string[count]; for (var i = 0; i < count; i++) arr[i] = cr.String; return arr; } }
            public string[] Ascii { get { var arr = new string[count]; for (var i = 0; i < count; i++) arr[i] = cr.Ascii; return arr; } }
            public int[] Int { get { var arr = new int[count]; for (var i = 0; i < count; i++) arr[i] = cr.Int; return arr; } }
            public int[] Int0 { get { var arr = new int[count]; for (var i = 0; i < count; i++) arr[i] = cr.Int0; return arr; } }
            public ulong[] Long { get { var arr = new ulong[count]; for (var i = 0; i < count; i++) arr[i] = cr.Long; return arr; } }
            public double[] Double { get { var arr = new double[count]; for (var i = 0; i < count; i++) arr[i] = cr.Double; return arr; } }
        }
        public RepeatReader Repeat(int count) => new RepeatReader(this, count);

        [DebuggerNonUserCode]
        public struct SplitReader
        {
            ConsoleReader cr;
            public SplitReader(ConsoleReader cr) { this.cr = cr; }
            public string[] String { get { while (cr.buffer[cr.pos] <= 32) cr.MoveNext(); var list = new List<string>(); do { if (cr.buffer[cr.pos] < 32) cr.MoveNext(); else list.Add(cr.String); } while (cr.buffer[cr.pos] != 10 && cr.buffer[cr.pos] != 13); return list.ToArray(); } }
            public string[] Ascii { get { while (cr.buffer[cr.pos] <= 32) cr.MoveNext(); var list = new List<string>(); do { if (cr.buffer[cr.pos] < 32) cr.MoveNext(); else list.Add(cr.Ascii); } while (cr.buffer[cr.pos] != 10 && cr.buffer[cr.pos] != 13); return list.ToArray(); } }
            public int[] Int { get { while (cr.buffer[cr.pos] <= 32) cr.MoveNext(); var list = new List<int>(); do { if (cr.buffer[cr.pos] < 32) cr.MoveNext(); else list.Add(cr.Int); } while (cr.buffer[cr.pos] != 10 && cr.buffer[cr.pos] != 13); return list.ToArray(); } }
            public int[] Int0 { get { while (cr.buffer[cr.pos] <= 32) cr.MoveNext(); var list = new List<int>(); do { if (cr.buffer[cr.pos] < 32) cr.MoveNext(); else list.Add(cr.Int0); } while (cr.buffer[cr.pos] != 10 && cr.buffer[cr.pos] != 13); return list.ToArray(); } }
            public double[] Double { get { while (cr.buffer[cr.pos] <= 32) cr.MoveNext(); var list = new List<double>(); do { if (cr.buffer[cr.pos] < 32) cr.MoveNext(); else list.Add(cr.Double); } while (cr.buffer[cr.pos] != 10 && cr.buffer[cr.pos] != 13); return list.ToArray(); } }
        }
        public SplitReader Split => new SplitReader(this);
    }
}
public class Program
{
    [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)] private ConsoleReader cr;

    public Program(ConsoleReader consoleReader) { this.cr = consoleReader; }
    static void Main() => Console.WriteLine(new Program(new ConsoleReader(Console.OpenStandardInput())).Result());
    #endregion
    public object Result()
    {
        N = cr.Int;
        s = cr.Repeat(N).Select(cr => cr.Int != 0);
        t = cr.Repeat(N).Select(cr => cr.Int != 0);
        u = cr.Repeat(N).Long;
        v = cr.Repeat(N).Long;
        mat = NewArray(64, N * N, 0);
        try
        {
            for (int b = 0; b < 64; b++)
                for (int i = 0; i < N; i++)
                    for (int j = 0; j < N; j++)
                        mat[b][i * N + j] = M(s[i], ((u[i] >> b) & 1) != 0, t[j], ((v[j] >> b) & 1) != 0);
        }
        catch
        {
            return -1;
        }


        Parallel.For(0, 64, CalcImpl);

        var res = NewArray(N, N, 0UL);
        for (int b = 0; b < 64; b++)
            for (int i = 0; i < N; i++)
                for (int j = 0; j < N; j++)
                    res[i][j] |= ((ulong)mat[b][i * N + j] << b);

        if (Validate(res))
            return AllLines(res.Select(AllJoin));

        return -1;
    }

    void CalcImpl(int b)
    {
        var mat = this.mat[b];
        var nokori = 0;
        var tate = NewArray(N, 4, 0);
        var yoko = NewArray(N, 4, 0);
        for (int i = 0; i < N; i++)
            for (int j = 0; j < N; j++)
            {
                tate[i][mat[i * N + j]]++;
                yoko[j][mat[i * N + j]]++;
                if (mat[i * N + j] > 1)
                    nokori++;
            }

        while (nokori > 0)
        {
            var prevnokori = nokori;
            (int i, int j) yet = (-1, -1);
            for (int i = 0; i < N; i++)
                for (int j = 0; j < N; j++)
                {
                    switch (mat[i * N + j])
                    {
                        case IZEROJONE:
                            if (tate[i][0] > 0)
                            {
                                mat[i * N + j] = ONE;
                                tate[i][IZEROJONE]--;
                                yoko[j][IZEROJONE]--;
                                tate[i][1]++;
                                yoko[j][1]++;
                                nokori--;
                            }
                            else if (yoko[j][1] > 0)
                            {
                                mat[i * N + j] = ZERO;
                                tate[i][IZEROJONE]--;
                                yoko[j][IZEROJONE]--;
                                tate[i][0]++;
                                yoko[j][0]++;
                                nokori--;
                            }
                            else if (tate[i][IZEROJONE] == 1 && tate[i][ONE] == N - 1)
                            {
                                mat[i * N + j] = ZERO;
                                tate[i][IZEROJONE]--;
                                yoko[j][IZEROJONE]--;
                                tate[i][0]++;
                                yoko[j][0]++;
                                nokori--;
                            }
                            else if (yoko[j][IZEROJONE] == 1 && yoko[j][ZERO] == N - 1)
                            {
                                mat[i * N + j] = ONE;
                                tate[i][IZEROJONE]--;
                                yoko[j][IZEROJONE]--;
                                tate[i][1]++;
                                yoko[j][1]++;
                                nokori--;
                            }
                            yet = (i, j);
                            break;
                        case IONEJZERO:
                            if (yoko[j][0] > 0)
                            {
                                mat[i * N + j] = ONE;
                                tate[i][IONEJZERO]--;
                                yoko[j][IONEJZERO]--;
                                tate[i][1]++;
                                yoko[j][1]++;
                                nokori--;
                            }
                            else if (tate[i][1] > 0)
                            {
                                mat[i * N + j] = ZERO;
                                tate[i][IONEJZERO]--;
                                yoko[j][IONEJZERO]--;
                                tate[i][0]++;
                                yoko[j][0]++;
                                nokori--;
                            }
                            else if (yoko[j][IONEJZERO] == 1 && yoko[j][ONE] == N - 1)
                            {
                                mat[i * N + j] = ZERO;
                                tate[i][IONEJZERO]--;
                                yoko[j][IONEJZERO]--;
                                tate[i][0]++;
                                yoko[j][0]++;
                                nokori--;
                            }
                            else if (tate[i][IONEJZERO] == 1 && tate[i][ZERO] == N - 1)
                            {
                                mat[i * N + j] = ONE;
                                tate[i][IONEJZERO]--;
                                yoko[j][IONEJZERO]--;
                                tate[i][1]++;
                                yoko[j][1]++;
                                nokori--;
                            }
                            yet = (i, j);
                            break;
                    }
                }
            if (prevnokori == nokori)
            {
                var (i, j) = yet;
                tate[i][mat[i * N + j]]--;
                yoko[j][mat[i * N + j]]--;
                mat[i * N + j] = ONE;
                tate[i][1]++;
                yoko[j][1]++;
                nokori--;
            }
        }
    }

    public const int ZERO = 0;
    public const int ONE = 1;
    public const int IZEROJONE = 2;
    public const int IONEJZERO = 3;

    int N;
    bool[] s;
    bool[] t;
    ulong[] u;
    ulong[] v;

    int[][] mat;

    bool Validate(ulong[][] res)
    {
        var ur = s.Select(b => b ? ulong.MinValue : ulong.MaxValue).ToArray();
        var vr = t.Select(b => b ? ulong.MinValue : ulong.MaxValue).ToArray();

        for (int i = 0; i < N; i++)
            for (int j = 0; j < N; j++)
            {
                if (s[i])
                {
                    ur[i] |= res[i][j];
                }
                else
                {
                    ur[i] &= res[i][j];
                }
                if (t[i])
                {
                    vr[i] |= res[j][i];
                }
                else
                {
                    vr[i] &= res[j][i];
                }
            }
        return ur.SequenceEqual(u) && vr.SequenceEqual(v);
    }
    static int MM(bool st, bool uv)
    {
        if (st && uv)
            return 3;
        else if (st && !uv)
            return 0;
        else if (!st && uv)
            return 1;
        else if (!st && !uv)
            return 2;
        return -1;
    }
    static int M(bool s, bool u, bool t, bool v)
    {
        switch (MM(s, u) * 4 + MM(t, v))
        {
            case 0:
            case 2:
            case 3:
                return ZERO;

            case 5:
            case 7:
            case 6:
                return ONE;

            case 8:
            case 10:
                return ZERO;
            case 9:
                return ONE;
            case 11:
                return IZEROJONE;

            case 12:
                return ZERO;
            case 13:
            case 15:
                return ONE;
            case 14:
                return IONEJZERO;
            default:
                throw new InvalidOperationException();
        }
    }
}