Problem:
Score : 600 points

Problem Statement

We have a tree with N vertices numbered 1 to N. The i-th edge in this tree connects Vertex a_i and b_i.
For each k=1, ..., N, solve the problem below:

Consider writing a number on each vertex in the tree in the following manner:

First, write 1 on Vertex k.

Then, for each of the numbers 2, ..., N in this order, write the number on the vertex chosen as follows:

Choose a vertex that still does not have a number written on it and is adjacent to a vertex with a number already written on it. If there are multiple such vertices, choose one of them at random.

Find the number of ways in which we can write the numbers on the vertices, modulo (10^9+7).

Constraints

2 \leq N \leq 2 \times 10^5

1 \leq a_i,b_i \leq N

The given graph is a tree.

Input

Input is given from Standard Input in the following format:

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

Output

For each k=1, 2, ..., N in this order, print a line containing the answer to the problem.

Sample Input 1

3
1 2
1 3

Sample Output 1

2
1
1

The graph in this input is as follows:

For k=1, there are two ways in which we can write the numbers on the vertices, as follows:

Writing 1, 2, 3 on Vertex 1, 2, 3, respectively

Writing 1, 3, 2 on Vertex 1, 2, 3, respectively

Sample Input 2

2
1 2

Sample Output 2

1
1

The graph in this input is as follows:

Sample Input 3

5
1 2
2 3
3 4
3 5

Sample Output 3

2
8
12
3
3

The graph in this input is as follows:

Sample Input 4

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

Sample Output 4

40
280
840
120
120
504
72
72

The graph in this input is as follows:

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

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

#define ALL(obj) (obj).begin(),(obj).end()
#define SPEED cin.tie(0);ios::sync_with_stdio(false);

template<class T> using PQ = priority_queue<T>;
template<class T> using PQR = priority_queue<T,vector<T>,greater<T>>;

constexpr long long MOD = (long long)1e9 + 7;
constexpr long long MOD2 = 998244353;
constexpr long long HIGHINF = (long long)1e18;
constexpr long long LOWINF = (long long)1e15;
constexpr long double PI = 3.1415926535897932384626433L;

template <class T> vector<T> multivector(size_t N,T init){return vector<T>(N,init);}
template <class... T> auto multivector(size_t N,T... t){return vector<decltype(multivector(t...))>(N,multivector(t...));}
template <class T> void corner(bool flg, T hoge) {if (flg) {cout << hoge << endl; exit(0);}}
template <class T, class U>ostream &operator<<(ostream &o, const map<T, U>&obj) {o << "{"; for (auto &x : obj) o << " {" << x.first << " : " << x.second << "}" << ","; o << " }"; return o;}
template <class T>ostream &operator<<(ostream &o, const set<T>&obj) {o << "{"; for (auto itr = obj.begin(); itr != obj.end(); ++itr) o << (itr != obj.begin() ? ", " : "") << *itr; o << "}"; return o;}
template <class T>ostream &operator<<(ostream &o, const multiset<T>&obj) {o << "{"; for (auto itr = obj.begin(); itr != obj.end(); ++itr) o << (itr != obj.begin() ? ", " : "") << *itr; o << "}"; return o;}
template <class T>ostream &operator<<(ostream &o, const vector<T>&obj) {o << "{"; for (int i = 0; i < (int)obj.size(); ++i)o << (i > 0 ? ", " : "") << obj[i]; o << "}"; return o;}
template <class T, class U>ostream &operator<<(ostream &o, const pair<T, U>&obj) {o << "{" << obj.first << ", " << obj.second << "}"; return o;}
template <template <class tmp>  class T, class U> ostream &operator<<(ostream &o, const T<U> &obj) {o << "{"; for (auto itr = obj.begin(); itr != obj.end(); ++itr)o << (itr != obj.begin() ? ", " : "") << *itr; o << "}"; return o;}
void print(void) {cout << endl;}
template <class Head> void print(Head&& head) {cout << head;print();}
template <class Head, class... Tail> void print(Head&& head, Tail&&... tail) {cout << head << " ";print(forward<Tail>(tail)...);}
template <class T> void chmax(T& a, const T b){a=max(a,b);}
template <class T> void chmin(T& a, const T b){a=min(a,b);}
void YN(bool flg) {cout << (flg ? "YES" : "NO") << endl;}
void Yn(bool flg) {cout << (flg ? "Yes" : "No") << endl;}
void yn(bool flg) {cout << (flg ? "yes" : "no") << endl;}


