Problem:
Score : 1900 points

Problem Statement

#nck {
width: 30px;
height: auto;
}

One day, Takahashi was given the following problem from Aoki:

You are given a tree with N vertices and an integer K. The vertices are numbered 1 through N. The edges are represented by pairs of integers (a_i, b_i).

For a set S of vertices in the tree, let f(S) be the minimum number of the vertices in a subtree of the given tree that contains all vertices in S.

There are ways to choose K vertices from the trees. For each of them, let S be the set of the chosen vertices, and find the sum of f(S) over all ways.

Since the answer may be extremely large, print it modulo 924844033(prime).

Since it was too easy for him, he decided to solve this problem for all K = 1,2,...,N.

Constraints

2 ≦ N ≦ 200,000

1 ≦ a_i, b_i ≦ N

The given graph is a tree.

Input

The input is given from Standard Input in the following format:

N
a_1 b_1
a_2 b_2
:
a_{N-1} b_{N-1}

Output

Print N lines. The i-th line should contain the answer to the problem where K=i, modulo 924844033.

Sample Input 1

3
1 2
2 3

Sample Output 1

3
7
3

The diagram above illustrates the case where K=2. The chosen vertices are colored pink, and the subtrees with the minimum number of vertices are enclosed by red lines.

Sample Input 2

4
1 2
1 3
1 4

Sample Output 2

4
15
13
4

Sample Input 3

7
1 2
2 3
2 4
4 5
4 6
6 7

Sample Output 3

7
67
150
179
122
45
7

Solution in C++14 (GCC 5.4.1) (judge verdict: Time Limit Exceeded)

const bool submit=1;
#include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define rep1(i,n) for(int i=1;i<=(int)(n);i++)
#define all(c) c.begin(),c.end()
#define pb push_back
#define fs first
#define sc second
#define show(x) if(!submit) cout << #x << " = " << x << endl
#define chmin(x,y) x=min(x,y)
#define chmax(x,y) x=max(x,y)
using namespace std;
template<class S,class T> ostream& operator<<(ostream& o,const pair<S,T> &p){return o<<"("<<p.fs<<","<<p.sc<<")";}
template<class T> ostream& operator<<(ostream& o,const vector<T> &vc){o<<"sz = "<<vc.size()<<endl<<"[";for(const T& v:vc) o<<v<<",";o<<"]";return o;}

template<unsigned int mod_>
struct ModInt{
	using uint = unsigned int;
	using ll = long long;
	using ull = unsigned long long;

	constexpr static uint mod = mod_;

	uint v;
	ModInt():v(0){}
	ModInt(ll v):v(normS(v%mod+mod)){}
	explicit operator bool() const {return v!=0;}
	static uint normS(const uint &x){return (x<mod)?x:x-mod;}		// [0 , 2*mod-1] -> [0 , mod-1]
	static ModInt make(const uint &x){ModInt m; m.v=x; return m;}
	ModInt operator+(const ModInt& b) const { return make(normS(v+b.v));}
	ModInt operator-(const ModInt& b) const { return make(normS(v+mod-b.v));}
	ModInt operator-() const { return make(normS(mod-v)); }
	ModInt operator*(const ModInt& b) const { return make((ull)v*b.v%mod);}
	ModInt operator/(const ModInt& b) const { return *this*b.inv();}
	ModInt& operator+=(const ModInt& b){ return *this=*this+b;}
	ModInt& operator-=(const ModInt& b){ return *this=*this-b;}
	ModInt& operator*=(const ModInt& b){ return *this=*this*b;}
	ModInt& operator/=(const ModInt& b){ return *this=*this/b;}
	ll extgcd(ll a,ll b,ll &x,ll &y) const{
		ll u[]={a,1,0},v[]={b,0,1};
		while(*v){
			ll t=*u/ *v;
			rep(i,3) swap(u[i]-=t*v[i],v[i]);
		}
		if(u[0]<0) rep(i,3) u[i]=-u[i];
		x=u[1],y=u[2];
		return u[0];
	}
	ModInt inv() const{
		ll x,y;
		extgcd(v,mod,x,y);
		return make(normS(x+mod));
	}
	bool operator==(const ModInt& b) const { return v==b.v;}
	bool operator!=(const ModInt& b) const { return v!=b.v;}
	friend istream& operator>>(istream &o,ModInt& x){
		ll tmp;
		o>>tmp;
		x=ModInt(tmp);
		return o;
	}
	friend ostream& operator<<(ostream &o,const ModInt& x){ return o<<x.v;}
};
using mint = ModInt<924844033>;

typedef long long ll;
typedef pair<ll,ll> P;		//val,mod;
ll inv(ll a,ll m){
	ll b=m,u=1,v=0;
	while(b){
		ll t=a/b;
		swap(a-=t*b,b);
		swap(u-=t*v,v);
	}
	u%=m;
	if(u<0) u+=m;
	return u;
}

