Problem p02728 (C++) — buggy submission, verdict: Runtime Error

// include
//------------------------------------------
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <locale>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

// typedef
//------------------------------------------
typedef long long LL;
typedef vector<int> VI;
typedef vector<bool> VB;
typedef vector<char> VC;
typedef vector<double> VD;
typedef vector<string> VS;
typedef vector<LL> VLL;
typedef vector<VI> VVI;
typedef vector<VB> VVB;
typedef vector<VS> VVS;
typedef vector<VLL> VVLL;
typedef vector<VVI> VVVI;
typedef vector<VVLL> VVVLL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef pair<int, string> PIS;
typedef pair<string, int> PSI;
typedef pair<string, string> PSS;
typedef vector<PII> VPII;
typedef vector<PLL> VPLL;
typedef vector<VPII> VVPII;
typedef vector<VPLL> VVPLL;
typedef vector<VS> VVS;
typedef map<int, int> MII;
typedef map<LL, LL> MLL;
typedef map<string, int> MSI;
typedef map<int, string> MIS;

// container util
//------------------------------------------
#define ALL(a) (a).begin(), (a).end()
#define SZ(a) int((a).size())
#define EACH(i, arr)                                                           \\
  for (typeof((arr).begin()) i = (arr).begin(); i != (arr).end(); ++i)
#define EXIST(str, e) ((str).find(e) != (str).end())
#define COUNT(arr, v) count((arr).begin(), (arr).end(), v)
#define SEARCH(v, w) search((v).begin(), (v).end(), (w).begin(), (w).end())
#define SORT(c) sort((c).begin(), (c).end())
#define RSORT(c) sort((c).rbegin(), (c).rend())
#define REVERSE(c) reverse((c).begin(), (c).end())
#define ROTATE_LEFT(arr, c)                                                    \\
  rotate((arr).begin(), (arr).begin() + (c), (arr).end())
#define ROTATE_RIGHT(arr, c)                                                   \\
  rotate((arr).rbegin(), (arr).rbegin() + (c), (arr).rend())
#define SUMI(arr) accumulate((arr).begin(), (arr).end(), 0)
#define SUMD(arr) accumulate((arr).begin(), (arr).end(), 0.)
#define SUMLL(arr) accumulate((arr).begin(), (arr).end(), 0LL)
#define MULD(arr)                                                              \\
  accumulate((arr).begin(), (arr).end(), 1., multiplies<double>())
#define UB(arr, n) upper_bound((arr).begin(), (arr).end(), n)
#define LB(arr, n) lower_bound((arr).begin(), (arr).end(), n)
#define PB push_back
#define MP make_pair
#define ft first
#define sd second

// input output
//------------------------------------------
#define GL(s) getline(cin, (s))
#define INIT()                                                                 \\
  std::ios::sync_with_stdio(false);                                            \\
  std::cin.tie(0)
#define OUT(d) std::cout << (d)
#define OUT_L(d) std::cout << (d) << endl
#define FOUT(n, data) std::cout << std::fixed << std::setprecision(n) << (data)
#define FOUT_L(n, data)                                                        \\
  std::cout << std::fixed << std::setprecision(n) << (data) << "\\n"
#define EL() printf("\\n")
#define SHOW_VECTOR(v)                                                         \\
  {                                                                            \\
    std::cerr << #v << "\\t:";                                                  \\
    for (const auto &xxx : v) {                                                \\
      std::cerr << xxx << " ";                                                 \\
    }                                                                          \\
    std::cerr << "\\n";                                                         \\
  }
#define SHOW_MAP(v)                                                            \\
  {                                                                            \\
    std::cerr << #v << endl;                                                   \\
    for (const auto &xxx : v) {                                                \\
      std::cerr << xxx.first << " " << xxx.second << "\\n";                     \\
    }                                                                          \\
  }
#define Yes() printf("Yes\\n")
#define No() printf("No\\n")
#define YES() printf("YES\\n")
#define NO() printf("NO\\n")
#define Yay() printf("Yay!\\n")
#define Nnn() printf(":(\\n")
#define CE(x, y) ((x + y - 1) / (y))

template <typename T1, typename T2>
istream &operator>>(istream &in, pair<T1, T2> &p) {
  in >> p.first >> p.second;
  return in;
}