template<class T = int> class Tree {
public:
	int nodeNum;
	int isWeighted;
	int maxBit;
	int idx;
	vector<vector<int>> edge;
	vector<vector<T>> weight;
	vector<int> depth;
	vector<int> order;
	vector<T> dist;
	vector<int> size;
	
	vector<int> parent;
	vector<T> parentDist;
	
	vector<vector<int>> child;
	vector<vector<T>> childDist;
 
	vector<vector<int>> ancestor;
	vector<vector<int>> descendant;
	
	vector<int> eulerTour;
    vector<T> eulerTourDist;
	vector<int> eulerTourIdxL;
	vector<int> eulerTourIdxR;
    vector<int> eulerTourDive,eulerTourFloat;
    vector<T> eulerTourDiveDist,eulerTourFloatDist;
	vector<int> eulerTourDiveIdxL,eulerTourFloatIdxL;
	vector<int> eulerTourDiveIdxR,eulerTourFloatIdxR;
 
	Tree(const int nodeNum, const int isWeighted = 0, const int maxBit = 20) : 
	nodeNum(nodeNum),
	isWeighted(isWeighted),
	maxBit(maxBit),
	edge(nodeNum),
	depth(nodeNum),
	order(nodeNum)
	{
		if(isWeighted) weight.resize(nodeNum);
		if(isWeighted) dist.resize(nodeNum);
	}
 
	//O(1) anytime
	void makeEdge(const int& from, const int& to, const T& w = 0) {
		edge[from].push_back(to);
		if(isWeighted)	weight[from].push_back(w);
	}
 
	//O(N) anytime
	void makeDepth(const int root) {
		depth[root] = 0;
		if(isWeighted) dist[root] = 0;
		idx = 0;
		dfs1(root);
		order[idx++] = root;
	}
 
    //for makeDepth
	void dfs1(int from, int prev = -1){
		for(int i = 0; i < edge[from].size(); ++i){
			int to = edge[from][i];
			if(to==prev) continue;
			depth[to] = depth[from] + 1;
			if(isWeighted) dist[to] = dist[from] + weight[from][i];
			dfs1(to,from);
			order[idx++] = to;
		}
	}
 
    //O(N) anytime
	int diameter(void){
		makeDepth(0);
		int tmp = max_element(depth.begin(), depth.end()) - depth.begin();
		makeDepth(tmp);
		return *max_element(depth.begin(), depth.end());
	}
 
	//O(N) after makeDepth
	void makeParent(void) {
		parent.resize(nodeNum);
		iota(parent.begin(),parent.end(),0);
		for (int i = 0; i < nodeNum; ++i) for (auto j : edge[i]) if (depth[i] > depth[j]) parent[i] = j;
 
		if(isWeighted) {
			parentDist.resize(nodeNum);
			for (int i = 0; i < nodeNum; ++i) for (int j = 0; j < edge[i].size(); ++j) if (depth[i] > depth[edge[i][j]]) parentDist[i] = weight[i][j];
		}
	}
 
	//O(N) after makeDepth
	void makeChild(void) {
		child.resize(nodeNum);
		for (int i = 0; i < nodeNum; ++i) for (auto j : edge[i]) if (depth[i] < depth[j]) child[i].push_back(j);
 
		if(isWeighted) {
			childDist.resize(nodeNum);
			for (int i = 0; i < nodeNum; ++i) for (int j = 0; j < edge[i].size(); ++j) if (depth[i] < depth[edge[i][j]]) childDist[i].push_back(weight[i][j]);
		}
	}

	//O(N) after makeChild
	void makeSize(void) {
		size.resize(nodeNum,1);
		for (int i:order) for (auto j : child[i]) size[i] += size[j];
	}
 
	//O(NlogN) after makeDepth
	void makeAncestor(void) {
		ancestor.resize(nodeNum,vector<int>(maxBit));
		for (int i = 0; i < nodeNum; ++i) ancestor[i][0] = i;
		for (int i = 0; i < nodeNum; ++i) for (auto j : edge[i]) if (depth[i] > depth[j]) ancestor[i][0] = j;
		for (int bit = 1; bit < maxBit; ++bit) for (int i = 0; i < nodeNum; ++i) ancestor[i][bit] = ancestor[ancestor[i][bit - 1]][bit - 1];
	}
 
	//O(N^2) after makeDepth
	void makeDescendant(void) {
		descendant.resize(nodeNum);
		for (int i = 0; i < nodeNum; ++i) descendant[i].push_back(i);
		for (int i = 0; i < nodeNum; ++i) for (auto j : edge[order[i]]) if (depth[order[i]] < depth[j]) for(auto k: descendant[j]) descendant[order[i]].push_back(k);
	}
 
	//O(logN) after makeAncestor
	int lca(int l, int r) {
		if (depth[l] < depth[r]) swap(l, r);
		int diff = depth[l] - depth[r];
		for (int bit = 0; bit < maxBit; ++bit) if (diff & (1 << bit)) l = ancestor[l][bit];
		if(l==r) return l;
		for (int bit = maxBit - 1; 0 <= bit; --bit) if(ancestor[l][bit]!=ancestor[r][bit]) l = ancestor[l][bit], r = ancestor[r][bit];
		return ancestor[l][0];
	}
 
	//O(N) after makeChild and makeParent
	void makeEulerTour(void){
        dfs2(order[nodeNum-1]);
		eulerTourIdxL.resize(nodeNum);
		eulerTourIdxR.resize(nodeNum);
		for(int i = 0; i < eulerTour.size(); ++i) eulerTourIdxR[eulerTour[i]] = i;
		for(int i = eulerTour.size()-1; 0 <= i; --i) eulerTourIdxL[eulerTour[i]] = i;
		return;
	}
 
    //for makeEulerTour
	void dfs2(int from, int prev = -1){
		eulerTour.push_back(from);
        if(isWeighted) eulerTourDist.push_back(parentDist[from]);
 
        for(int i = 0; i < child[from].size(); ++i){
            int to = child[from][i];            
            dfs2(to,from);            
    		eulerTour.push_back(from);
            if(isWeighted) eulerTourDist.push_back(-childDist[from][i]);
        }
	}

	//O(NlogN) after makeEulerTour
	void makeEulerTourEdge(void) {
		eulerTourDive.push_back(order[nodeNum-1]);
		if(isWeighted) eulerTourDiveDist.push_back(0);
		for(int i = 1; i < eulerTour.size(); ++i) {
			int l = eulerTour[i-1];
			int r = eulerTour[i];
			if(depth[l] < depth[r]) {
				eulerTourDive.push_back(i);
				if(isWeighted) eulerTourDiveDist.push_back(eulerTourDist[i]);
			}
			else {
				eulerTourFloat.push_back(i);
				if(isWeighted) eulerTourFloatDist.push_back(eulerTourDist[i]);
			}
		}
		eulerTourDiveIdxL.resize(nodeNum);
		eulerTourDiveIdxR.resize(nodeNum);
		eulerTourFloatIdxL.resize(nodeNum);
		eulerTourFloatIdxR.resize(nodeNum);
		for(int i = 0; i < nodeNum; ++i) {
			int l = eulerTourIdxL[i];
			int r = eulerTourIdxR[i];
			eulerTourDiveIdxL[i]  =  upper_bound(eulerTourDive.begin() ,eulerTourDive.end() ,l) - eulerTourDive.begin()     ;
			eulerTourDiveIdxR[i]  = (upper_bound(eulerTourDive.begin() ,eulerTourDive.end() ,r) - eulerTourDive.begin())  -1;
			eulerTourFloatIdxL[i] =  upper_bound(eulerTourFloat.begin(),eulerTourFloat.end(),l) - eulerTourFloat.begin()    ;
			eulerTourFloatIdxR[i] = (upper_bound(eulerTourFloat.begin(),eulerTourFloat.end(),r) - eulerTourFloat.begin()) -1;
			eulerTourDiveIdxR[i]  = max(eulerTourDiveIdxL[i]-1 ,eulerTourDiveIdxR[i]);
			eulerTourFloatIdxR[i] = max(eulerTourFloatIdxL[i]-1,eulerTourFloatIdxR[i]);
		}
	}
		// iの部分木の頂点に加算するとき
		// [ eulerTourIdxL[i]  ,eulerTourIdxR[i]  ]に　+val
		// [i]の頂点クエリ
		// [eulerTourIdxL[i],eulerTourIdxL[i]]

		// iの部分木の辺に加算するとき
		// [ eulerTourDiveIdxL[i]  ,eulerTourDiveIdxR[i]  ]に　+val
		// [ eulerTourFloatIdxL[i] ,eulerTourFloatIdxR[i] ]に　-val
		// [0,i]のパスクエリ
		// [ 0, eulerTourDiveIdxL[i] ) + [0, eulerTourFloatIdxL[i])
 
};
 
