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: Wrong Answer)

#include <bits/stdc++.h>
using namespace std;
using ll = unsigned long long;
using ull = unsigned long long;
#define REP(i, n)    for (ll (i) = 0;   (i) < (n); ++(i))
#define FOR(i, a, b) for (ll (i) = (a); (i) < (b); ++(i))

template<typename T>
void PV(T &v) {
    int sz = v.size();
    for (int i = 0; i < sz; ++i) cout << v[i] << " \n"[i == sz - 1];
}

int f(int t, int n) { return (t << 1) + n; }
const int AND = 0;
const int OR_ = 1;
const int ALL_0 = f(OR_, 0);
const int ALL_1 = f(AND, 1);
const int ANY_0 = f(AND, 0);
const int ANY_1 = f(OR_, 1);
bool isall(int t) { return (t == ALL_0) or (t == ALL_1); }
bool isany(int t) { return (t == ANY_0) or (t == ANY_1); }

int N;
vector<int> S, T;
vector<ull> U, V;

void invalid() {
    cout << -1 << endl;
    exit(0);
}

vector<vector<int>> solve(vector<int> &u, vector<int> &v) {
    vector<vector<int>> res(N, vector<int>(N, -1));
    vector<int> tx(N), ty(N);
    REP(i, N) tx[i] = f(S[i], u[i]);
    REP(i, N) ty[i] = f(T[i], v[i]);
    vector<vector<pair<int, int>>> pr;
    REP(i, N) {
        vector<pair<int, int>> tmp;
        REP(j, N) {
            if (isall(tx[i]) and isall(ty[j])) {
                if (tx[i] == ty[j]) res[i][j] = (tx[i] == ALL_0) ? 0 : 1;
                else invalid();
            } else if (isall(tx[i])) {
                res[i][j] = (tx[i] == ALL_0) ? 0 : 1;
            } else if (isall(ty[j])) {
                res[i][j] = (ty[j] == ALL_0) ? 0 : 1;
            } else {
                tmp.emplace_back(i, j);
            }
        }
        if (tmp.size() == 0) continue;
        pr.emplace_back(tmp);
    }

    if (pr.size() == 0 or pr[0].size() == 0) {
        REP(i, N) REP(j, N) if (res[i][j] == -1) assert(false);
        REP(i, N) {
            int _0 = 0, _1 = 0;
            REP(j, N) (res[i][j] == 0 ? _0 : _1)++;
            if (tx[i] == ALL_0 and _1 != 0) invalid();
            if (tx[i] == ALL_1 and _0 != 0) invalid();
            if (tx[i] == ANY_0 and _0 == 0) invalid();
            if (tx[i] == ANY_1 and _1 == 0) invalid();
        }
        REP(j, N) {
            int _0 = 0, _1 = 0;
            REP(i, N) (res[i][j] == 0 ? _0 : _1)++;
            if (ty[j] == ALL_0 and _1 != 0) invalid();
            if (ty[j] == ALL_1 and _0 != 0) invalid();
            if (ty[j] == ANY_0 and _0 == 0) invalid();
            if (ty[j] == ANY_1 and _1 == 0) invalid();
        }
        return res;
    }
    int H = pr.size(), W = pr[0].size();

    if (H > 1 and W > 1) {
        REP(h, H) REP(w, W) {
            int x, y;
            tie(x, y) = pr[h][w];
            res[x][y] = (h + w) % 2;
        }
    } else if (H == 1) {
        bool flg[2]; flg[0] = flg[1] = false;
        REP(w, W) {
            int x, y;
            tie(x, y) = pr[0][w];
            res[x][y] = (ty[y] == ANY_0) ? 0 : 1;
            flg[res[x][y]] = true;
        }
        if ((tx[pr[0][0].first] == ANY_0) and not flg[0]) invalid();
        if ((tx[pr[0][0].first] == ANY_1) and not flg[1]) invalid();
    } else {
        bool flg[2]; flg[0] = flg[1] = false;
        REP(h, H) {
            int x, y;
            tie(x, y) = pr[h][0];
            res[x][y] = (tx[x] == ANY_0) ? 0 : 1;
            flg[res[x][y]] = true;
        }
        if ((ty[pr[0][0].second] == ANY_0) and not flg[0]) invalid();
        if ((ty[pr[0][0].second] == ANY_1) and not flg[1]) invalid();
    }
    return res;
}

signed main() {

    cin >> N;

    S.resize(N); for (auto& e: S) cin >> e;
    T.resize(N); for (auto& e: T) cin >> e;
    U.resize(N); for (auto& e: U) cin >> e;
    V.resize(N); for (auto& e: V) cin >> e;

    vector<vector<ull>> res(N, vector<ull>(N, 0ULL));
    REP(i, 64) {
        vector<int> u(N), v(N);
        REP(j, N) u[j] = (U[j] >> i) & 1, v[j] = (V[j] >> i) & 1;
        auto mat = solve(u, v);
        REP(j, N) REP(k, N) res[j][k] |= ull(mat[j][k]) << i;
    }

    REP(i, N) REP(j, N) cout << res[i][j] << " \n"[j == N - 1];

}