/**
 * @brief 木 DP
 * @author えびちゃん
 */

#ifndef H_dp_on_tree
#define H_dp_on_tree

#include <cstddef>
#include <queue>
#include <vector>

template <typename Monoid, typename AdjacencyList, typename Fn>
std::vector<Monoid> dp_on_tree(AdjacencyList const& g, Fn f, Monoid e = Monoid{}) {
  size_t n = g.size();
  std::vector<size_t> ord, par(n, n);
  std::vector<bool> vis(n, false);
  ord.reserve(n);
  vis[0] = true;
  std::queue<size_t> q;
  q.push(0);
  while (!q.empty()) {
    size_t v = q.front();
    q.pop();
    ord.push_back(v);
    for (auto const& e: g[v]) {
      size_t u = e.target();
      if (!vis[u]) {
        vis[u] = true;
        par[u] = v;
        q.push(u);
      }
    }
  }

  std::vector<Monoid> dpl(n, e), dpr(n, e), dpp(n, e);
  for (size_t i = n; i--;) {
    size_t v = ord[i];
    bool bef = true;
    for (size_t j = 0; j < g[v].size(); ++j) {
      auto const& e = g[v][j];
      size_t u = e.target();
      auto w = e.weight();
      if (u == par[v]) {
        bef = true;
      } else if (bef) {
        dpl[v] += f(dpl[u] + dpr[u], w);
      } else {
        dpr[v] = f(dpl[u] + dpr[u], w) + std::move(dpr[v]);
      }
    }
  }

  std::vector<Monoid> dp(n);
  for (size_t i = 0; i < n; ++i) {
    size_t v = ord[i];
    std::vector<Monoid> al(g[v].size());
    for (size_t j = 0; j < g[v].size(); ++j) {
      auto const& e = g[v][j];
      size_t u = e.target();
      auto w = e.weight();
      al[j] = ((u == par[v])? dpp[v]: f(dpl[u] + dpr[u], w));
    }
    auto ar = al;
    al.insert(al.begin(), e);
    ar.push_back(e);
    for (size_t j = 1; j <= g[v].size(); ++j) al[j] = al[j-1] + std::move(al[j]);
    for (size_t j = g[v].size(); j--;) ar[j] += ar[j+1];
    for (size_t j = 0; j < g[v].size(); ++j) {
      auto const& e = g[v][j];
      size_t u = e.target();
      if (u == par[v]) continue;
      auto w = e.weight();
      dpp[u] = f(al[j] + ar[j+1], w);
    }
    dp[v] = ar[0];
  }
  return dp;
}

#endif  /* !defined(H_dp_on_tree) */

/**
 * @brief 重みつきグラフの隣接リスト
 * @author えびちゃん
 */

#ifndef H_adjacency_list
#define H_adjacency_list

#include <cstddef>
#include <algorithm>
#include <type_traits>
#include <vector>

template <typename WeightType>
class weighted_edge {
public:
  using size_type = size_t;
  using weight_type = WeightType;

protected:
  size_type M_src, M_dst;
  weight_type M_weight;

public:
  weighted_edge() = default;
  weighted_edge(weighted_edge const&) = default;
  weighted_edge(weighted_edge&&) = default;

  weighted_edge(size_type s, size_type d, weight_type w):
    M_src(s), M_dst(d), M_weight(w)
  {}

  weighted_edge& operator =(weighted_edge const&) = default;
  weighted_edge& operator =(weighted_edge&&) = default;

  bool operator <(weighted_edge const& other) const {
    if (M_weight < other.M_weight) return true;
    if (other.M_weight < M_weight) return false;
    if (M_src != other.M_src) return M_src < other.M_src;
    return M_dst < other.M_dst;
  }

  size_type source() const { return M_src; }
  size_type target() const { return M_dst; }
  weight_type weight() const { return M_weight; }
};

struct directed_tag {};
struct undirected_tag {};