//depth,dist
//https://atcoder.jp/contests/abc126/tasks/abc126_d
 
//lca
//https://atcoder.jp/contests/abc014/tasks/abc014_4
 
//child
//https://atcoder.jp/contests/abc133/tasks/abc133_e

//diameter
//https://atcoder.jp/contests/agc033/tasks/agc033_c

//eulerTour
//https://yukicoder.me/problems/no/900


template<long long mod> class ModInt {
public:
	long long x;
	ModInt():x(0) {
		// do nothing
	}
	ModInt(long long y) : x(y>=0?(y%mod): (mod - (-y)%mod)%mod) {
		// do nothing
	}
	ModInt &operator+=(const ModInt &p) {
		if((x += p.x) >= mod) x -= mod;
		return *this;
	}
	ModInt &operator+=(const long long y) {
        ModInt p(y);
		if((x += p.x) >= mod) x -= mod;
		return *this;
	}
	ModInt &operator+=(const int y) {
        ModInt p(y);
		if((x += p.x) >= mod) x -= mod;
		return *this;
	}
	ModInt &operator-=(const ModInt &p) {
		if((x += mod - p.x) >= mod) x -= mod;
		return *this;
	}
	ModInt &operator-=(const long long y) {
        ModInt p(y);
		if((x += mod - p.x) >= mod) x -= mod;
		return *this;
	}
	ModInt &operator-=(const int y) {
        ModInt p(y);
		if((x += mod - p.x) >= mod) x -= mod;
		return *this;
	}
	ModInt &operator*=(const ModInt &p) {
		x = (x * p.x % mod);
		return *this;
	}
	ModInt &operator*=(const long long y) {
        ModInt p(y);
		x = (x * p.x % mod);
		return *this;
	}
	ModInt &operator*=(const int y) {
        ModInt p(y);
		x = (x * p.x % mod);
		return *this;
	}
	ModInt &operator/=(const ModInt &p) {
		*this *= p.inv();
		return *this;
	}
	ModInt &operator/=(const long long y) {
        ModInt p(y);
		*this *= p.inv();
		return *this;
	}
	ModInt &operator/=(const int y) {
        ModInt p(y);
		*this *= p.inv();
		return *this;
	}
	ModInt operator=(const int y) {
        ModInt p(y);
        *this = p;
        return *this;
    }
    ModInt operator=(const long long y) {
        ModInt p(y);
		*this = p;
        return *this;
    }
	ModInt operator-() const { return ModInt(-x); }
	ModInt operator++() { 
        x++;
        if(x>=mod) x-=mod;
        return *this; 
    }
	ModInt operator--() { 
        x--;
        if(x<0) x+=mod;
        return *this; 
    }
	ModInt operator+(const ModInt &p) const { return ModInt(*this) += p; }
	ModInt operator-(const ModInt &p) const { return ModInt(*this) -= p; }
	ModInt operator*(const ModInt &p) const { return ModInt(*this) *= p; }
	ModInt operator/(const ModInt &p) const { return ModInt(*this) /= p; }
	bool operator==(const ModInt &p) const { return x == p.x; }
	bool operator!=(const ModInt &p) const { return x != p.x; }
	ModInt inv() const {
		int a = x, b = mod, u = 1, v = 0, t;
		while(b > 0) {
			t = a / b;
			swap(a -= t * b, b);
			swap(u -= t * v, v);
		}
		return ModInt(u);
	}
	ModInt pow(long long n) const {
		ModInt ret(1), mul(x);
		while(n > 0) {
			if(n & 1) ret *= mul;
			mul *= mul;
			n >>= 1;
		}
		return ret;
	}
	friend ostream &operator<<(ostream &os, const ModInt &p) {
		return os << p.x;
	}
	friend istream &operator>>(istream &is, ModInt &a) {
		long long t;
		is >> t;
		a = ModInt<mod>(t);
		return (is);
	}
};
using modint = ModInt<MOD>;

