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 = long long;
using PII = pair<ll, ll>;
#define FOR(i, a, n) for(ll i=(ll)a; i<(ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()
template<typename T> void chmin(T &a, const T &b) { a = min(a, b); }
template<typename T> void chmax(T &a, const T &b) { a = max(a, b); }
struct FastIO {FastIO() { cin.tie(0); ios::sync_with_stdio(0); }}fastiofastio;
#ifdef DEBUG
#include "../program_contest_library/memo/dump.hpp"
#else
#define dump(...)
#endif
constexpr ll INF = 1LL<<60;

int main() {
    ll n;
    cin >> n;
    vector<ll> s(n), t(n), u(n), v(n);
    REP(i, n) cin >> s[i];
    REP(i, n) cin >> t[i];
    REP(i, n) cin >> u[i];
    REP(i, n) cin >> v[i];

    vector<vector<ll>> ans(n, vector<ll>(n));
    REP(i, 64) {
        dump(i);
        vector<vector<int>> used(n, vector<int>(n, -1));
        vector<ll> u2(n), v2(n);
        REP(j, n) u2[j] = !!(u[j]&1LL<<i), v2[j] = !!(v[j]&1LL<<i);
        dump(u2);
        dump(v2);

        auto check = [&] {
            // 行/列についてだめなパターン
            // and 1 に 0 がある
            // or 0 に 1 がある
            // and 0 に 0 がない
            // or 1 に 1 がない
            bool ret = true;
            REP(j, n) {
                bool flag = false;
                if(s[j] == 0 && u2[j] == 1) {
                    flag = true;
                    REP(k, n) if(used[j][k] == 0) flag = false;
                } else if(s[j] == 1 && u2[j] == 0) {
                    flag = true;
                    REP(k, n) if(used[j][k] == 1) flag = false;
                } else if(s[j] == 0 && u2[j] == 0) {
                    flag = false;
                    REP(k, n) if(used[j][k] == 0) flag = true;
                } else if(s[j] == 1 && u2[j] == 1) {
                    flag = false;
                    REP(k, n) if(used[j][k] == 1) flag = true;
                }
                ret &= flag;
            }
            REP(j, n) {
                bool flag = false;
                if(t[j] == 0 && v2[j] == 1) {
                    flag = true;
                    REP(k, n) if(used[k][j] == 0) flag = false;
                } else if(t[j] == 1 && v2[j] == 0) {
                    flag = true;
                    REP(k, n) if(used[k][j] == 1) flag = false;
                } else if(t[j] == 0 && v2[j] == 0) {
                    flag = false;
                    REP(k, n) if(used[k][j] == 0) flag = true;
                } else if(t[j] == 1 && v2[j] == 1) {
                    flag = false;
                    REP(k, n) if(used[k][j] == 1) flag = true;
                }
                ret &= flag;
            }
            return ret;
        };
        
        REP(j, n) {
            if(s[j]==0 && u2[j]==1) {
                REP(k, n) used[j][k] = 1, ans[j][k] |= 1LL<<i;
            } else if(s[j]==1 && u2[j]==0) {
                REP(k, n) used[j][k] = 0;
            }
        }
        REP(j, n) {
            if(t[j]==0 && v2[j]==1) {
                REP(k, n) {
                    if(used[k][j]==-1) used[k][j] = 1, ans[k][j] |= 1LL<<i;
                    else if(used[k][j] != 1) {
                        cout << -1 << endl;
                        return 0;
                    }
                }
            } else if(t[j]==1 && v2[j]==0) {
                REP(k, n) {
                    if(used[k][j]==-1) used[k][j] = 0;
                    else if(used[k][j] != 0) {
                        cout << -1 << endl;
                        return 0;
                    }
                }
            }
        }
        REP(j, n) REP(k, n) if(u2[j] == v2[k]) {
            if(used[j][k] != -1 && used[j][k] != u2[j]) {
                cout << -1 << endl;
                return 0;
            }
            used[j][k] = u2[j], ans[j][k] |= u2[j]<<i;
        }

        REP(j, n) REP(k, n) if(used[j][k] == -1) used[j][k] = 0;
        // 論理和が1の行の制約を満たせるように
        {
            vector<ll> zero_c(n);
            REP(j, n) REP(k, n) zero_c[k] += (used[j][k]==0);
            REP(j, n) if(s[j]==1 && u2[j]==1) {
                bool exist = false;
                REP(k, n) if(used[j][k]==1) exist = true;
                if(exist) continue;
                REP(k, n) if(zero_c[k]>=1) {
                    used[j][k] = 1;
                    ans[j][k] |= 1LL<<i;
                    zero_c[k]--;
                    exist = true;
                    break;
                }
                if(!exist) {
                    cout << -1 << endl;
                    return 0;
                }
            }
        }
        // 列
        {
            vector<ll> zero_r(n);
            REP(j, n) REP(k, n) zero_r[k] += (used[j][k]==0);
            REP(j, n) if(t[j]==1 && v2[j]==1) {
                bool exist = false;
                REP(k, n) if(used[k][j]==1) exist = true;
                if(exist) continue;
                REP(k, n) if(zero_r[k]>=1) {
                    used[k][j] = 1;
                    ans[k][j] |= 1LL<<i;
                    zero_r[k]--;
                    exist = true;
                    break;
                }
                if(!exist) {
                    cout << -1 << endl;
                    return 0;
                }
            }
        }
        dump(used);

        if(!check()) {
            cout << -1 << endl;
            return 0;
        }
    }

    REP(i, n) REP(j, n) cout << ans[i][j] << (j==n-1?'\n':' ');

    return 0;
}