struct NTT{
	const int mod,g;
	NTT(int mod,int g) :mod(mod),g(g){}
	ll ex(ll x,ll p){
		ll a=1;
		while(p){
			if(p%2) a=a*x%mod;
			x=x*x%mod;
			p/=2;
		}
		return a;
	}
	ll inv(ll a){
		ll b=mod,u=1,v=0;
		while(b){
			ll t=a/b;
			swap(a-=t*b,b);
			swap(u-=t*v,v);
		}
		u%=mod;
		if(u<0) u+=mod;
		return u;
	}
	void ntt(vector<ll>& a,ll h){
		int N=a.size();
		for(int m=N;m>=2;m/=2){
			int mh=m/2;
			ll w=1;
			rep(i,mh){
				for(int j=i;j<N;j+=m){
					int k=j+mh;
					ll x=(a[j]-a[k]);
					a[j]+=a[k];
					if(a[j]>=mod) a[j]-=mod;
					a[k]=w*x%mod;
					if(a[k]<0) a[k]+=mod;
				}
				w=w*h%mod;
			}
			h=h*h%mod;
		}
		int i=0;
		rep1(j,N-2){
			for(int k=N/2;k>(i^=k);k/=2);
			if(j<i) swap(a[i],a[j]);
		}
	}
	vector<ll> conv(vector<ll> a,vector<ll> b){		// (mod-1)%N==0でないとだめ!!
		for(auto& x:a) x%=mod;
		for(auto& x:b) x%=mod;
		int n=a.size()+b.size();
		int N=1;
		while(N<n) N*=2;
		a.resize(N),b.resize(N);
		assert((mod-1)%N==0);
		ll h=ex(g,(mod-1)/N);
		ntt(a,h),ntt(b,h);
		rep(i,N) (a[i]*=b[i])%=mod;
		h=inv(h);
		ntt(a,h);
		h=inv(N);
		rep(i,N) (a[i]*=h)%=mod;
		return a;
	}
};

vector<mint> multiply_ntt(const vector<mint> &a_,const vector<mint> &b_){
	int mod = mint::mod;
	vector<ll> a(a_.size()),b(b_.size());
	rep(i,a.size()) a[i]=a_[i].v;
	rep(i,b.size()) b[i]=b_[i].v;
	vector<ll> vs;
	vs=NTT(mod,5).conv(a,b);
	int N=vs.size();
	vector<mint> ret(N);
	rep(i,N){
		ret[i]=vs[i];
	}
	return ret;
}

template<class D>
struct Poly{
	vector<D> v;
	int size() const{ return v.size();}	//deg+1
	Poly(int N=0) : v(vector<D>(N)){}
	Poly(vector<D> v) : v(v){shrink();}

	Poly& shrink(){
		while(!v.empty()&&v.back()==D(0)) v.pop_back();	//double? iszeroをglobalに用意したほうがいいかな
		return *this;
	}
	D at(int i) const{
		return (i<size())?v[i]:D(0);
	}
	void set(int i,const D& x){		//v[i] := x
		while(i>=size()) v.push_back(D(0));
		v[i]=x;
		shrink();
		return;
	}

	Poly operator+(const Poly &r) const{
		int N=max(size(),r.size());
		vector<D> ret(N);
		rep(i,N) ret[i]=at(i)+r.at(i);
		return Poly(ret);
	}
	Poly operator-(const Poly &r) const{
		int N=max(size(),r.size());
		vector<D> ret(N);
		rep(i,N) ret[i]=at(i)-r.at(i);
		return Poly(ret);
	}
	Poly operator-() const{
		int N=size();
		vector<D> ret(N);
		rep(i,N) ret[i] = -at(i);
		return Poly(ret);
	}
	Poly operator*(const Poly &r) const{
		if(size()==0||r.size()==0) return Poly();
		return mul_ntt(r);
	}
	Poly operator*(const D &r) const{
		int N=size();
		vector<D> ret(N);
		rep(i,N) ret[i]=v[i]*r;
		return Poly(ret);
	}
	Poly operator/(const Poly &y) const{
		return div_fast(y);
	}
	Poly operator%(const Poly &y) const{
		return rem_fast(y);
//		return rem_naive(y);
	}
	Poly operator<<(const int &n) const{	// *=x^n
		assert(n>=0);
		int N=size();
		vector<D> ret(N+n);
		rep(i,N) ret[i+n]=v[i];
		return Poly(ret);
	}
	Poly operator>>(const int &n) const{	// /=x^n
		assert(n>=0);
		int N=size();
		if(N<=n) return Poly();
		vector<D> ret(N-n);
		rep(i,N-n) ret[i]=v[i+n];
		return Poly(ret);
	}
	bool operator==(const Poly &y) const{
		return v==y.v;
	}
	bool operator!=(const Poly &y) const{
		return v!=y.v;
	}