template <typename Edge, typename Directedness>
class adjacency_list {
public:
  using size_type = size_t;
  using edge_type = Edge;
  using weight_type = typename Edge::weight_type;

private:
  std::vector<std::vector<edge_type>> M_g;

public:
  adjacency_list() = default;
  adjacency_list(adjacency_list const&) = default;
  adjacency_list(adjacency_list&&) = default;
  explicit adjacency_list(size_type n): M_g(n) {}

  template <typename... Args>
  void emplace(size_type src, size_type dst, Args... args) {
    M_g[src].emplace_back(src, dst, args...);
    if (std::is_same<Directedness, undirected_tag>::value)
      M_g[dst].emplace_back(dst, src, args...);
  }

  void sort_by_index() {
    auto cmp = [](auto const& e1, auto const& e2) {
      return e1.target() < e2.target();
    };
    for (auto v: M_g) std::sort(v.begin(), v.end(), cmp);
  }

  size_type size() const { return M_g.size(); }
  auto const& operator [](size_type i) const { return M_g[i]; }
};

#endif  /* !defined(H_adjacency_list) */

#include <cstdio>

template <typename Tp>
class mul_monoid {
public:
  using value_type = Tp;

private:
  value_type M_x;

public:
  mul_monoid() = default;  // identity
  mul_monoid(value_type x): M_x(x) {}

  mul_monoid& operator +=(mul_monoid that) { M_x *= that.M_x; return *this; }
  mul_monoid operator +(mul_monoid const& that) const { return mul_monoid(*this) += that; }

  value_type const& get() const { return M_x; }
};

/**
 * @brief 合同算術用クラス
 * @author えびちゃん
 */

#ifndef H_modint
#define H_modint

#include <cstdint>
#include <type_traits>
#include <utility>

template <intmax_t Modulo>
class modint {
public:
  using value_type = intmax_t;

private:
  static constexpr value_type S_mod = Modulo;
  value_type M_value = 0;
  value_type M_mod;  // runtime value (used if S_mod == 0)

  static constexpr value_type S_inv(value_type n, value_type m) {
    value_type x = 0;
    value_type y = 1;
    value_type a = n;
    value_type b = m;
    for (value_type u = y, v = x; a;) {
      value_type q = b / a;
      std::swap(x -= q*u, u);
      std::swap(y -= q*v, v);
      std::swap(b -= q*a, a);
    }
    if ((x %= m) < 0) x += m;
    return x;
  }

  static value_type S_normalize(value_type n, value_type m) {
    if (n >= m) {
      n %= m;
    } else if (n < 0) {
      if ((n %= m) < 0) n += m;
    }
    return n;
  }

public:
  modint() = default;
  modint(modint const&) = default;
  modint(modint&&) = default;
  template <typename Up = intmax_t, typename std::enable_if<(Modulo > 0), Up>::type* = nullptr>
  modint(value_type n):
    M_value(S_normalize(n, Modulo)) {}
  template <typename Up = intmax_t, typename std::enable_if<(Modulo == 0), Up>::type* = nullptr>
  modint(value_type n, value_type m):
    M_value(S_normalize(n, m)), M_mod(m) {}
  // copying runtime mod
  modint(value_type n, modint const& base):
    M_value(S_normalize(n, base.modulo())), M_mod(base.M_mod) {}

  modint& operator =(modint const&) = default;
  modint& operator =(modint&&) = default;
  modint& operator =(value_type n) {
    M_value = S_normalize(n, modulo());
    return *this;
  }

  modint& operator +=(modint const& that) {
    if ((M_value += that.M_value) >= modulo()) M_value -= modulo();
    return *this;
  }
  modint& operator -=(modint const& that) {
    if ((M_value -= that.M_value) < 0) M_value += modulo();
    return *this;
  }
  modint& operator *=(modint const& that) {
    (M_value *= that.M_value) %= modulo();
    return *this;
  }
  modint& operator /=(modint const& that) {
    (M_value *= S_inv(that.M_value, modulo())) %= modulo();
    return *this;
  }

