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 lint = long long;
const lint mod = 1e9 + 7;
#define all(x) (x).begin(), (x).end()
#define fcout cout << fixed << setprecision(15)
inline int bitcount(lint n){ return __builtin_popcountl(n); }
inline int highest(lint n){ return 63 - __builtin_clzl(n); }
inline void YES(bool condition){ if(condition) cout << "YES" << endl; else cout << "NO" << endl; }
inline void Yes(bool condition){ if(condition) cout << "Yes" << endl; else cout << "No" << endl; }
inline void assert_NO(bool condition){ if(!condition){ cout << "NO" << endl; exit(0); } }
inline void assert_No(bool condition){ if(!condition){ cout << "No" << endl; exit(0); } }
inline void assert_minus_1(bool condition){ if(!condition){ cout << -1 << endl; exit(0); } }
lint power(lint base, lint exponent, lint module){ if(exponent % 2){ return power(base, exponent - 1, module) * base % module; }else if(exponent){ lint root_ans = power(base, exponent / 2, module); return root_ans * root_ans % module; }else{ return 1; }}
inline lint mod_inv(lint n){ return power(n, mod - 2, mod); }
struct position{ int y, x; }; position mv[4] = {{0, -1}, {1, 0}, {0, 1}, {-1, 0}}; // double euclidean(position first, position second){ return sqrt((second.x - first.x) * (second.x - first.x) + (second.y - first.y) * (second.y - first.y)); }
template<class T, class U> string to_string(pair<T, U> x){ return to_string(x.first) + "," + to_string(x.second); } string to_string(string x){ return x; }
template<class itr> void array_output(itr start, itr goal){ string ans; for(auto i = start; i != goal; i++) ans += to_string(*i) + " "; if(!ans.empty()) ans.pop_back(); cout << ans << endl; }
template<class itr> void cins(itr first, itr last){ for(auto i = first; i != last; i++){ cin >> (*i); } }
template<class T> T gcd_calc(T a, T b){ if(b){ return gcd_calc(b, a % b); }else{ return a; }}
template<class T> T gcd(T a, T b){ if(a < b) swap(a, b); return gcd_calc(a, b); }
template<class T> T lcm(T a, T b){ return a / gcd(a, b) * b; }
struct combination{ vector<lint> fact, inv; combination(int sz) : fact(sz + 1), inv(sz + 1){ fact[0] = 1; for(int i = 1; i <= sz; i++){ fact[i] = fact[i - 1] * i % mod; } inv[sz] = power(fact[sz], mod - 2, mod); for(int i = sz - 1; i >= 0; i--){ inv[i] = inv[i + 1] * (i + 1) % mod; } } lint C(int p, int q) const{ if(q < 0 || p < q) return 0; return (fact[p] * inv[q] % mod * inv[p - q] % mod); } };
template<class itr> bool next_sequence(itr first, itr last, int max_bound){ itr now = last; while(now != first){ now--; (*now)++; if((*now) == max_bound){ (*now) = 0; }else{ return true; } } return false; }
template<class T> bool chmax(T &a, const T &b){ if(a < b){ a = b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b){ if(b < a){ a = b; return 1; } return 0; }
inline int at(int x, int k){ return (x >> k) & 1; }
random_device rnd;
#define rep(i, n) for(int i = 0; i < (n); i++)
#define rep2(i, l, n) for(int i = int(l); i < (n); i++)
#define repr(i, n) for(int i = int(n) - 1; i >= 0; i--)

combination table(1e6);

int N;
vector<vector<int>> roads;

vector<int> size;
vector<lint> down_dp, up_dp;

void dfs(int now, int back){
    for(int i: roads[now]){
        if(i != back){
            dfs(i, now);
            size[now] += size[i];
            down_dp[now] = down_dp[now] * table.inv[size[i]] % mod * down_dp[i] % mod;
        }
    }
    down_dp[now] = down_dp[now] * table.fact[size[now] - 1] % mod;
}

void dfs_for_up(int now, int back){
    lint base = up_dp[now] * table.inv[N - size[now]] % mod;
    for(int i: roads[now]){
        if(i != back){
            base = base * table.inv[size[i]] % mod * down_dp[i] % mod;
        }
    }
    for(int i: roads[now]){
        if(i != back){
            up_dp[i] = base * table.fact[size[i]] % mod * mod_inv(down_dp[i]) % mod * table.fact[N - 1 - size[i]] % mod;
            dfs_for_up(i, now);
        }
    }
}

vector<lint> ans;

void get_ans(int now, int back){
    ans[now] = table.fact[N - 1];
    for(int i: roads[now]){
        if(i != back){
            get_ans(i, now);
            ans[now] = ans[now] * table.inv[size[i]] % mod * down_dp[i] % mod;
        }
    }
    ans[now] = ans[now] * table.inv[N - size[now]] % mod * up_dp[now] % mod;
}

int main(){
    cin >> N;
    roads.resize(N);
    rep(i, N - 1){
        int a, b;
        cin >> a >> b;
        a--, b--;
        roads[a].push_back(b);
        roads[b].push_back(a);
    }
    size.resize(N, 1);
    down_dp.resize(N, 1);
    dfs(0, -1);
    up_dp.resize(N);
    up_dp[0] = 1;
    dfs_for_up(0, -1);
    //array_output(all(down_dp));
    //array_output(all(up_dp));
    ans.resize(N);
    get_ans(0, -1);
    rep(i, N){
        cout << ans[i] << endl;
    }
}