	Poly& operator+=(const Poly &r) {return *this = *this+r;}
	Poly& operator-=(const Poly &r) {return *this = *this-r;}
	Poly& operator*=(const Poly &r) {return *this = *this*r;}
	Poly& operator*=(const D &r) {return *this = *this*r;}
	Poly& operator%=(const Poly &y) {return *this = *this%y;}
	Poly& operator<<=(const int &n) {return *this = *this<<n;}
	Poly& operator>>=(const int &n) {return *this = *this>>n;}


	Poly mul_naive(const Poly &r) const{
		int N=size(),M=r.size();
		vector<D> ret(N+M-1);
		rep(i,N) rep(j,M) ret[i+j]+=at(i)*r.at(j);
		return Poly(ret);
	}
	Poly mul_kar(const Poly &r) const{
		return Poly(multiply_karatsuba(this->v,r.v));
	}
	Poly mul_ntt(const Poly &r) const{
		return Poly(multiply_ntt(this->v,r.v));
	}
	Poly mul_fft(const Poly &r) const{
		vector<D> ret = multiply_fft(v,r.v);
		return Poly(ret);
	}

	Poly div_fast_with_inv(const Poly &inv, int B) const {
		return (*this * inv)>>(B-1);
	}
	Poly div_fast(const Poly &y) const{
		if(size()<y.size()) return Poly();
		int n = size();
		return div_fast_with_inv(y.inv(n),n);
	}
	Poly rem_naive(const Poly &y) const{
		Poly x = *this;
		while(y.size()<=x.size()){
			int N=x.size(),M=y.size();
			D coef = x.v[N-1]/y.v[M-1];
			x -= (y<<(N-M))*coef;
		}
		return x;
	}
	Poly rem_fast(const Poly &y) const{
		return *this - y * div_fast(y);
	}
	Poly strip(int n) const {	//ignore x^n , x^n+1,...
		vector<D> res = v;
		res.resize(min(n,size()));
		return Poly(res);
	}
	Poly rev(int n = -1) const {	//ignore x^n ~  ->  return x^(n-1) * f(1/x)
		vector<D> res = v;
		if(n!=-1) res.resize(n);
		reverse(all(res));
		return Poly(res);
	}
	Poly inv(int n) const{		// f * f.inv() = x^B + r(x) (B>=n)
		int N = size();
		assert(N>=1);		//f : non0
		assert(n>=N-1);		//f = .. + c_{N-1}x^{N-1}
		D coef = D(1)/at(N-1);
		Poly a = rev();
		Poly g(vector<D>(1,coef));
		for(int i=1; i+N-2<n; i*=2){		//need to strip!!
			g *= (Poly(vector<D>{2})-a*g).strip(2*i);
		}
		return g.rev(n+1-N);
	}

	friend ostream& operator<<(ostream &o,const Poly& x){
		if(x.size()==0) return o<<0;
		rep(i,x.size()) if(x.v[i]!=D(0)){
			o<<x.v[i]<<"x^"<<i;
			if(i!=x.size()-1) o<<" + ";
		}
		return o;
	}
};



int N;
const int MN=200000;
vector<int> G[MN];
int sz[MN];
int par[MN];
void dfs(int v,int p=-1){
	par[v]=p;
	sz[v]=1;
	for(int u:G[v]) if(u!=p){
		dfs(u,v);
		sz[v]+=sz[u];
	}
}
int cnt[MN+1];
mint fac[MN+1];
int main(){
	cin>>N;
	fac[0]=1;
	rep1(i,N) fac[i]=fac[i-1]*i;
	rep(i,N-1){
		int a,b;
		cin>>a>>b;
		a--,b--;
		G[a].pb(b);
		G[b].pb(a);
	}
	dfs(0);
	rep(v,N){
		for(int u:G[v]) if(u!=par[v]) cnt[sz[u]]++;
		if(v!=0) cnt[N-sz[v]]++;
	}
	rep(i,N+1) show(cnt[i]);
	Poly<mint> f(N+1),g(N+1);
	rep(i,N+1) f.set(i,fac[i]*cnt[i]);
	rep(i,N+1) g.set(i,mint(1)/fac[N-i]);
	show(f);
	show(g);
	Poly<mint> ans = f*g;
	show(ans);
	rep1(k,N){
		show(N+k);
		show(ans.at(N+k));
		mint a = fac[N]/fac[k]/fac[N-k]*mint(N);
		show(a);
		a -= ans.at(N+k)/fac[k];
		cout<<a<<endl;
	}
}