  modint& operator +=(value_type const& n) {
    if ((M_value += S_normalize(n, modulo())) >= modulo()) M_value -= modulo();
    return *this;
  }
  modint& operator -=(value_type const& n) {
    if ((M_value -= S_normalize(n, modulo())) < 0) M_value += modulo();
    return *this;
  }
  modint& operator *=(value_type const& n) {
    (M_value *= S_normalize(n, modulo())) %= modulo();
    return *this;
  }
  modint& operator /=(value_type const& n) {
    (M_value *= S_inv(S_normalize(n, modulo()), modulo())) %= modulo();
    return *this;
  }

  modint operator +(modint const& that) const { return modint(*this) += that; }
  modint operator -(modint const& that) const { return modint(*this) -= that; }
  modint operator *(modint const& that) const { return modint(*this) *= that; }
  modint operator /(modint const& that) const { return modint(*this) /= that; }
  modint operator +(value_type const& n) const { return modint(*this) += n; }
  modint operator -(value_type const& n) const { return modint(*this) -= n; }
  modint operator *(value_type const& n) const { return modint(*this) *= n; }
  modint operator /(value_type const& n) const { return modint(*this) /= n; }

  modint operator +() const { return *this; }
  modint operator -() const {
    if (M_value == 0) return *this;
    return modint(modulo()-M_value, *this);
  }

  bool operator ==(modint const& that) const {
    return M_value == that.M_value;
  }
  bool operator ==(value_type const& n) const {
    return M_value == S_normalize(n, modulo());
  }
  bool operator !=(modint const& that) const { return !(*this == that); }
  bool operator !=(value_type const& n) const { return !(*this == n); }

  value_type get() const { return M_value; }
  value_type modulo() const { return ((S_mod > 0)? S_mod: M_mod); }
};

template <typename Tp, intmax_t Modulo>
modint<Modulo> operator +(Tp const& lhs, modint<Modulo> const& rhs) {
  return rhs + lhs;
}
template <typename Tp, intmax_t Modulo>
modint<Modulo> operator -(Tp const& lhs, modint<Modulo> const& rhs) {
  return -(rhs - lhs);
}
template <typename Tp, intmax_t Modulo>
modint<Modulo> operator *(Tp const& lhs, modint<Modulo> const& rhs) {
  return rhs * lhs;
}
template <typename Tp, intmax_t Modulo>
modint<Modulo> operator /(Tp const& lhs, modint<Modulo> const& rhs) {
  return modint<Modulo>(lhs, rhs) / rhs;
}
template <typename Tp, intmax_t Modulo>
bool operator ==(Tp const& lhs, modint<Modulo> const& rhs) {
  return rhs == lhs;
}
template <typename Tp, intmax_t Modulo>
bool operator !=(Tp const& lhs, modint<Modulo> const& rhs) {
  return !(lhs == rhs);
}

#ifndef CALL_FROM_TEST
// constexpr intmax_t mod = 1000'000'007;
// constexpr intmax_t mod = 998244353;
constexpr intmax_t mod = 0;
using mi = modint<mod>;
#endif

#endif  /* !defined(H_modint) */

int main() {
  size_t n;
  int m;
  scanf("%zu %d", &n, &m);

  adjacency_list<weighted_edge<int>, undirected_tag> g(n);
  for (size_t i = 1; i < n; ++i) {
    size_t a, b;
    scanf("%zu %zu", &a, &b);
    --a, --b;
    g.emplace(a, b, 1);
  }

  auto dp = dp_on_tree<mul_monoid<mi>>(g, [&](mul_monoid<mi> x, int) -> mul_monoid<mi> {
    return x.get() + mi(1, m);
  }, mi(1, m));

  for (size_t i = 0; i < n; ++i) {
    printf("%jd\n", dp[i].get().get());
  }
}


Measured memory_bytes: 23600