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++ (GCC 9.2.1) (judge verdict: Runtime Error)

#include <bits/stdc++.h>
using namespace std;
#define int long
using pi = pair<int, int>;
using u64 = unsigned long long;
void end() {
    cout << -1 << endl;
    exit(0);
}
template <class T>
void printsq(vector<vector<T>>& v, ostream& os=cerr) {
    for (auto w : v) {
        for (auto i : w) {
            os << " " << i;
        }
        os << endl;
    }
}
void printst(vector<vector<bool>>& ssuf, vector<vector<bool>>& tsuf) {
    cerr << "rs\\ct:";
    for (auto v : tsuf) {
        cerr << (v[1] ? "T" : "F") << (v[0] ? "T" : "F");
        cerr << " ";
    }
    cerr << endl;
    for (auto v : ssuf) {
        cerr << (v[1] ? "T" : "F") << (v[0] ? "T" : "F");
        cerr << endl;
    }
    cerr << endl;
}
signed main() {
    int n, m = 0;
    cin >> n;
    vector<int> s(n), t(n);
    vector<vector<bool>> u(64, vector<bool>(n, false)), v(u);
    for (auto& i : s) cin >> i;
    for (auto& i : t) cin >> i;
    for (int i = 0; i < n; ++i) {
        u64 x;
        cin >> x;
        while ((x >> m) > 0) ++m;
        for (int b = 0; x > 0; ++b, x >>= 1) u[b][i] = x & 1;
    }
    for (int i = 0; i < n; ++i) {
        u64 x;
        cin >> x;
        while ((x >> m) > 0) ++m;
        for (int b = 0; x > 0; ++b, x >>= 1) v[b][i] = x & 1;
    }
    vector<vector<vector<int>>> a(64, vector<vector<int>>(n, vector<int>(n, -1)));
    for (int b = 0; b < m; ++b) {
        vector<vector<bool>> ssuf(n, vector<bool>(2, false)), tsuf(ssuf);
        vector<int> us, ut;
        for (int i = 0; i < n; ++i) {
            if (s[i] && !u[b][i]) {
                for (int x = 0; x < n; ++x) {
                    a[b][i][x] = 0;
                    tsuf[x][0] = true;
                }
                ssuf[i][0] = ssuf[i][1] = true;
            } else if (!s[i] && u[b][i]) {
                for (int x = 0; x < n; ++x) {
                    a[b][i][x] = 1;
                    tsuf[x][1] = true;
                }
                ssuf[i][0] = ssuf[i][1] = true;
            } else
                us.push_back(i);
        }
        for (int i = 0; i < n; ++i) {
            if (t[i] && !v[b][i]) {
                for (int x = 0; x < n; ++x) {
                    if (a[b][x][i] == 1) end();
                    a[b][x][i] = 0;
                    ssuf[x][0] = true;
                }
                tsuf[i][0] = tsuf[i][1] = true;
            } else if (!t[i] && v[b][i]) {
                for (int x = 0; x < n; ++x) {
                    if (a[b][x][i] == 0) end();
                    a[b][x][i] = 1;
                    ssuf[x][1] = true;
                }
                tsuf[i][0] = tsuf[i][1] = true;
            } else
                ut.push_back(i);
        }
        if (us.size() > 1 && ut.size() > 1) {
            for (int i = 0; i < us.size(); ++i) {
                for (int j = 0; j < ut.size(); ++j) {
                    a[b][us[i]][ut[j]] = (i + j) & 1;
                }
            }
            continue;
        }

        for (int i = 0; i < n; ++i) {
            if (s[i]) { // wa
                ssuf[i][0] = true;
            } else { // seki
                ssuf[i][1] = true;
            }
        }

        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                if (s[i] && u[b][i]) ssuf[i][0] = true;
                if (t[j] && v[b][j]) tsuf[j][0] = true;
                if (!s[i] && !u[b][i]) ssuf[i][1] = true;
                if (!t[j] && !v[b][j]) tsuf[j][1] = true;
            }
        }

        queue<int> rem;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                if (a[b][i][j] < 0) {
                    if (ssuf[i][0] && tsuf[j][0] && !(ssuf[i][1] && tsuf[j][1])) {
                        a[b][i][j] = 1;
                        ssuf[i][1] = tsuf[j][1] = true;
                    } else if (ssuf[i][1] && tsuf[j][1] && !(ssuf[i][0] && tsuf[j][0])) {
                        a[b][i][j] = 0;
                        ssuf[i][0] = tsuf[j][0] = true;
                    } else {
                        rem.push(us.size() > 1 ? i : j);
                    }
                }
            }
        }

        rem.push(-1);
        if (us.size() == 1) {
            int row = us[0];
            for (int i = rem.front(), p = 0; !rem.empty(); i = rem.front(), rem.pop()) {
                if (i < 0) {
                    p = 1;
                    continue;
                }
                if (tsuf[i][0] && tsuf[i][1]) {
                    if (p) {
                        if (ssuf[row][0])
                            a[b][row][i] = 1, ssuf[row][1] = true;
                        else
                            a[b][row][i] = 0, ssuf[row][0] = true;
                    } else
                        rem.push(i);
                } else if (tsuf[i][0])
                    a[b][row][i] = 1, tsuf[i][1] = true;
                else if (tsuf[i][1])
                    a[b][row][i] = 0, tsuf[i][0] = true;
                else
                    end();
            }

            if (!ssuf[row][0] || !ssuf[row][1]) end();
        } else {
            int col = ut[0];
            for (int i = rem.front(), p = 0; !rem.empty(); i = rem.front(), rem.pop()) {
                if (i < 0) {
                    p = 1;
                    continue;
                }
                if (ssuf[i][0] && ssuf[i][1]) {
                    if (p) {
                        if (tsuf[col][0])
                            a[b][i][col] = 1, tsuf[col][1] = true;
                        else
                            a[b][i][col] = 0, tsuf[col][0] = true;
                    } else
                        rem.push(i);
                } else if (ssuf[i][0])
                    a[b][i][col] = 1, ssuf[i][1] = true;
                else if (ssuf[i][1])
                    a[b][i][col] = 0, ssuf[i][0] = true;
                else
                    end();
            }
            if (!tsuf[col][0] || !tsuf[col][1]) end();
        }
    }
    vector<vector<u64>> res(n, vector<u64>(n, 0));
    for(int i=0;i<n;++i){
        for(int j=0;j<n;++j){
            for (int b = m-1; b >= 0;--b){
                res[i][j] *= 2;
                res[i][j] += (a[b][i][j] ? 1 : 0);
            }
        }
    }
    printsq(res, cout);
}