template <typename T> istream &operator>>(istream &in, vector<T> &v) {
  for (auto &x : v)
    in >> x;
  return in;
}

template <typename T1, typename T2>
ostream &operator<<(ostream &out, const std::pair<T1, T2> &p) {
  out << "[" << p.first << ", " << p.second << "]"
      << "\\n";
  return out;
}

template <class T1, class T2> inline bool chmin(T1 &a, T2 b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

template <class T1, class T2> inline bool chmax(T1 &a, T2 b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

// repetition
//------------------------------------------
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define RFOR(i, a, b) for (int i = (b)-1; i >= (a); --i)
#define REP(i, n) FOR(i, 0, n)
#define RREP(i, n) for (int i = n - 1; i >= 0; i--)
#define FORLL(i, a, b) for (LL i = LL(a); i < LL(b); ++i)
#define RFORLL(i, a, b) for (LL i = LL(b) - 1; i >= LL(a); --i)
#define REPLL(i, n) for (LL i = 0; i < LL(n); ++i)
#define RREPLL(i, n) for (LL i = LL(n) - 1; i >= 0; --i)
#define FOREACH(x, arr) for (auto &(x) : (arr))

//------------------------------------------
//------------------------------------------

template <int_fast64_t Modulas = 1000000007ul> class ModInt {
  using u64 = int_fast64_t;

public:
  u64 x;

  constexpr ModInt() : x(0) {}
  constexpr ModInt(int_fast64_t v) : x((v % Modulas + Modulas) % Modulas) {}
  constexpr ModInt operator+(const ModInt rhs) const noexcept {
    return ModInt(*this) += rhs;
  }
  constexpr ModInt operator-(const ModInt rhs) const noexcept {
    return ModInt(*this) -= rhs;
  }
  constexpr ModInt operator*(const ModInt rhs) const noexcept {
    return ModInt(*this) *= rhs;
  }
  constexpr ModInt operator/(const ModInt rhs) const noexcept {
    return ModInt(*this) /= rhs;
  }
  constexpr ModInt operator/(const long long rhs) const noexcept {
    return ModInt(*this) /= rhs;
  }
  constexpr ModInt operator+=(const ModInt rhs) noexcept {
    x += rhs.x;
    if (x >= Modulas)
      x -= Modulas;
    return *this;
  }
  constexpr ModInt operator+=(const long long rhs) noexcept {
    auto hs = ModInt<Modulas>(rhs);
    (*this) += hs;
    return *this;
  }
  constexpr ModInt operator-=(const ModInt rhs) noexcept {
    if (x < rhs.x)
      x += Modulas;
    x -= rhs.x;
    return *this;
  }
  constexpr ModInt operator-=(const long long rhs) noexcept {
    auto hs = ModInt<Modulas>(rhs);
    (*this) -= hs;
    return *this;
  }
  constexpr ModInt operator*=(const ModInt rhs) noexcept {
    x = x * rhs.x % Modulas;
    return *this;
  }
  constexpr ModInt operator*=(const long long rhs) noexcept {
    auto hs = ModInt<Modulas>(rhs);
    (*this) *= hs;
    return *this;
  }
  constexpr ModInt &operator/=(ModInt rhs) noexcept {
    u64 exp = Modulas - 2;
    while (exp > 0) {
      if (exp & 1ul)
        *this *= rhs;
      rhs *= rhs;
      exp >>= 1ul;
    }
    return *this;
  }
  constexpr ModInt &operator/=(long long rhs) noexcept {
    auto hs = ModInt<Modulas>(rhs);
    (*this) /= hs;
    return *this;
  }

  constexpr ModInt &operator++() noexcept {
    x++;
    if (x >= Modulas)
      x -= Modulas;
    return *this;
  }
  constexpr ModInt &operator--() noexcept {
    if (x == 0)
      x += Modulas;
    x--;
    return *this;
  }
  constexpr bool operator<(const ModInt rhs) const noexcept {
    return x < rhs.x;
  }
  constexpr bool operator==(const ModInt rhs) const noexcept {
    return this->x == rhs.x;
  }
  constexpr bool operator!=(const ModInt rhs) const noexcept {
    return !(*this == rhs);
  }
  friend istream &operator>>(istream &in, ModInt &m) {
    in >> m.x;
    if (m.x < 0)
      m.x += Modulas;
    m.x %= Modulas;
    return in;
  }
  friend ostream &operator<<(ostream &out, const ModInt &p) {
    out << p.x;
    return out;
  }
  constexpr ModInt pow(u64 p) const {
    ModInt ret(1);
    ModInt mul(x);
    while (p > 0) {
      if (p & 1ul)
        ret *= mul;
      mul *= mul;
      p >>= 1ul;
    }
    return ret;
  }
  constexpr ModInt operator~() const noexcept {
    u64 exp = Modulas - 2;
    return pow(exp);
  }

  constexpr static ModInt arith_sum(ModInt<Modulas> a, ModInt<Modulas> d,
                                    ModInt<Modulas> n) noexcept {
    return (a * ModInt<Modulas>(2) + (n - 1) * d) * n / ModInt<Modulas>(2);
  }
};

template <class T> struct BI_COMB {
  vector<T> fact_, inv_;
  constexpr BI_COMB() {}
  constexpr BI_COMB(long long n) : fact_(n, 1), inv_(n, 1) { init(n); }
  constexpr void init(int n) {
    fact_.assign(n, 1);
    inv_.assign(n, 1);
    for (long long i = 2; i < n; i++) {
      fact_[i] = fact_[i - 1] * i;
      inv_[i] = ~fact_[i];
    }
  }
  constexpr T comb(int n, int r) {
    if (n < r || n < 0 || r < 0)
      return 0;
    return fact_[n] * inv_[r] * inv_[n - r];
  }
  constexpr T fact(int n) {
    if (n < 0)
      return 0;
    return fact_[n];
  }
  constexpr T inv(int n) {
    if (n < 0)
      return 0;
    return inv_[n];
  }
};

template <class T> class ReRooting {

private:
  int N;

  // G[i][j]
  // 頂点iのj番目に隣接している頂点
  vector<vector<int>> G;

  // idxs[i][j]
  // G[i][j]頂点(頂点iのj番目に隣接している頂点)からみて、頂点iは何番目か
  vector<vector<int>> idxs;

  // result[i]
  // 頂点iからの答え
  vector<T> result;

  // dp[i][j]
  // 頂点iを親としたとき
  // 頂点iに番目につながっている部分木G[i][j]以降の答え
  vector<vector<T>> dp;

  T identity;

  // func(x, y)
  // 値x,yを処理するモノイド
  function<T(T, T)> func;

  // add_node(x, u)
  // 頂点uを根付き木としたときその子供のモノイドを計算した後の最後の一手
  // u自体を加えるイメージ
  function<T(T, int)> add_node;

public:
  ReRooting(int N, vector<pair<int, int>> &edges, T identity,
            function<T(T, T)> func, function<T(T, int)> add_node)
      : N(N), identity(identity), func(func), add_node(add_node) {

    G = vector<vector<int>>(N);
    idxs = vector<vector<int>>(N);

    for (auto &&e : edges) {
      int f = e.first;
      int t = e.second;
      idxs[f].push_back(G[t].size());
      idxs[t].push_back(G[f].size());
      G[f].push_back(t);
      G[t].push_back(f);
    }

    dp = vector<vector<T>>(N);
    result = vector<T>(N);
    for (int i = 0; i < N; i++)
      dp[i] = vector<T>(G[i].size());

    if (N > 1)
      reroot();
    else if (N == 1)
      result[0] = add_node(identity, 0);
  }

  T query(int v) { return result[v]; }

private:
  void reroot() {

    // parent[i] = iの親頂点
    vector<int> parent(N);

    // order[i] = 行きがけ順でi番目に訪れた頂点
    vector<int> order;

    // region init_ordered_tree

    stack<int> stk;
    stk.push(0);
    parent[0] = -1;
    while (!stk.empty()) {
      auto v = stk.top();
      stk.pop();
      order.push_back(v);
      for (auto to : G[v]) {
        if (to == parent[v])
          continue;
        stk.push(to);
        parent[to] = v;
      }
    }
    // endregion

    // region from_leaf (bottom-up)

    for (int i = N - 1; i >= 1; i--) {
      auto v = order[i];
      auto p = parent[v];

      // 親pとする部分木vの答え
      T aum = identity;

      // vの親pがvに何番目で隣接しているか
      int p_idx = -1;

      for (int j = 0; j < G[v].size(); j++) {
        if (G[v][j] == p) {
          p_idx = j;
          continue;
        }
        aum = func(aum, dp[v][j]);
      }

      // 親pにとって、頂点vはidxs[v][p_idx]番目にある
      dp[p][idxs[v][p_idx]] = add_node(aum, v);
    }
    // endregion

    // region to_leaf(top-down)
    for (int i = 0; i < N; i++) {
      auto v = order[i];
      T aum = identity;

      // tails[i]
      // 頂点vの最後から 先頭から数えてi番目に隣接している頂点までの値
      vector<T> tails(G[v].size());
      tails.back() = identity;

      for (int j = tails.size() - 1; j >= 1; j--)
        tails[j - 1] = func(dp[v][j], tails[j]);
      for (int j = 0; j < tails.size(); j++) {
        dp[G[v][j]][idxs[v][j]] = add_node(func(aum, tails[j]), v);
        aum = func(aum, dp[v][j]);
      }

      result[v] = add_node(aum, v);
    }
    // endregion
  }
};

struct DP {
  ModInt<> m = 1;
  int d = 0;
  DP() {}
  DP(ModInt<> m, int d) : m(m), d(d) {}
};

constexpr int MAX = 400010;

int main() {

  int N;
  cin >> N;

  BI_COMB<ModInt<>> biComb(MAX);

  vector<pair<int, int>> ab(N - 1);

  REP(i, N - 1) {
    int a, b;
    cin >> a >> b;
    a--, b--;
    ab[i] = make_pair(a, b);
  }

  ReRooting<DP> reRooting(
      N, ab, DP(),
      [&](DP dp1, DP dp2) -> DP {
        int d = dp1.d + dp2.d;
        return DP(dp1.m * dp2.m * biComb.fact(d) / biComb.fact(dp1.d) /
                      biComb.fact(dp2.d),
                  d);
      },
      [&](DP dp, int v) -> DP { return DP(dp.m, dp.d + 1); });

  for (int i = 0; i < N; i++)
    cout << reRooting.query(i).m << endl;
}


Error: 0

Fixed submission:

// include
//------------------------------------------
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <locale>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

// typedef
//------------------------------------------
typedef long long LL;
typedef vector<int> VI;
typedef vector<bool> VB;
typedef vector<char> VC;
typedef vector<double> VD;
typedef vector<string> VS;
typedef vector<LL> VLL;
typedef vector<VI> VVI;
typedef vector<VB> VVB;
typedef vector<VS> VVS;
typedef vector<VLL> VVLL;
typedef vector<VVI> VVVI;
typedef vector<VVLL> VVVLL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef pair<int, string> PIS;
typedef pair<string, int> PSI;
typedef pair<string, string> PSS;
typedef vector<PII> VPII;
typedef vector<PLL> VPLL;
typedef vector<VPII> VVPII;
typedef vector<VPLL> VVPLL;
typedef vector<VS> VVS;
typedef map<int, int> MII;
typedef map<LL, LL> MLL;
typedef map<string, int> MSI;
typedef map<int, string> MIS;

// container util
//------------------------------------------
#define ALL(a) (a).begin(), (a).end()
#define SZ(a) int((a).size())
#define EACH(i, arr)                                                           \\
  for (typeof((arr).begin()) i = (arr).begin(); i != (arr).end(); ++i)
#define EXIST(str, e) ((str).find(e) != (str).end())
#define COUNT(arr, v) count((arr).begin(), (arr).end(), v)
#define SEARCH(v, w) search((v).begin(), (v).end(), (w).begin(), (w).end())
#define SORT(c) sort((c).begin(), (c).end())
#define RSORT(c) sort((c).rbegin(), (c).rend())
#define REVERSE(c) reverse((c).begin(), (c).end())
#define ROTATE_LEFT(arr, c)                                                    \\
  rotate((arr).begin(), (arr).begin() + (c), (arr).end())
#define ROTATE_RIGHT(arr, c)                                                   \\
  rotate((arr).rbegin(), (arr).rbegin() + (c), (arr).rend())
#define SUMI(arr) accumulate((arr).begin(), (arr).end(), 0)
#define SUMD(arr) accumulate((arr).begin(), (arr).end(), 0.)
#define SUMLL(arr) accumulate((arr).begin(), (arr).end(), 0LL)
#define MULD(arr)                                                              \\
  accumulate((arr).begin(), (arr).end(), 1., multiplies<double>())
#define UB(arr, n) upper_bound((arr).begin(), (arr).end(), n)
#define LB(arr, n) lower_bound((arr).begin(), (arr).end(), n)
#define PB push_back
#define MP make_pair
#define ft first
#define sd second

// input output
//------------------------------------------
#define GL(s) getline(cin, (s))
#define INIT()                                                                 \\
  std::ios::sync_with_stdio(false);                                            \\
  std::cin.tie(0)
#define OUT(d) std::cout << (d)
#define OUT_L(d) std::cout << (d) << endl
#define FOUT(n, data) std::cout << std::fixed << std::setprecision(n) << (data)
#define FOUT_L(n, data)                                                        \\
  std::cout << std::fixed << std::setprecision(n) << (data) << "\\n"
#define EL() printf("\\n")
#define SHOW_VECTOR(v)                                                         \\
  {                                                                            \\
    std::cerr << #v << "\\t:";                                                  \\
    for (const auto &xxx : v) {                                                \\
      std::cerr << xxx << " ";                                                 \\
    }                                                                          \\
    std::cerr << "\\n";                                                         \\
  }
#define SHOW_MAP(v)                                                            \\
  {                                                                            \\
    std::cerr << #v << endl;                                                   \\
    for (const auto &xxx : v) {                                                \\
      std::cerr << xxx.first << " " << xxx.second << "\\n";                     \\
    }                                                                          \\
  }
#define Yes() printf("Yes\\n")
#define No() printf("No\\n")
#define YES() printf("YES\\n")
#define NO() printf("NO\\n")
#define Yay() printf("Yay!\\n")
#define Nnn() printf(":(\\n")
#define CE(x, y) ((x + y - 1) / (y))

template <typename T1, typename T2>
istream &operator>>(istream &in, pair<T1, T2> &p) {
  in >> p.first >> p.second;
  return in;
}

template <typename T> istream &operator>>(istream &in, vector<T> &v) {
  for (auto &x : v)
    in >> x;
  return in;
}

template <typename T1, typename T2>
ostream &operator<<(ostream &out, const std::pair<T1, T2> &p) {
  out << "[" << p.first << ", " << p.second << "]"
      << "\\n";
  return out;
}

template <class T1, class T2> inline bool chmin(T1 &a, T2 b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

template <class T1, class T2> inline bool chmax(T1 &a, T2 b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

// repetition
//------------------------------------------
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define RFOR(i, a, b) for (int i = (b)-1; i >= (a); --i)
#define REP(i, n) FOR(i, 0, n)
#define RREP(i, n) for (int i = n - 1; i >= 0; i--)
#define FORLL(i, a, b) for (LL i = LL(a); i < LL(b); ++i)
#define RFORLL(i, a, b) for (LL i = LL(b) - 1; i >= LL(a); --i)
#define REPLL(i, n) for (LL i = 0; i < LL(n); ++i)
#define RREPLL(i, n) for (LL i = LL(n) - 1; i >= 0; --i)
#define FOREACH(x, arr) for (auto &(x) : (arr))

//------------------------------------------
//------------------------------------------

template <int_fast64_t Modulas = 1000000007ul> class ModInt {
  using u64 = int_fast64_t;

public:
  u64 x;

  constexpr ModInt() : x(0) {}
  constexpr ModInt(int_fast64_t v) : x((v % Modulas + Modulas) % Modulas) {}
  constexpr ModInt operator+(const ModInt rhs) const noexcept {
    return ModInt(*this) += rhs;
  }
  constexpr ModInt operator-(const ModInt rhs) const noexcept {
    return ModInt(*this) -= rhs;
  }
  constexpr ModInt operator*(const ModInt rhs) const noexcept {
    return ModInt(*this) *= rhs;
  }
  constexpr ModInt operator/(const ModInt rhs) const noexcept {
    return ModInt(*this) /= rhs;
  }
  constexpr ModInt operator/(const long long rhs) const noexcept {
    return ModInt(*this) /= rhs;
  }
  constexpr ModInt operator+=(const ModInt rhs) noexcept {
    x += rhs.x;
    if (x >= Modulas)
      x -= Modulas;
    return *this;
  }
  constexpr ModInt operator+=(const long long rhs) noexcept {
    auto hs = ModInt<Modulas>(rhs);
    (*this) += hs;
    return *this;
  }
  constexpr ModInt operator-=(const ModInt rhs) noexcept {
    if (x < rhs.x)
      x += Modulas;
    x -= rhs.x;
    return *this;
  }
  constexpr ModInt operator-=(const long long rhs) noexcept {
    auto hs = ModInt<Modulas>(rhs);
    (*this) -= hs;
    return *this;
  }
  constexpr ModInt operator*=(const ModInt rhs) noexcept {
    x = x * rhs.x % Modulas;
    return *this;
  }
  constexpr ModInt operator*=(const long long rhs) noexcept {
    auto hs = ModInt<Modulas>(rhs);
    (*this) *= hs;
    return *this;
  }
  constexpr ModInt &operator/=(ModInt rhs) noexcept {
    u64 exp = Modulas - 2;
    while (exp > 0) {
      if (exp & 1ul)
        *this *= rhs;
      rhs *= rhs;
      exp >>= 1ul;
    }
    return *this;
  }
  constexpr ModInt &operator/=(long long rhs) noexcept {
    auto hs = ModInt<Modulas>(rhs);
    (*this) /= hs;
    return *this;
  }

  constexpr ModInt &operator++() noexcept {
    x++;
    if (x >= Modulas)
      x -= Modulas;
    return *this;
  }
  constexpr ModInt &operator--() noexcept {
    if (x == 0)
      x += Modulas;
    x--;
    return *this;
  }
  constexpr bool operator<(const ModInt rhs) const noexcept {
    return x < rhs.x;
  }
  constexpr bool operator==(const ModInt rhs) const noexcept {
    return this->x == rhs.x;
  }
  constexpr bool operator!=(const ModInt rhs) const noexcept {
    return !(*this == rhs);
  }
  friend istream &operator>>(istream &in, ModInt &m) {
    in >> m.x;
    if (m.x < 0)
      m.x += Modulas;
    m.x %= Modulas;
    return in;
  }
  friend ostream &operator<<(ostream &out, const ModInt &p) {
    out << p.x;
    return out;
  }
  constexpr ModInt pow(u64 p) const {
    ModInt ret(1);
    ModInt mul(x);
    while (p > 0) {
      if (p & 1ul)
        ret *= mul;
      mul *= mul;
      p >>= 1ul;
    }
    return ret;
  }
  constexpr ModInt operator~() const noexcept {
    u64 exp = Modulas - 2;
    return pow(exp);
  }

  constexpr static ModInt arith_sum(ModInt<Modulas> a, ModInt<Modulas> d,
                                    ModInt<Modulas> n) noexcept {
    return (a * ModInt<Modulas>(2) + (n - 1) * d) * n / ModInt<Modulas>(2);
  }
};

template <class T> struct BI_COMB {
  vector<T> fact_, inv_;
  constexpr BI_COMB() {}
  constexpr BI_COMB(long long n) : fact_(n, 1), inv_(n, 1) { init(n); }
  constexpr void init(int n) {
    fact_.assign(n, 1);
    inv_.assign(n, 1);
    for (long long i = 2; i < n; i++) {
      fact_[i] = fact_[i - 1] * i;
      inv_[i] = ~fact_[i];
    }
  }
  constexpr T comb(int n, int r) {
    if (n < r || n < 0 || r < 0)
      return 0;
    return fact_[n] * inv_[r] * inv_[n - r];
  }
  constexpr T fact(int n) {
    if (n < 0)
      return 0;
    return fact_[n];
  }
  constexpr T inv(int n) {
    if (n < 0)
      return 0;
    return inv_[n];
  }
};

template <class T> class ReRooting {

private:
  int N;

  // G[i][j]
  // 頂点iのj番目に隣接している頂点
  vector<vector<int>> G;

  // idxs[i][j]
  // G[i][j]頂点(頂点iのj番目に隣接している頂点)からみて、頂点iは何番目か
  vector<vector<int>> idxs;

  // result[i]
  // 頂点iからの答え
  vector<T> result;

  // dp[i][j]
  // 頂点iを親としたとき
  // 頂点iに番目につながっている部分木G[i][j]以降の答え
  vector<vector<T>> dp;

  T identity;

  // func(x, y)
  // 値x,yを処理するモノイド
  function<T(T, T)> func;

  // add_node(x, u)
  // 頂点uを根付き木としたときその子供のモノイドを計算した後の最後の一手
  // u自体を加えるイメージ
  function<T(T, int)> add_node;

public:
  ReRooting(int N, vector<pair<int, int>> &edges, T identity,
            function<T(T, T)> func, function<T(T, int)> add_node)
      : N(N), identity(identity), func(func), add_node(add_node) {

    G = vector<vector<int>>(N);
    idxs = vector<vector<int>>(N);

    for (auto &&e : edges) {
      int f = e.first;
      int t = e.second;
      idxs[f].push_back(G[t].size());
      idxs[t].push_back(G[f].size());
      G[f].push_back(t);
      G[t].push_back(f);
    }

    dp = vector<vector<T>>(N, vector<T>(N));
    result = vector<T>(N);

    if (N > 1)
      reroot();
    else if (N == 1)
      result[0] = add_node(identity, 0);
  }

  T query(int v) { return result[v]; }

private:
  void reroot() {

    // parent[i] = iの親頂点
    vector<int> parent(N);

    // order[i] = 行きがけ順でi番目に訪れた頂点
    vector<int> order;

    // region init_ordered_tree

    stack<int> stk;
    stk.push(0);
    parent[0] = -1;
    while (!stk.empty()) {
      auto v = stk.top();
      stk.pop();
      order.push_back(v);
      for (auto to : G[v]) {
        if (to == parent[v])
          continue;
        stk.push(to);
        parent[to] = v;
      }
    }
    // endregion

    // region from_leaf (bottom-up)

    for (int i = N - 1; i >= 1; i--) {
      auto v = order[i];
      auto p = parent[v];

      // 親pとする部分木vの答え
      T aum = identity;

      // vの親pがvに何番目で隣接しているか
      int p_idx = -1;

      for (int j = 0; j < G[v].size(); j++) {
        if (G[v][j] == p) {
          p_idx = j;
          continue;
        }
        aum = func(aum, dp[v][j]);
      }

      // 親pにとって、頂点vはidxs[v][p_idx]番目にある
      dp[p][idxs[v][p_idx]] = add_node(aum, v);
    }
    // endregion

    // region to_leaf(top-down)
    for (int i = 0; i < N; i++) {
      auto v = order[i];
      T aum = identity;

      // tails[i]
      // 頂点vの最後から 先頭から数えてi番目に隣接している頂点までの値
      vector<T> tails(G[v].size());
      tails.back() = identity;

      for (int j = tails.size() - 1; j >= 1; j--)
        tails[j - 1] = func(dp[v][j], tails[j]);
      for (int j = 0; j < tails.size(); j++) {
        dp[G[v][j]][idxs[v][j]] = add_node(func(aum, tails[j]), v);
        aum = func(aum, dp[v][j]);
      }

      result[v] = add_node(aum, v);
    }
    // endregion
  }
};

struct DP {
  ModInt<> m = 1;
  int d = 0;
  DP() {}
  DP(ModInt<> m, int d) : m(m), d(d) {}
};

constexpr int MAX = 400010;

int main() {

  int N;
  cin >> N;

  BI_COMB<ModInt<>> biComb(MAX);

  vector<pair<int, int>> ab(N - 1);

  REP(i, N - 1) {
    int a, b;
    cin >> a >> b;
    a--, b--;
    ab[i] = make_pair(a, b);
  }

  ReRooting<DP> reRooting(
      N, ab, DP(),
      [&](DP dp1, DP dp2) -> DP {
        int d = dp1.d + dp2.d;
        return DP(dp1.m * dp2.m * biComb.fact(d) / biComb.fact(dp1.d) /
                      biComb.fact(dp2.d),
                  d);
      },
      [&](DP dp, int v) -> DP { return DP(dp.m, dp.d + 1); });

  for (int i = 0; i < N; i++)
    cout << reRooting.query(i).m << endl;
}