#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <queue>
#include <tuple>
#include <algorithm>
#include <functional>
#include <cmath>
#include <numeric>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
typedef long long ll;

// #define DEBUG 1
// debug
// https://trap.jp/post/998/
void debug_out() { cout << endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cout << H << " ";
  debug_out(T...);
}
#ifdef DEBUG
#define debug(...) debug_out(__VA_ARGS__)
#else
#define debug(...) 
#endif

const int MAX_N = 200009;
const ll bigprime = 1000000007;
int tree_size;
vector<int> edge1(MAX_N), edge2(MAX_N); // 辺の端点2つ
vector<ll> result1(MAX_N); // dfs1回目
vector<ll> result1_partial(MAX_N, 1); // dfs1回目 子の結果をマージしたもの
vector<ll> result2(MAX_N); // dfs2回目
vector<vector<ll>> result2_left(MAX_N, vector<ll>(1, 1)); // 累積
vector<vector<ll>> result2_right(MAX_N, vector<ll>(1, 1)); // 累積
vector<int> subtree_size(MAX_N, 1); // dfs1回目 部分木のサイズ
vector<int> parent(MAX_N); // dfs1回目での親
vector<int> index_in_parent(MAX_N); // 親の何番目の子か
vector<vector<int>> adjacent(MAX_N, vector<int>()); // 隣接頂点のリスト
vector<vector<int>> childs(MAX_N, vector<int>()); // adjacent と似ているが、親を含めない
vector<ll> modfactmemo(1, 1);

ll modpow(ll n, ll k)
{
  if (k <= 0)
  {
    return 1;
  }
  else if (k % 2 == 0)
  {
    ll res = modpow(n, k / 2);
    return (res * res) % bigprime;
  }
  else
  {
    ll res = modpow(n, k - 1);
    return (res * n) % bigprime;
  }
}

ll modinv(ll n)
{
  return modpow(n, bigprime - 2);
}

ll modfact(int n)
{
  if (modfactmemo.size() > n)
  {
    return modfactmemo.at(n);
  }
  ll res = (modfact(n - 1) * n) % bigprime;
  modfactmemo.push_back(res);
  return res;
}

// 子の結果をマージしたものから、posでの結果を得る
ll calcup(int subtree_size, ll childsres)
{
  return (subtree_size == 1) ? 1
    : (modinv(subtree_size) * childsres % bigprime);
}

// result1 たち, subtree_size, parent, index_in_parent を計算
void dfs1(int pos)
{
  int num_ad = adjacent.at(pos).size();
  // debug("pos, num_ad", pos, num_ad);

  // 子についてdfs1
  for (int i = 0; i < num_ad; i++)
  {
    int child = adjacent.at(pos).at(i);
    if (child == parent.at(pos))
    {
      continue;
    }
    // debug("child, index_in_parent", child, i);
    childs.at(pos).push_back(child);
    parent[child] = pos;
    index_in_parent[child] = i;
    dfs1(child);

    subtree_size[pos] += subtree_size.at(child);
  }

  int num_ch = childs.at(pos).size();

  // // 累積を計算
  // 子の結果をマージ
  for (int i = 0; i < num_ch; i++)
  {
    // debug("pos, partial", pos, result1_partial.at(pos));
    int child = childs.at(pos).at(i);
    result1_partial[pos] = result1_partial.at(pos) * result1.at(child) % bigprime;
  }
  /*
  for (int i = 0; i < num_ch; i++)
  {
    int child = childs.at(pos).at(num_ch - 1 - i);
    result1_right.at(pos).push_back((result1_right.at(pos).at(i) * result1.at(child)) % bigprime);
  }
  */

  // calc result1[pos]
  // result1[pos] = calcup(pos, num_ch, result1_left.at(pos).at(num_ch));
  result1[pos] = calcup(subtree_size.at(pos), result1_partial.at(pos));
  debug("pos, result1", pos, result1.at(pos) * modfact(subtree_size.at(pos)) % bigprime);
}

void dfs2(int pos)
{
  // もうループでいいけど

  int num_ad = adjacent.at(pos).size();
  int num_ch = childs.at(pos).size();

  // posでの結果
  if (pos == 0)
  {
    result2[pos] = result1.at(pos);

    rep(i, num_ad)
    {
      int child = childs.at(pos).at(i);
      result2_left.at(pos).push_back(result2_left.at(pos).at(i) * result1.at(child) % bigprime);
    }
    rep(i, num_ad)
    {
      int child = childs.at(pos).at(num_ad - 1 - i);
      result2_right.at(pos).push_back(result2_right.at(pos).at(i) * result1.at(child) % bigprime);
    }
  }
  else
  {
    int par_pos = parent.at(pos);
    int num_ad_par = adjacent.at(par_pos).size();
    int i = index_in_parent.at(pos);
    // ll par_res = (result1_left.at(par_pos).at(i) * result1_right.at(par_pos).at(num_ad_par - 1 - i)) % bigprime;
    ll par_res = result2_left.at(par_pos).at(i) * result2_right.at(par_pos).at(num_ad_par - 1 - i) % bigprime;
    par_res = calcup(tree_size - subtree_size.at(pos), par_res);
    debug("pos, par_res", pos, par_res);
    result2[pos] = calcup(tree_size, par_res * result1_partial.at(pos) % bigprime);

    rep(i, num_ad)
    {
      int child = adjacent.at(pos).at(i);
      ll res;
      if (child == parent.at(pos))
      {
        res = par_res;
      }
      else
      {
        res = result1.at(child);
      }
      result2_left.at(pos).push_back(result2_left.at(pos).at(i) * res % bigprime);
    }
    rep(i, num_ad)
    {
      int child = adjacent.at(pos).at(num_ad - 1 - i);
      ll res;
      if (child == parent.at(pos))
      {
        res = par_res;
      }
      else
      {
        res = result1.at(child);
      }
      result2_right.at(pos).push_back(result2_right.at(pos).at(i) * res % bigprime);
    }
  }

  // 子にも
  rep(i, num_ch)
  {
    int child = childs.at(pos).at(i);
    dfs2(child);
  }
}

int main()
{
  cin >> tree_size;
  rep(i, tree_size-1)
  {
    cin >> edge1[i] >> edge2[i];
    edge1[i]--; edge2[i]--;
    adjacent.at(edge1.at(i)).push_back(edge2.at(i));
    adjacent.at(edge2.at(i)).push_back(edge1.at(i));
  }

  parent[0] = -1;
  index_in_parent[0] = -1;
  dfs1(0);

  dfs2(0);

  rep(pos, tree_size)
  {
    cout << (result2.at(pos) * modfact(tree_size) % bigprime) << endl;
  }
}

Measured memory_bytes: 75868