#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>
#include <utility>
#include <cmath>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <tuple>
#include <numeric>
#include <functional>
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vector<ll>> vvl;
typedef pair<ll, ll> P;
#define rep(i, n) for(ll i = 0; i < n; i++)
#define exrep(i, a, b) for(ll i = a; i <= b; i++)
#define out(x) cout << x << endl
#define exout(x) printf("%.10f\n", x)
#define chmax(x, y) x = max(x, y)
#define chmin(x, y) x = min(x, y)
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define pb push_back
#define re0 return 0
const ll mod = 1000000007;
const ll INF = 1e16;
const ll MAX_N = 200010;

// aのn乗を求める。計算量はO(logn)
ll modpow(ll a, ll n) {
    if(n == 0) {
        return 1;
    }
    if(n%2 == 1) {
        return (a * modpow(a, n-1))%mod;
    }
    return (modpow(a, n/2) * modpow(a, n/2))%mod;
}

ll inverse(ll a) {
    return modpow(a, mod-2);
}

ll fact[MAX_N];  // fact[i] : iの階乗のmod
ll invfact[MAX_N];  // invfact[i] : iの階乗の逆数のmod

void init() {
    fact[0] = invfact[0] = 1;
    for(ll i = 1; i < MAX_N; i++) {
        fact[i] = (i * fact[i-1])%mod;
        invfact[i] = inverse(fact[i]);
    }
}

ll n;
vvl G;
vl subtreeSize;  // subtreeSize[v] : 頂点vを根とした部分木のサイズ
vl dp1;  // dp1[v] : 頂点vを根とする下方向の部分木の場合の数
vl dp2;  // dp2[v] : 頂点vを根とする上方向の部分木の場合の数
vl ans;  // ans[v] : 頂点vを根としたときの場合の数

void dfs1(ll v, ll p = -1) {
    // 行きの処理はこのへんに書く
    subtreeSize[v] = 1;
    for(ll to : G[v]) {
        if(to == p) {
            continue;
        }
        dfs1(to, v);
        // 帰りの処理はこのへんに書く
        subtreeSize[v] += subtreeSize[to];
    }
}

void dfs2(ll v, ll p = -1) {
    // 行きの処理はこのへんに書く
    dp1[v] = fact[subtreeSize[v] - 1];
    for(ll to : G[v]) {
        if(to == p) {
            continue;
        }
        dfs2(to, v);
        // 帰りの処理はこのへんに書く
        dp1[v] = dp1[to] * invfact[subtreeSize[to]] % mod * dp1[v] % mod;
    }
}

void dfs3(ll v, ll p = -1) {
    // 行きの処理はこのへんに書く
    if(p == -1) {
        dp2[v] = 1;
    }
    vl ruiL(G[v].size(), 1);
    rep(i, (ll)G[v].size()) {
        ll to = G[v][i];
        if(i-1 >= 0) {
            ruiL[i] = ruiL[i-1];
        }
        if(to == p) {
            continue;
        }
        ruiL[i] = dp1[to] * invfact[subtreeSize[to]] % mod * ruiL[i] % mod;
    }
    vl ruiR(G[v].size(), 1);
    for(ll i = G[v].size()-1; i >= 0; i--) {
        ll to = G[v][i];
        if(i+1 < (ll)G[v].size()) {
            ruiR[i] = ruiR[i+1];
        }
        if(to == p) {
            continue;
        }
        ruiR[i] = dp1[to] * invfact[subtreeSize[to]] % mod * ruiR[i] % mod;
    }
    rep(i, (ll)G[v].size()) {
        ll to = G[v][i];
        if(to == p) {
            continue;
        }
        dp2[to] = dp2[v] * fact[n-1 - subtreeSize[to]] % mod * invfact[n - subtreeSize[v]] % mod;
        if(i-1 >= 0) {
            dp2[to] = dp2[to] * ruiL[i-1] % mod;
        }
        if(i+1 < (ll)G[v].size()) {
            dp2[to] = dp2[to] * ruiR[i+1] % mod;
        }
        dfs3(to, v);
    }
}

void dfs4(ll v, ll p = -1) {
    // 行きの処理はこのへんに書く
    ans[v] = fact[n-1] * invfact[n - subtreeSize[v]] % mod * dp2[v] % mod;
    for(ll to : G[v]) {
        if(to == p) {
            continue;
        }
        ans[v] = dp1[to] * invfact[subtreeSize[to]] % mod * ans[v] % mod;
        dfs4(to, v);
        // 帰りの処理はこのへんに書く
    }
}

int main() {
    
    cin >> n;    
    
    G.resize(n);
    rep(i, n-1) {
        ll a, b;
        cin >> a >> b;
        a--;  b--;
        G[a].pb(b);
        G[b].pb(a);
    }

    subtreeSize.resize(n);
    dp1.resize(n);
    dp2.resize(n);
    ans.resize(n);
    init();
    dfs1(0);
    dfs2(0);
    dfs3(0);
    dfs4(0);

    rep(v, n) {
        out(ans[v]);
    }
    
    re0;
}

Measured memory_bytes: 28216