#include "bits/stdc++.h"
#define rep(i,n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<int, int>;

// auto mod int
// https://youtu.be/L8grWxBlIZ4?t=9858
// https://youtu.be/ERZuLAxZffQ?t=4807 : optimize
// https://youtu.be/8uowVvQ_-Mo?t=1329 : division
const int mod = 1000000007;
struct mint {
	ll x; // typedef long long ll;
	mint(ll x = 0) :x((x%mod + mod) % mod) {}
	mint operator-() const { return mint(-x); }
	mint& operator+=(const mint a) {
		if ((x += a.x) >= mod) x -= mod;
		return *this;
	}
	mint& operator-=(const mint a) {
		if ((x += mod - a.x) >= mod) x -= mod;
		return *this;
	}
	mint& operator*=(const mint a) { (x *= a.x) %= mod; return *this; }
	mint operator+(const mint a) const { return mint(*this) += a; }
	mint operator-(const mint a) const { return mint(*this) -= a; }
	mint operator*(const mint a) const { return mint(*this) *= a; }
	mint pow(ll t) const {
		if (!t) return 1;
		mint a = pow(t >> 1);
		a *= a;
		if (t & 1) a *= *this;
		return a;
	}

	// for prime mod
	mint inv() const { return pow(mod - 2); }
	mint& operator/=(const mint a) { return *this *= a.inv(); }
	mint operator/(const mint a) const { return mint(*this) /= a; }
};
istream& operator>>(istream& is, const mint& a) { return is >> a.x; }
ostream& operator<<(ostream& os, const mint& a) { return os << a.x; }
// combination mod prime
// https://www.youtube.com/watch?v=8uowVvQ_-Mo&feature=youtu.be&t=1619
struct combination {
	vector<mint> fact, ifact;
	combination(int n) :fact(n + 1), ifact(n + 1) {
		assert(n < mod);
		fact[0] = 1;
		for (int i = 1; i <= n; ++i) fact[i] = fact[i - 1] * i;
		ifact[n] = fact[n].inv();
		for (int i = n; i >= 1; --i) ifact[i - 1] = ifact[i] * i;
	}
	mint operator()(int n, int k) {
		if (k < 0 || k > n) return 0;
		return fact[n] * ifact[k] * ifact[n - k];
	}
	mint p(int n, int k) {
		return fact[n] * ifact[n - k];
	}
}c(1000005);
/* Rerooting: 全方位木 DP
	問題ごとに以下を書き換える
	- 型DPと単位元
	- 型DPに対する二項演算 merge
	- まとめたDPを用いて新たな部分木のDPを計算する add_root
	計算量: O(N)
*/
struct Rerooting {
	/* start 問題ごとに書き換え */
	struct DP {  // DP の型
		mint dp;
		int s;
		DP(mint dp_,int s_) : dp(dp_),s(s_) {}
	};

	const DP identity = DP(mint(1),0);  // 単位元(末端の値は add_root(identity) になるので注意)
	function<DP(DP, DP, long long)> merge = [](DP dp_cum, DP d,long long cost) -> DP {
		int n = dp_cum.s + d.s;
		return DP(dp_cum.dp * d.dp*c(n,d.s),n);
	};

	function<DP(DP)> add_root = [](DP d) -> DP {
		return DP(d.dp, d.s+ 1);
	};

	/* end 問題ごとに書き換え */
	// グラフの定義
	struct Edge {
		int from;
		int to;
		long long 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(int N) : G(N) {
		dp.resize(N);
		ans.assign(N, identity);
	}
	void add_edge(int a, int b,long long c =1) {
		G[a].push_back({a, b ,c});
	}
	void build() {
		dfs(0);            // 普通に木DP
		bfs(0, identity);  // 残りの部分木に対応するDPを計算
	}
	DP dfs(int v, int p = -1) {  // 頂点v, 親p
		DP dp_cum = identity;
		int deg = G[v].size();
		dp[v] = vector<DP>(deg, identity);
		for (int i = 0; i < deg; i++) {
			int 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(int v, const DP& dp_p, int p = -1) {  // bfs だが、実装が楽なので中身は dfs になっている
		int deg = G[v].size();
		for (int 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 (int i = 0; i < deg; i++) {
			dp_l[i + 1] = merge(dp_l[i], dp[v][i], G[v][i].cost);
		}
		for (int 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 (int i = 0; i < deg; i++) {  // 一つ隣の頂点に対しても同様に計算
			int 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() {
	int N;
	cin >> N;
	Rerooting reroot(N);
	for (int i = 0; i < N - 1; i++) {
		int u, v;
		cin >> u >> v;
		u--, v--;
		reroot.add_edge(u, v);
		reroot.add_edge(v, u);
	}
	reroot.build();
	for (int i = 0; i < N; i++) {
		cout << reroot.ans[i].dp << endl;
	}
}

Measured memory_bytes: 56376