#include using namespace std; using ll = long long; using ld = long double; using ull = unsigned long long; #define rep(i,n) for(ll i=0;i T div_floor(T a, T b) { return a / b - ((a ^ b) < 0 && a % b); } template T div_ceil(T a, T b) { return a / b + ((a ^ b) > 0 && a % b); } template inline bool chmin(T &x, U y) { return (y < x) ? (x = y, true) : false; } template inline bool chmax(T &x, U y) { return (x < y) ? (x = y, true) : false; } template ostream &operator<<(ostream &os,const pair &p){ return os< ostream &operator<<(ostream &os, const vector &a){ if (a.empty()) return os; os << a.front(); for (auto e : a | views::drop(1)){ os << ' ' << e; } return os; } void dump(auto ...vs){ ((cout << vs << ' '), ...) << endl; } pair>> solve_one(vector X,vector Y,vector Z){ ll N=X.size(); vector A(N,vector(N,0)); if (N<=3){ rep(bi,1<<(N-1)*(N-1)){ rep(i,N){ rep(j,N){ A[i][j]=0; } } for (ll i=1;i>((i-1)*(N-1)+j)&1; ll t=i+j; if (t oky(N,false); rep(j,N){ if (Y[j]==0){ rep(i,N){ A[i][j]=0; } oky[j]=true; } } rep(k,2*N-1){ ll siwa=-1; ll r=0; rep(j,N){ ll i=k-j; if (i>=N)continue; if (i<0)continue; if (A[i][j]!=-1){ r^=A[i][j]; continue; } } rep(j,N){ ll i=k-j; if (i>=N)continue; if (i<0)continue; if (A[i][j]==-1){ siwa=j; if (oky[j]){ break; } continue; } } if (siwa==-1)continue; rep(j,N){ ll i=k-j; if (i>=N)continue; if (i<0)continue; if (j==siwa)continue; if (A[i][j]==-1){ A[i][j]=1; oky[j]=true; r^=1; continue; } } { ll j=siwa; ll i=k-j; A[i][j]=Z[k]^r; if (A[i][j]==1){ oky[j]=true; } } } } if (fx and (not fy)){ rep(i,N)rep(j,N)A[i][j]=-1; vector okx(N,false); rep(i,N){ if (X[i]==1){ rep(j,N){ A[i][j]=1; } okx[i]=true; } } rep(k,2*N-1){ // rep(i,N){ // dump(A[i]); // } ll siwa=-1; ll r=0; rep(i,N){ ll j=k-i; if (j>=N)continue; if (j<0)continue; if (A[i][j]!=-1){ r^=A[i][j]; continue; } } rep(i,N){ ll j=k-i; if (j>=N)continue; if (j<0)continue; if (A[i][j]==-1){ siwa=i; if (okx[i]){ break; } continue; } } if (siwa==-1)continue; rep(i,N){ ll j=k-i; if (j>=N)continue; if (j<0)continue; if (i==siwa)continue; if (A[i][j]==-1){ A[i][j]=0; okx[i]=true; r^=0; continue; } } { ll i=siwa; ll j=k-i; A[i][j]=Z[k]^r; if (A[i][j]==0){ okx[i]=true; } } } } vector rx(N,1),ry(N,0),rz(2*N-1,0); rep(i,N){ rep(j,N){ assert(A[i][j]==0 or A[i][j]==1); rx[i]&=A[i][j]; ry[j]|=A[i][j]; rz[i+j]^=A[i][j]; } } bool flag=true; if (rx!=X)flag=false; if (ry!=Y)flag=false; if (ry!=Y)flag=false; if (flag){ return {true,A}; } else{ return {false,{}}; } } void solve() { ll N; cin>>N; vector X(N),Y(N),Z(2*N-1); rep(i,N)cin>>X[i]; rep(i,N)cin>>Y[i]; rep(i,2*N-1)cin>>Z[i]; vector A(N,vector (N,0)); bool flag=true; rep(d,31){ vector dx(N),dy(N),dz(2*N-1); rep(i,N){ dx[i]=X[i]>>d&1; } rep(j,N){ dy[j]=Y[j]>>d&1; } rep(k,2*N-1){ dz[k]=Z[k]>>d&1; } auto res=solve_one(dx,dy,dz); if (!res.first){ flag=false; continue; } rep(i,N){ rep(j,N){ A[i][j]|=res.second[i][j]< rx(N,-1); vector ry(N,0); rep(i,N){ rep(j,N){ Z[i+j]^=A[i][j]; rx[i]&=A[i][j]; ry[j]|=A[i][j]; } } // assert(X==rx); // assert(Y==ry); // if (*max_element(all(Z))!=0){ // dump("NG"); // assert(false); // } return; } int main() { cin.tie(0)->sync_with_stdio(0); ll T=1; cin>>T; while (T--){ solve(); } return 0; }