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<iostream>
#include<vector>
#include<bitset>
using namespace std;
typedef unsigned long long li;
#define rep(i,n) for(int i=0;i<(n);i++)
#define df 0
template<class T> void print(const T& t){ cout << t << "\n"; }
template<class T, class... Ts> void print(const T& t, const Ts&... ts) { cout << t; if (sizeof...(ts)) cout << " "; print(ts...); }
// Container コンテナ型, map以外
template< template<class ...> class Ctn,class T>
std::ostream& operator<<(std::ostream& os,const Ctn<T>& v){
  // ここでストリームに obj を書き込みます。
  auto itr=v.begin();
  while(itr!=v.end()){
    if(itr!=v.begin())cout << " ";
    cout << *(itr++);
  }
  return os;
}

void input(vector<vector<int>>& v,int k,li a,int flag){
  rep(i,64){
    if(flag!=a%2){
      v[i][k]=2-flag;
    }
    a/=2;
  }
}

int calc(vector<vector<int>>& sgy,vector<int>& s,vector<int>& t,
         vector<int>& u,vector<int>& v){
  if(df) print(s,t,"u",u,"v",v);
  int f1=0,f2=0,f;
  for(int x:u) f1|=x;
  for(int x:v) f2|=x;
  f=f1*f2*(f1+f2);
  if(df) print(f1,f2,f);
  if(f!=0 and f!=2 and f!=16) return 1;
  int n=s.size();
  vector<int> unu,unv;
  rep(i,n){
    if(!u[i]) unu.push_back(i);
    rep(j,n) sgy[i][j]=u[i]-1;
  }
  rep(j,n){
    if(!v[j]) unv.push_back(j);
    rep(i,n) if(sgy[i][j]==-1) sgy[i][j]=v[j]-1;
  }
  
  if(df){
    rep(i,n) print(sgy[i]);
    print("u:",unu);
    print("v:",unv);
  }
  if(unu.size()==0) return 0;
  if(n==1){
    if(s[0]!=t[0])return 1;
    else sgy[0][0]=s[0];
    return 0;
  }
  if(unu.size()==1){
    int flag=1;
    int a=s[unu[0]];  // aがあればok
    for(int j:unv){
      int b=t[j];    // bがあればok
      rep(i,n){
        if(i==unu[0])continue;
        if(a==sgy[i][j]) flag=0;
        if(b==sgy[i][j]){
          sgy[unu[0]][j]=a;
          if(df)print("[",unu[0],j,"]=",a);
          flag=0;
          break;
        }
      }
      if(sgy[unu[0]][j]==-1) sgy[unu[0]][j]=b;
    }
    return flag;
  }
  
  
  if(unv.size()==1){
    int flag=1;
    int b=t[unv[0]];  // bがあればok
    for(int i:unu){
      int a=s[i];    // aがあればok
      rep(j,n){
        if(j==unv[0])continue;
        if(b==sgy[i][j]) flag=0;
        if(a==sgy[i][j]){
          sgy[i][unv[0]]=b;
          flag=0;
          break;
        }
      }
      if(sgy[i][unv[0]]==-1) sgy[i][unv[0]]=b;
    }
    return flag;
  }
  rep(i,unu.size())
    rep(j,unv.size())
    sgy[unu[i]][unv[j]]=(i+j)%2;
  return 0;
}


int main(){
  int n; cin >>n;
  vector<int> s(n),t(n);
  vector<vector<int>> u(64,vector<int>(n,0)),v(64,vector<int>(n,0));
  li dm=1;
  rep(i,n) cin >> s[i];
  rep(i,n) cin >> t[i];
  rep(i,n){
    li a; cin >>a; if(dm<a) dm=a;
    input(u,i,a,s[i]);
  }
  int ord=3; while(dm){ord++;dm/=2;}
  ord=min(64,ord); ord=64;
  rep(i,n){
    li a; cin >>a;
    input(v,i,a,t[i]);
  } 
  if(df){
    print(s,t);
    rep(i,ord) print(u[i]);
    rep(i,ord) print(v[i]);
  }

  vector<vector<li>> ans(n,vector<li> (n,0));
  vector<vector<int>> sgy(n,vector<int> (n,-1));
  
  li b=1;
  rep(i,ord){
    if(calc(sgy,s,t,u[i],v[i])){
      print(-1);
      return 0;
    }
    if(df) rep(i,n) print(sgy[i]);
    rep(row,n) rep(col,n) ans[row][col]+=sgy[row][col]*b;
    if(df) print("2^",i,"=",b);
    b*=2;
  }
  for(auto x:ans) print(x);
}