#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ull = unsigned long long;
#define repi(n) for (long long i = 0; i < (n); ++i)
#define repj(n) for (long long j = 0; j < (n); ++j)
#define repk(n) for (long long k = 0; k < (n); ++k)
#define rep(i, a, b) for (auto i = (a); i < (b); ++i)
#define itr(itr) for (auto&& v : (itr))
#define updatemax(t, v) (t = std::max(t, (v)))
#define updatemin(t, v) (t = std::min(t, (v)))

#include <boost/concept_check.hpp>
#include <functional>
#include <vector>

template <typename T, typename Merge, typename Post, typename Pre>
struct _Rerooting {
  const std::vector<std::vector<int>>& graph;
  Merge merge;
  T mergeIdentity;
  Post post;
  Pre pre;
  int n;
  std::vector<int> adjucentsLen;
  std::vector<std::vector<T>> dp;
  std::vector<T> result;

  _Rerooting(const std::vector<std::vector<int>>& graph, Merge merge, T mergeIdentity, Post post, Pre pre)
      : graph(graph), merge(merge), mergeIdentity(mergeIdentity), post(post), pre(pre), n(graph.size()) {
    adjucentsLen.resize(n);
    dp.resize(n);
    result.resize(n);
    for (int i = 0; i < n; i++) {
      adjucentsLen[i] = graph[i].size();
      dp[i].resize(adjucentsLen[i]);
    }
  }

  T dfs1(int parent, int current) {
    T result = mergeIdentity;
    for (int i = 0; i < adjucentsLen[current]; ++i) {
      int child = graph[current][i];
      if (child == parent) continue;
      dp[current][i] = dfs1(current, child);
      result = merge(result, pre(dp[current][i], child));
    }
    return post(result, current);
  }

  void dfs2(int parent, int current, T upstreamValue) {
    int m = adjucentsLen[current];

    for (int i = 0; i < m; i++) {
      if (graph[current][i] == parent) {
        dp[current][i] = upstreamValue;
        break;
      }
    }

    std::vector<T> pS(m), pL(m + 1), pR(m + 1);
    for (int i = 0; i < m; ++i) pS[i] = pre(dp[current][i], graph[current][i]);
    pL[0] = mergeIdentity;
    for (int i = 0; i < m; ++i) pL[i + 1] = merge(pL[i], pS[i]);
    pR[m] = mergeIdentity;
    for (int i = m; i > 1; --i) pR[i - 1] = merge(pR[i], pS[i - 1]);
    pR[0] = pL[m];
    result[current] = post(pL[m], current);

    for (int i = 0; i < m; ++i) {
      int child = graph[current][i];
      if (child == parent) continue;
      T value = merge(pL[i], pR[i + 1]);
      dfs2(current, child, post(value, current));
    }
  }

  std::vector<T> calc() {
    dfs1(-1, 0);
    dfs2(-1, 0, mergeIdentity);
    return result;
  }
};
template <typename T, typename Merge, typename Post = T (*)(const T&, int), typename Pre = T (*)(const T&, int)>
std::vector<T> rerooting(
    const std::vector<std::vector<int>>& graph,
    Merge merge,
    T mergeIdentity,
    Post post = [](const T& a, int i) { return a; },
    Pre pre = [](const T& a, int i) { return a; }) {
  boost::function_requires<boost::ConvertibleConcept<Merge, std::function<T(T&, T&)>>>();
  boost::function_requires<boost::ConvertibleConcept<Post, std::function<T(T&, int)>>>();
  boost::function_requires<boost::ConvertibleConcept<Pre, std::function<T(T&, int)>>>();
  return _Rerooting(graph, merge, mergeIdentity, post, pre).calc();
}

const ll M = 1e9 + 7;
ll inv(long long x) {
  long long r = 1, a = x;
  int b = M - 2;
  while (b) {
    if (b & 1) r = r * a % M;
    b = b >> 1;
    a = a * a % M;
  }
  return r;
}

int main() {
  int n;
  cin >> n;
  vector<vector<int>> g(n);
  repi(n - 1) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    g[a].push_back(b);
    g[b].push_back(a);
  }
  vector<ll> fact(n + 1), factinv(n + 1);
  fact[0] = 1;
  rep(i, 1, n + 1) fact[i] = i * fact[i - 1] % M;
  repi(n + 1) factinv[i] = inv(fact[i]);
  using T = pair<ll, int>;
  auto re = rerooting<T>(
      g,
      [&](const T& a, const T& b) { return T(a.first * b.first % M * fact[a.second + b.second] % M * factinv[a.second] % M * factinv[b.second] % M, a.second + b.second); },
      T(1, 0),
      [](const T& a, int i) { return T(a.first, a.second + 1); });
  itr(re) cout << v.first << endl;
}


Measured memory_bytes: 45336