#include <bits/stdc++.h>

#if DEBUG
template <typename T>
void debug(const T& value) {
  std::cerr << value;
}
template <typename T, typename... Ts>
void debug(const T& value, const Ts&... args) {
  std::cerr << value << ", ";
  debug(args...);
}
#define dbg(...)                        \
  do {                                  \
    cerr << #__VA_ARGS__ << ": ";       \
    debug(__VA_ARGS__);                 \
    cerr << " (L" << __LINE__ << ")\n"; \
  } while (0)
#else
#define dbg(...)
#endif

void read_from_cin() {}
template <typename T, typename... Ts>
void read_from_cin(T& value, Ts&... args) {
  std::cin >> value;
  read_from_cin(args...);
}
#define rd(type, ...) \
  type __VA_ARGS__;   \
  read_from_cin(__VA_ARGS__);

template <typename T>
void write_to_cout(const T& value) {
  std::cout << value << '\n';
}
template <typename T, typename... Ts>
void write_to_cout(const T& value, const Ts&... args) {
  std::cout << value << ' ';
  write_to_cout(args...);
}
#define wt(...) write_to_cout(__VA_ARGS__);

#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)

using ll = long long;

template <typename T>
using V = std::vector<T>;
template <typename T>
using VV = V<V<T>>;

template <int Mod>
class ModInt {
 public:
  ModInt() : n_(0) {}
  ModInt(long long n) : n_(n % Mod) {
    if (n_ < 0) {
      // In C++, (-n)%m == -(n%m).
      n_ += Mod;
    }
  }
  ModInt& operator+=(const ModInt& m) {
    n_ += m.n_;
    if (n_ >= Mod) {
      n_ -= Mod;
    }
    return *this;
  }
  ModInt& operator++() { return (*this) += 1; }
  ModInt& operator-=(const ModInt& m) {
    n_ -= m.n_;
    if (n_ < 0) {
      n_ += Mod;
    }
    return *this;
  }
  ModInt& operator--() { return (*this) -= 1; }
  ModInt& operator*=(const ModInt& m) {
    n_ *= m.n_;
    n_ %= Mod;
    return *this;
  }
  ModInt& operator/=(const ModInt& m) {
    *this *= m.Inv();
    return *this;
  }
#define DEFINE_BINARY_OPERATOR(op) \
  ModInt operator op(const ModInt& m) const { return ModInt(*this) op## = m; }
  DEFINE_BINARY_OPERATOR(+)
  DEFINE_BINARY_OPERATOR(-)
  DEFINE_BINARY_OPERATOR(*)
  DEFINE_BINARY_OPERATOR(/)
#undef DEFINE_BINARY_OPERATOR
#define DEFINE_COMPARISON_OPERATOR(op) \
  bool operator op(const ModInt& m) const { return n_ op m.n_; }
  DEFINE_COMPARISON_OPERATOR(!=)
  DEFINE_COMPARISON_OPERATOR(<)
  DEFINE_COMPARISON_OPERATOR(<=)
  DEFINE_COMPARISON_OPERATOR(==)
  DEFINE_COMPARISON_OPERATOR(>)
  DEFINE_COMPARISON_OPERATOR(>=)
#undef BDEFINE_COMPARISON_OPERATOR
  ModInt operator-() const { return ModInt(-n_); }
  ModInt Pow(int n) const {
    if (n < 0) {
      return Inv().Pow(-n);
    }
    // a * b ^ n = answer.
    ModInt a = 1, b = *this;
    while (n != 0) {
      if (n & 1) {
        a *= b;
      }
      n /= 2;
      b *= b;
    }
    return a;
  }
  ModInt Inv() const {
    // Compute the inverse based on Fermat's little theorem. Note that this only
    // works when n_ and Mod are relatively prime. The theorem says that
    // n_^(Mod-1) = 1 (mod Mod). So we can compute n_^(Mod-2).
    return Pow(Mod - 2);
  }
  long long value() const { return n_; }

  static ModInt Fact(int n) {
    for (int i = fact_.size(); i <= n; ++i) {
      fact_.push_back(i == 0 ? 1 : fact_.back() * i);
    }
    return fact_[n];
  }
  static ModInt Comb(int n, int k) { return Perm(n, k) / Fact(k); }
  static ModInt CombSlow(int n, int k) { return PermSlow(n, k) / Fact(k); }
  static ModInt Perm(int n, int k) {
#if DEBUG
    assert(n <= 1000000 &&
           "n is too large. If k is small, consider using PermSlow.");
#endif
    return Fact(n) / Fact(n - k);
  }
  static ModInt PermSlow(int n, int k) {
    ModInt p = 1;
    for (int i = 0; i < k; ++i) {
      p *= (n - i);
    }
    return p;
  }

 private:
  long long n_;
  static std::vector<ModInt> fact_;
};

template <int Mod>
std::vector<ModInt<Mod>> ModInt<Mod>::fact_;

template <int Mod>
std::ostream& operator<<(std::ostream& out, const ModInt<Mod>& m) {
  out << m.value();
  return out;
}

using mint = ModInt<1000000007>;

template <typename T>
class TreeDP {
 public:
  TreeDP(const std::vector<std::vector<int>>& edges, std::function<T(T, T)> op2,
         std::function<T(T)> op1, T identity = T())
      : edges_(edges), op2_(op2), op1_(op1), identity_(identity) {
    dp_.resize(edges.size());
    for (std::size_t i = 0; i < edges.size(); ++i) {
      dp_[i].resize(edges[i].size());
    }
    result_.resize(edges.size());
  }

