#include <bits/stdc++.h>
using namespace std;

using ull = uint64_t;
using ll = int64_t;

template<typename complex_t>
class Fft{
    static constexpr double PI(){return 3.1415926535897932384626;};
    static constexpr int SPLIT_BITS = 15;
    using cvec = std::vector<complex_t>;
    using ivec = std::vector<int64_t>;

    static int lg(int x){
        return __builtin_clz(1) - __builtin_clz(x);
    }
    static int next_2pow(int x){
        return x>1 ? 1<<lg(2*x-1): 1;
    }

    static std::vector<complex_t> roots;
    static void gen_roots(int const&depth){
        if(roots.size() < (1u<<depth)){
            if(roots.empty()){
                roots.emplace_back(std::polar(0.0, 0.0));
                roots.emplace_back(std::polar(1.0, 0.0));
            }
            int cur_d = lg(roots.size())-1;
            roots.resize(1<<(depth+1));
            for(int i = cur_d;i<depth;++i){
                int n = 1 << i;
                complex_t ome = std::polar(1.0, PI()/2.0/n);
                for(int j=n;j<2*n;++j){
                    roots[2*j] = roots[j];
                    roots[2*j+1] = roots[j]*ome;
                }
            }
        }
    }
    static void bitflip(cvec &v){
        int n = v.size();
		for(int i=1, j=0;i<n;++i){
			int m = n >> 1;
			for(;j>=m;m >>= 1)
				j -= m;
			j += m;
			if(i < j) std::swap(v[i], v[j]);
		}
    }
    template<bool is_rev>
    static void fft_regular(cvec& vec){
        bitflip(vec);
        int n = vec.size();
        gen_roots(lg(n));
        for(int iter=1, sh=0;iter<n;iter*=2, ++sh){
			for(int x=0;x<n;x+=2*iter){
				for(int y=0;y<iter;++y){
					complex_t ome = roots[(1 << sh) + y];
					if (is_rev) ome = conj(ome);
					complex_t v = vec[x+y], w=vec[x+y+iter];
					vec[x+y] = v+ome*w;
					vec[x+y+iter] = v-ome*w;
				}
			}
		}
    }
    template<bool is_rev>
    static void fft_inplace(cvec&v){
        fft_regular<is_rev>(v);
    }
public:
    static void three_mul(ivec &vout, ivec const&v1, ivec const& v2, const size_t mod = 0){
        constexpr int BITS = 17, MASK = (1<<BITS) - 1;
        const size_t out_size = v1.size() + v2.size() - 1;
        const size_t n = next_2pow(out_size);

        cvec c1(n, complex_t(0.0, 0.0)), c2(n, complex_t(0.0, 0.0)), c3(n, complex_t(0.0, 0.0));
        for(size_t i=0;i<v1.size();++i){
            int64_t a = v1[i] >> (2*BITS), b = (v1[i] >> BITS) & MASK, c = v1[i] & MASK;
            if(MASK-c < c){
                c-= 1<<BITS;
                ++b;
            }
            if(MASK-b < b){
                b-= 1<<BITS;
                ++a;
            }
            c1[i].real(a);
            c1[i].imag(b);
            c2[i].real(c);
        }
        for(size_t i=0;i<v2.size();++i){
            int64_t a = v2[i] >> (2*BITS), b = (v2[i] >> BITS) & MASK, c = v2[i] & MASK;
            if(MASK-c < c){
                c-= 1<<BITS;
                ++b;
            }
            if(MASK-b < b){
                b-= 1<<BITS;
                ++a;
            }
            c2[i].imag(a);
            c3[i].real(b);
            c3[i].imag(c);
        }
        fft_inplace<false>(c1);
        fft_inplace<false>(c2);
        fft_inplace<false>(c3);

        const double factor = 0.25 / static_cast<double>(c1.size());
        const complex_t IMAG (0.0, 1.0);
        const complex_t NIMAG = conj(IMAG);

        for(int i=0;i<=n/2;++i){
            int j = (n-i)&(n-1); //reverse index
            complex_t rx = (c1[i] + conj(c1[j]));
            complex_t ix = (c1[i] - conj(c1[j])) * NIMAG;
            complex_t ry = (c2[i] + conj(c2[j]));
            complex_t iy = (c2[i] - conj(c2[j])) * NIMAG;
            complex_t rz = (c3[i] + conj(c3[j]));
            complex_t iz = (c3[i] - conj(c3[j])) * NIMAG;
            //cerr << rx << " " << ix << " " << ry << "\n";
            c1[i] = (ry*iz + (ix*iz + ry*rz) * IMAG) * factor;
            c2[i] = (rx*iz + ix*rz + ry*iy) * factor;
            c1[j] = conj(ry*iz + (ix*iz + ry*rz) * NIMAG) * factor;
            c2[j] = conj(rx*iz + ix*rz + ry*iy) * factor;
        }
        fft_inplace<true>(c1);
        fft_inplace<true>(c2);
        vout.resize(out_size);
        //cerr << c1[0] << " " << c2[0] << "\n";
        for(int i=0;i<out_size;++i){
            uint64_t a = llround(c1[i].real()), b = llround(c1[i].imag()), c = llround(c2[i].real());
            vout[i] = (a + (b<<BITS) + (c<<(2*BITS))) % mod;
        }

    }
};
template<typename complex_t>
std::vector<complex_t> Fft<complex_t>::roots;