//Factorial Mod
vector<long long> FactorialMod(long long N, long long mod) {
    vector<long long> res(N + 1, 1);
    for (long long i = 1; i <= N; ++i) res[i] = (res[i - 1] * i) % mod;
    return res;
}

int main() {
    SPEED
    int N; cin >> N;
    Tree<> tree(N);
    for(int i = 0; i < N-1; ++i){
        int u,v; cin >> u >> v;
        u--,v--;
        tree.makeEdge(u,v);
        tree.makeEdge(v,u);
    }
    tree.makeDepth(0);
    tree.makeChild();
    tree.makeParent();
	tree.makeSize();
    auto F = FactorialMod(N,MOD);

    vector<modint> dp(N,1);
    for(int pa:tree.order){
        dp[pa] *= F[tree.size[pa]-1];
        for(int ch:tree.child[pa]){
            dp[pa] *= dp[ch];
            dp[pa] /= F[tree.size[ch]];
        }
    }
    reverse(ALL(tree.order));
    vector<modint> dp2(N,1);
    for(int pa:tree.order){
        dp[pa] = F[N-1];
        dp[pa] *= dp2[pa];
        dp[pa] /= F[N-tree.size[pa]];
        ll sum = 0;
        modint cnt = 1;
        modint mul = 1;
        for(int ch:tree.child[pa]){
            dp[pa] *= dp[ch];
            mul *= dp[ch];
            dp[pa] /= F[tree.size[ch]];
            cnt /= F[tree.size[ch]];
            sum += tree.size[ch];
        }
        mul *= dp2[pa];
        cnt /= F[N-tree.size[pa]];
        sum += N-tree.size[pa];
        for(int ch:tree.child[pa]){
            dp2[ch] *= cnt*F[tree.size[ch]];
            dp2[ch] *= F[sum-tree.size[ch]];
            dp2[ch] *= mul/dp[ch];
        }
    }
    for(auto e:dp) cout << e << endl;
    
    return 0;
}