  void DFS(int root) {
    // Use a stack to avoid potential stack overflows.
    std::stack<std::tuple<int, int, int, bool>> s;
    s.push({root, -1, -1, true});

    while (!s.empty()) {
      auto [node, parent, parent_index, enter] = s.top();
      s.pop();

      if (enter) {
        s.push({node, parent, parent_index, false});
        for (std::size_t i = 0; i < edges_[node].size(); ++i) {
          if (int child = edges_[node][i]; child != parent) {
            s.push({child, node, i, true});
          }
        }
      } else {
        T t = identity_;
        for (std::size_t i = 0; i < edges_[node].size(); ++i) {
          if (int child = edges_[node][i]; child != parent) {
            t = op2_(t, dp_[node][i]);
          }
        }
        if (parent != -1) {
          dp_[parent][parent_index] = op1_(t);
        }
      }
    }
  }

  void Rerooting(int root) {
    std::stack<std::tuple<int, int, T>> s;
    s.push({root, -1, identity_});

    while (!s.empty()) {
      auto [node, parent, parent_result] = s.top();
      s.pop();

      const std::vector<int> edges = edges_[node];
      std::vector<T>& dp = dp_[node];

      if (parent != -1) {
        for (std::size_t i = 0; i < edges.size(); ++i) {
          if (edges[i] == parent) {
            dp[i] = parent_result;
          }
        }
      }

      // lower[i] = op2_(dp[i - 1], op2_(dp[i - 2], ...))
      std::vector<T> lower(edges.size() + 1);
      lower[0] = identity_;
      for (std::size_t i = 0; i < edges.size(); ++i) {
        lower[i + 1] = op2_(lower[i], dp[i]);
      }

      // higher[i] = op2_(dp[i], op2_(dp[i + 1], ...))
      std::vector<T> higher(edges.size() + 1);
      higher[edges.size()] = identity_;
      for (std::size_t i = edges.size() - 1; i < edges.size(); --i) {
        higher[i] = op2_(higher[i + 1], dp[i]);
      }

      result_[node] = op1_(higher[0]);

      for (std::size_t i = 0; i < edges.size(); ++i) {
        if (int child = edges[i]; child != parent) {
          s.push({child, node, op1_(op2_(lower[i], higher[i + 1]))});
        }
      }
    }
  }

  const std::vector<std::vector<T>>& DP() const { return dp_; }
  const std::vector<T>& Result() const { return result_; }

 private:
  std::vector<std::vector<int>> edges_;

  const std::function<T(T, T)> op2_;
  const std::function<T(T)> op1_;
  const T identity_;

  std::vector<std::vector<T>> dp_;
  std::vector<T> result_;
};

using namespace std;

struct DP {
  int size;
  mint cnt;
  mint fact;
};

ostream& operator<<(ostream& os, const DP& dp) {
  os << "{" << dp.size << "," << dp.cnt << "," << dp.fact << "}";
  return os;
}

DP Combine(DP a, DP b) {
  return {a.size + b.size, a.cnt * b.cnt, a.fact * b.fact};
}

DP Calc(DP x) {
  return {x.size + 1, x.cnt / x.fact * mint::Fact(x.size),
          mint::Fact(x.size + 1)};
}

int main() {
  int N;
  cin >> N;

  vector<vector<int>> edges(N);
  rep(i, N - 1) {
    int a, b;
    cin >> a >> b;
    --a, --b;
    edges[a].push_back(b);
    edges[b].push_back(a);
  }

  TreeDP<DP> tdp(edges, Combine, Calc, {0, 1, 1});
  tdp.DFS(0);
  tdp.Rerooting(0);
  rep(i, N) wt(tdp.Result()[i].cnt);
}


Measured memory_bytes: 65180