#define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
#define FOR(i, a, b) for(ll i = a; i < b; i++)
#define rep(i, n) FOR(i, 0, n)
#define rFOR(i, a, b) for(ll i = a - 1; i >= b; i--)
#define rrep(i, a) rFOR(i, a, 0)
#define pb push_back
using namespace std;
using ll = long long;
using ld = long double;
typedef pair<ll,ll> P;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<P> vP;
typedef vector<char> vc;
typedef vector<vc> vvc;
const ll MOD = 1000000007;
const ll MOD2 = 998244353;
const ld PI = acos(-1);
const ll INF = 1e18;
struct edge{ll to, cost;};

template <typename T>
bool chmax(T &a, const T &b) {
    if (a < b) {
      a = b;
        return true;
    }
    return false;
}

template <typename T>
bool chmin(T &a, const T &b) {
    if (a > b) {
      a = b;
      return true;
    }
    return false;
}

//組み合わせを線形で
//参考:https://drken1215.hatenablog.com/entry/2018/06/08/210000

const int MXN = 1000001;//変更可
long long fac[MXN], inv[MXN], finv[MXN];

void COMinit(int M){
    fac[0] = fac[1] = 1;
    inv[1] = 1;
    finv[0] = finv[1] = 1;
    for(int i = 2; i < MXN; i++){
        fac[i] = fac[i-1] * i % M;
        inv[i] = M - M / i * inv[M%i] % M;
        finv[i] = finv[i-1] * inv[i] % M;
    }
}

long long COMBI(int N, int K, int M){
    if(N < K){
        return 0;
    }
    if(N < 0||K < 0){
        return 0;
    }
    return fac[N] * finv[N-K] % M * finv[K] % M;
}

long long PERMU(int N, int K, int M){
    if(N < K){
        return 0;
    }
    if(N < 0||K < 0){
        return 0;
    }
    return fac[N] * finv[N-K] % M;
}

/* Rerooting: 全方位木 DP
    問題ごとに以下を書き換える
    - 型DPと単位元
    - 型DPに対する二項演算 merge
    - まとめたDPを用いて新たな部分木のDPを計算する add_root
    計算量: O(N)
*/
struct Rerooting {
    /* start 問題ごとに書き換え */
    struct DP {  // DP の型
        ll dp;
        ll s;
        DP(ll dp_, ll s_) : dp(dp_),s(s_) {}
    };
    const DP identity = DP(1,0);  // 単位元(末端の値は add_root(identity) になるので注意)
    function<DP(DP, DP,ll)> merge = [](DP dp_cum, DP d,ll cost) -> DP {
        ll n = dp_cum.s + d.s;
        return DP(((dp_cum.dp*d.dp)%MOD*COMBI(n,d.s,MOD))%MOD,n);
    };
    function<DP(DP)> add_root = [](DP d) -> DP {
        return DP(d.dp,d.s+1);
    };
    /* end 問題ごとに書き換え */
    // グラフの定義
    struct Edge {
        ll from; ll to; ll cost;
    };
    using Graph = vector<vector<Edge>>;
    vector<vector<DP>> dp;  // dp[v][i]: vから出るi番目の有向辺に対応する部分木のDP
    vector<DP> ans;         // ans[v]: 頂点vを根とする木の答え
    Graph G;
    Rerooting(ll N) : G(N) {
        dp.resize(N);
        ans.assign(N, identity);
    }
    void add_edge(ll a, ll b,ll c=1) {
        G[a].push_back({ a,b,c });
    }
    void build() {
        dfs(0);            // 普通に木DP
        bfs(0, identity);  // 残りの部分木に対応するDPを計算
    }
    DP dfs(ll v, ll p = -1) {  // 頂点v, 親p
        DP dp_cum = identity;
        ll deg = G[v].size();
        dp[v] = vector<DP>(deg, identity);
        for (ll i = 0; i < deg; i++) {
            ll u = G[v][i].to;
            if (u == p) continue;
            dp[v][i] = dfs(u, v);
            dp_cum = merge(dp_cum, dp[v][i],G[v][i].cost);
        }
        return add_root(dp_cum);
    }
    void bfs(ll v, const DP& dp_p, ll p = -1) {  // bfs だが、実装が楽なので中身は dfs になっている
        ll deg = G[v].size();
        for (ll i = 0; i < deg; i++) {  // 前のbfsで計算した有向辺に対応する部分木のDPを保存
            if (G[v][i].to == p) dp[v][i] = dp_p;
        }
        vector<DP> dp_l(deg + 1, identity), dp_r(deg + 1, identity);  // 累積merge
        for (ll i = 0; i < deg; i++) {
            dp_l[i + 1] = merge(dp_l[i], dp[v][i],G[v][i].cost);
        }
        for (ll i = deg - 1; i >= 0; i--) {
            dp_r[i] = merge(dp_r[i + 1], dp[v][i],G[v][i].cost);
        }
 
        ans[v] = add_root(dp_l[deg]);  // 頂点 v の答え
 
        for (ll i = 0; i < deg; i++) {  // 一つ隣の頂点に対しても同様に計算
            ll u = G[v][i].to;
            if (u == p) continue;
            bfs(u, add_root(merge(dp_l[i], dp_r[i + 1],0)), v);
        }
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int N;
    cin >> N;
    COMinit(MOD);
    Rerooting reroot(N);
    rep(i,N-1){
        int u,v;
        cin >> u >> v;
        u--;v--;
        reroot.add_edge(u,v);
        reroot.add_edge(v,u);
    }
    reroot.build();
    rep(i,N){
        cout << reroot.ans[i].dp << '\n';
    }
}
/*
overflow checked?
corner case checked?
boundary checked?
not TLE in worst case checked?
*/

Measured memory_bytes: 78276