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 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;

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 BitCount(ulong 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 MSB(ulong 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 ULong
        {
            [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[] ULong { get { var arr = new ulong[count]; for (var i = 0; i < count; i++) arr[i] = cr.ULong; 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);
    }
}
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 string Result() => Calc().ToString();
    public object Calc()
    {
        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).Select(cr => (BitArray)cr.ULong);
        v = cr.Repeat(N).Select(cr => (BitArray)cr.ULong);
        mat = NewArray(N, N, 64, (Status)(-1));
        for (int i = 0; i < N; i++)
            for (int j = 0; j < N; j++)
                for (int b = 0; b < 64; b++)
                {
                    if (s[i] && u[i][b] && t[j] && v[j][b])
                        mat[i][j][b] = Status.One;
                    else if (s[i] && u[i][b] && t[j] && !v[j][b])
                        mat[i][j][b] = Status.Zero;
                    else if (s[i] && u[i][b] && !t[j] && v[j][b])
                        mat[i][j][b] = Status.One;
                    else if (s[i] && u[i][b] && !t[j] && !v[j][b])
                        mat[i][j][b] = Status.WantIOneJZero;
                    else if (s[i] && !u[i][b] && t[j] && v[j][b])
                        mat[i][j][b] = Status.Zero;
                    else if (s[i] && !u[i][b] && t[j] && !v[j][b])
                        mat[i][j][b] = Status.Zero;
                    else if (s[i] && !u[i][b] && !t[j] && v[j][b])
                        return -1;
                    else if (s[i] && !u[i][b] && !t[j] && !v[j][b])
                        mat[i][j][b] = Status.Zero;
                    else if (!s[i] && u[i][b] && t[j] && v[j][b])
                        mat[i][j][b] = Status.One;
                    else if (!s[i] && u[i][b] && t[j] && !v[j][b])
                        return -1;
                    else if (!s[i] && u[i][b] && !t[j] && v[j][b])
                        mat[i][j][b] = Status.One;
                    else if (!s[i] && u[i][b] && !t[j] && !v[j][b])
                        mat[i][j][b] = Status.One;
                    else if (!s[i] && !u[i][b] && t[j] && v[j][b])
                        mat[i][j][b] = Status.WantIZeroJOne;
                    else if (!s[i] && !u[i][b] && t[j] && !v[j][b])
                        mat[i][j][b] = Status.Zero;
                    else if (!s[i] && !u[i][b] && !t[j] && v[j][b])
                        mat[i][j][b] = Status.One;
                    else if (!s[i] && !u[i][b] && !t[j] && !v[j][b])
                        mat[i][j][b] = Status.Zero;
                }

        var allnokori = 0;
        var tate = NewArray(N, 64, 4, 0);
        var yoko = NewArray(N, 64, 4, 0);
        for (int i = 0; i < N; i++)
            for (int j = 0; j < N; j++)
                for (int b = 0; b < 64; b++)
                {
                    tate[i][b][(int)mat[i][j][b]]++;
                    yoko[j][b][(int)mat[i][j][b]]++;
                    switch (mat[i][j][b])
                    {
                        case Status.WantIOneJZero:
                        case Status.WantIZeroJOne:
                            allnokori++;
                            break;
                    }
                }
        while (allnokori > 0)
        {
            var prevnokori = allnokori;
            var yet = NewArray<(int i, int j)>(64, (-1, -1));
            for (int i = 0; i < N; i++)
                for (int j = 0; j < N; j++)
                    for (int b = 0; b < 64; b++)
                        switch (mat[i][j][b])
                        {
                            case Status.WantIOneJZero:
                                if (tate[i][b][1] > 0)
                                {
                                    mat[i][j][b] = Status.Zero;
                                    tate[i][b][0]++;
                                    yoko[j][b][0]++;
                                    tate[i][b][(int)Status.WantIOneJZero]--;
                                    yoko[j][b][(int)Status.WantIOneJZero]--;
                                    allnokori--; yet[b] = (-2, -2);
                                }
                                else if (yoko[j][b][0] > 0)
                                {
                                    mat[i][j][b] = Status.One;
                                    tate[i][b][1]++;
                                    yoko[j][b][1]++;
                                    tate[i][b][(int)Status.WantIOneJZero]--;
                                    yoko[j][b][(int)Status.WantIOneJZero]--;
                                    allnokori--; yet[b] = (-2, -2);
                                }
                                else if (tate[i][b][(int)Status.WantIOneJZero] == 1 && tate[i][b][0] == N - 1)
                                {
                                    mat[i][j][b] = Status.One;
                                    tate[i][b][1]++;
                                    yoko[j][b][1]++;
                                    tate[i][b][(int)Status.WantIOneJZero]--;
                                    yoko[j][b][(int)Status.WantIOneJZero]--;
                                    allnokori--; yet[b] = (-2, -2);
                                }
                                else if (yoko[i][b][(int)Status.WantIOneJZero] == 1 && yoko[j][b][1] == N - 1)
                                {
                                    mat[i][j][b] = Status.Zero;
                                    tate[i][b][0]++;
                                    yoko[j][b][0]++;
                                    tate[i][b][(int)Status.WantIOneJZero]--;
                                    yoko[j][b][(int)Status.WantIOneJZero]--;
                                    allnokori--; yet[b] = (-2, -2);
                                }
                                else if (yet[b].i == -1) yet[b] = (i, j);
                                break;
                            case Status.WantIZeroJOne:
                                if (tate[i][b][0] > 0)
                                {
                                    mat[i][j][b] = Status.One;
                                    tate[i][b][1]++;
                                    yoko[j][b][1]++;
                                    tate[i][b][(int)Status.WantIZeroJOne]--;
                                    yoko[j][b][(int)Status.WantIZeroJOne]--;
                                    allnokori--; yet[b] = (-2, -2);
                                }
                                else if (yoko[j][b][1] > 0)
                                {
                                    mat[i][j][b] = Status.Zero;
                                    tate[i][b][0]++;
                                    yoko[j][b][0]++;
                                    tate[i][b][(int)Status.WantIZeroJOne]--;
                                    yoko[j][b][(int)Status.WantIZeroJOne]--;
                                    allnokori--; yet[b] = (-2, -2);
                                }
                                else if (tate[i][b][(int)Status.WantIZeroJOne] == 1 && tate[i][b][1] == N - 1)
                                {
                                    mat[i][j][b] = Status.Zero;
                                    tate[i][b][0]++;
                                    yoko[j][b][0]++;
                                    tate[i][b][(int)Status.WantIZeroJOne]--;
                                    yoko[j][b][(int)Status.WantIZeroJOne]--;
                                    allnokori--; yet[b] = (-2, -2);
                                }
                                else if (yoko[i][b][(int)Status.WantIZeroJOne] == 1 && yoko[j][b][0] == N - 1)
                                {
                                    mat[i][j][b] = Status.One;
                                    tate[i][b][1]++;
                                    yoko[j][b][1]++;
                                    tate[i][b][(int)Status.WantIZeroJOne]--;
                                    yoko[j][b][(int)Status.WantIZeroJOne]--;
                                    allnokori--; yet[b] = (-2, -2);
                                }
                                else if (yet[b].i == -1) yet[b] = (i, j);
                                break;
                        }


            for (int b = 0; b < 64; b++)
            {
                var (i, j) = yet[b];
                if (i >= 0)
                {
                    mat[i][j][b] = Status.One;
                    tate[i][b][1]++;
                    yoko[j][b][1]++;
                    tate[i][b][(int)Status.WantIZeroJOne]--;
                    yoko[j][b][(int)Status.WantIZeroJOne]--;
                    allnokori--;
                }
            }

            if (prevnokori == allnokori)
                return -1;
        }
        var res = NewArray(N, N, 0UL);
        for (int i = 0; i < N; i++)
            for (int j = 0; j < N; j++)
                res[i][j] = ToULong(mat[i][j]);

        if (!Validate(res))
            return -1;

        return AllLines(res.Select(m2 => AllJoin(m2)));
    }
    bool Validate(ulong[][] res)
    {
        var ur = new ulong[N];
        var vr = new ulong[N];
        for (int i = 0; i < N; i++)
        {
            if (s[i])
            {
                for (int j = 0; j < N; j++)
                {
                    ur[i] |= res[i][j];
                }
            }
            else
            {
                unchecked { ur[i] -= 1; }
                for (int j = 0; j < N; j++)
                {
                    ur[i] &= res[i][j];
                }
            }
            if (t[i])
            {
                for (int j = 0; j < N; j++)
                {
                    vr[i] |= res[j][i];
                }
            }
            else
            {
                unchecked { vr[i] -= 1; }
                for (int j = 0; j < N; j++)
                {
                    vr[i] &= res[j][i];
                }
            }
        }
        return ur.Zip(u, (r, w) => r == w).All(b=>b) && vr.Zip(v, (r, w) => r == w).All(b=>b);
    }
    ulong ToULong(Status[] sts)
    {
        ulong res = 0;
        for (int i = 0; i < 64; i++)
        {
            if (sts[i] == Status.One)
                res |= (1UL << i);
        }
        return res;
    }
    int N;
    bool[] s;
    bool[] t;
    BitArray[] u;
    BitArray[] v;
    Status[][][] mat;
}
enum Status
{
    Zero = 0,
    One = 1,
    WantIOneJZero = 2,
    WantIZeroJOne = 3,
}
struct BitArray : IEquatable<BitArray>, IEnumerable<bool>
{
    private readonly ulong num;
    public BitArray(ulong num) { this.num = num; }
    public bool this[int index] => ((num >> index) & 1) != 0;

    public static BitArray operator &(BitArray bits, ulong r) => new BitArray(bits.num & r);
    public static BitArray operator |(BitArray bits, ulong r) => new BitArray(bits.num | r);
    public static BitArray operator ^(BitArray bits, ulong r) => new BitArray(bits.num ^ r);
    public static BitArray operator +(BitArray bits, ulong r) => new BitArray(bits.num + r);
    public static BitArray operator -(BitArray bits, ulong r) => new BitArray(bits.num - r);
    public static implicit operator BitArray(ulong num) => new BitArray(num);
    public static implicit operator ulong(BitArray bits) => bits.num;

    public override string ToString() => Convert.ToString((long)num, 2).PadLeft(sizeof(long) * 8, '0');
    public bool Equals(BitArray other) => this.num == other.num;
    public override bool Equals(object obj) => obj is BitArray && Equals((BitArray)obj);
    public override int GetHashCode() => this.num.GetHashCode();
    public IEnumerable<int> Bits()
    {
        var msb = MSB(this) + 1;
        for (var i = 0; i < msb; i++)
            if (((num >> i) & 1) == 1)
                yield return i;
    }
    public IEnumerator<bool> GetEnumerator()
    {
        const int len = sizeof(long) * 8;
        for (var i = 0; i < len; i++)
            yield return ((num >> i) & 1) == 1;
    }
    IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
}