using fft = Fft<std::complex<double>>;


template<int64_t mod>
struct NT64 {
    static_assert(mod >= 0, "mod should be non-negative.");
    static int64_t add(int64_t const&a, int64_t const&b){
        int64_t ret = a+b;
        if(ret>=mod) ret-=mod;
        return ret;
    }
    static int64_t& xadd(int64_t& a, int64_t const&b){
        a+=b;
        if(a>=mod) a-=mod;
        return a;
    }
    static int64_t sub(int64_t const&a, int64_t const&b){
        return add(a, mod-b);
    }
    static int64_t& xsub(int64_t& a, int64_t const&b){
        return xadd(a, mod-b);
    }
    static int64_t mul(int64_t const&a, int64_t const&b){
        return a*static_cast<int64_t>(b)%mod;
    }
    static int64_t& xmul(int64_t &a, int64_t const&b){
        return a=mul(a, b);
    }
    static int64_t inv_rec(int64_t const&a, int64_t const&m){
        assert(a!=0);
        if(a==1) return 1;
        int64_t ret = m+(1-inv_rec(m%a, a)*static_cast<int64_t>(m))/a;
        return ret;
    }
	// this is soooo great, can even be used for a sieve
    static int64_t inv_rec_2(int64_t const&a, int64_t const&m){
        assert(a!=0);
        if(a==1) return 1;
        int64_t ret = m-mul((m/a), inv_rec_2(m%a, m));
        return ret;
    }
    static int64_t inv(int64_t const&a){
        return inv_rec(a, mod);
    }
    static int64_t div(int64_t const&a, int64_t const&b){
        return mul(a, inv(b));
    }
};


using nt = NT64<1ll<<32>;



const int max_log = 32 + 18;
const ll MODMOD = 1ll << max_log;


int lg(int x){
    return __builtin_clz(1) - __builtin_clz(x);
}


vector<unsigned int> facts, ifacts, v2;

void precalc_facts(int lim){
    facts.resize(lim, 1);
    ifacts.resize(lim, 1);
    v2.resize(lim, 0);
    for(int i=1;i<lim;++i){
        const int j = i >> __builtin_ctz(i);
        v2[i] = v2[i-1] + __builtin_ctz(i);
        facts[i] = facts[i-1] * j;
    }
    ifacts.back() = nt::inv(facts.back());
    for(int i=lim-1;i>0;--i){
        const int j = i >> __builtin_ctz(i);
        ifacts[i-1] = ifacts[i] * j;
    }
}


void twofy(vector<ll> &v){
    for(size_t i=0;i<v.size();++i){
        v[i] *= 1ll<<(i-v2[i]);
        v[i] *= ifacts[i];
        v[i] %= MODMOD;
    }
}


void vec_mul(vector<ll> &c, vector<ll> const&a, vector<ll> const&b){
    const int bits = 25;
    fft::three_mul(c, a, b, MODMOD);
}

signed main()
{
    cin.tie(0); cout.tie(0); ios_base::sync_with_stdio(false);
    precalc_facts(2e5+10);
    int n;
    cin >> n;
    ++n;
    const int m = lg(n)+1;
    vector<ll> a(n), b(n), c;
    for(int i=0;i<n;++i)
        cin >> a[i];
    for(int i=0;i<n;++i)
        cin >> b[i];
    twofy(a);
    twofy(b);
    vec_mul(c, a, b);
    for(int i=0;i<n;++i){
        ll val = c[i];
        val >>= (i-v2[i]);
        uint32_t out = val;
        out*= facts[i];
        cout << out << " ";
    }
    cout << "\n";
    return 0;
}
