/*
如代码所示
设p(x)表示x二进制拆分后1的个数
题目要求维护的i&j==0 且 i|j=k 实际上就是 就是i|j=k 且p(i)+p(j)=p(k)
很容易理解
然后我们考虑将FMT拆成两维来同时维护这两个要求
把a[i]插入f[p(i)][i]中,b[i]插入g[p(i)][i]中
然后对每个f[0~lim],g[0~lim]做fmt
然后暴力区间合并维护p(i)+p(j)=p(k)这个条件即可
时间复杂度O(2^n*n^2)
*/
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dwn(i,a,b) for(int i=a;i>b=;i--)
#define MAXN 1500000
using namespace std;
inline int read(){
int x=0,f=1;
char ch=getchar();
while('0'>ch || ch>'9'){if(ch=='-') f=-1; ch=getchar();}
while('0'<=ch && ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return x*f;
}
typedef long long ll;
const int mod=1e9+9;
int check(int x){
int res=0;
while(x){
if(x&1) res++;
x>>=1;
}
return res;
}
int n,lim,f[22][MAXN],g[22][MAXN],h[22][MAXN];
void FWT_or(int *a,int opt){
for(int i=1;i<n;i<<=1)
for(int j=0,p=(i<<1);j<n;j+=p)
rep(k,0,i-1)
if(opt==1) a[j+i+k]=(a[j+i+k]+a[j+k])%mod;
else a[j+i+k]=(a[j+i+k]+mod-a[j+k])%mod;
}
main(){
// freopen("my.out","w",stdout);
n=read();
lim=n; n=(1<<n);
// rep(i,0,n-1) cout<<check(i)<<" ";cout<<endl;
rep(i,0,n-1) f[check(i)][i]=read();
rep(i,0,n-1) g[check(i)][i]=read();
rep(i,0,lim) FWT_or(f[i],1),FWT_or(g[i],1);
rep(i,0,lim){
rep(j,0,i){
rep(k,0,n-1) h[i][k]=(h[i][k]+(1ll*f[j][k]*g[i-j][k])%mod)%mod;
}
}
rep(i,0,lim) FWT_or(h[i],-1);
rep(i,0,n-1) printf("%d ",h[check(i)][i]);
return 0;
}