#include <bits/stdc++.h>
using namespace std;
#define _GLIBCXX_DEBUG
#define rep2(i, m, n) for(int i=int(m); i<int(n); ++i)
#define drep2(i, m, n) for(int i=int(m-1); i>=int(n); --i)
#define rep(i, n) rep2(i, 0, n)
#define drep(i, n) drep2(i, n, 0)
#define all(a) a.begin(), a.end()
#define fst first
#define snd second
using ll = long long;
using ld = long double;
using V = vector<int>;
using Vll = vector<ll>;
using Vld = vector<ld>;
using VV = vector<V>;
using VVll = vector<Vll>;
using VVld = vector<Vld>;
using P = pair<int, int>;
using Pll = pair<ll, ll>;
using Pld = pair<ld, ld>;
const int INF = 1<<30;
const ll INFll = 1ll<<62;
const ld EPS = 1e-10;
// const int MOD = int(1e9)+7;
template<typename T> inline bool chmin(T& a, T b) {if(a>b) {a=b; return true;} return false;}
template<typename T> inline bool chmax(T& a, T b) {if(a<b) {a=b; return true;} return false;}
template<typename T> inline int Log2(T& x) {int k; for(k=0; (T(1)<<k)<=x; ++k); return k;} // number of binary digits

int MOD;
struct mint {
  ll x;
  mint(ll x=0):x((x%MOD+MOD)%MOD){}
  mint operator-() const { return mint(-x);}
  mint& operator+=(const mint a) {
    if ((x += a.x) >= MOD) x -= MOD;
    return *this;
  }
  mint& operator-=(const mint a) {
    if ((x += MOD-a.x) >= MOD) x -= MOD;
    return *this;
  }
  mint& operator*=(const mint a) { (x *= a.x) %= MOD; return *this;}
  mint operator+(const mint a) const { return mint(*this) += a;}
  mint operator-(const mint a) const { return mint(*this) -= a;}
  mint operator*(const mint a) const { return mint(*this) *= a;}
  mint pow(ll t) const {
    if (!t) return 1;
    mint a = pow(t>>1);
    a *= a;
    if (t&1) a *= *this;
    return a;
  }
  mint& operator/=(const mint r) {
    ll a = r.x, b = MOD, u = 1, v = 0;
    while (b) {
      ll t = a / b;
      a -= t * b; swap(a, b);
      u -= t * v; swap(u, v);
    }
    x = x * u % MOD;
    if (x < 0) x += MOD;
    return *this;
  }
  mint operator/(const mint a) const { return mint(*this) /= a;}
};
istream& operator>>(istream& is, const mint& a) { return is >> a.x;}
ostream& operator<<(ostream& os, const mint& a) { return os << a.x;}


// DP
template<typename T>
struct rerooting_dp {
  struct edge {
    int v; T dp_sub;
    edge(int v) : v(v) {}
  };

  using Edges = vector<edge>;
  using Graph = vector<Edges>;
  Graph G;
  const T ident;
  vector<T> dp;

  using Fm = function<T(T, T)>;
  using Ft = function<T(T)>;
  const Fm f_merge;
  const Ft f_trans;

  rerooting_dp(int N, const T &ident, const Fm fm, const Ft ft)
    : G(N), ident(ident), dp(N, ident), f_merge(fm), f_trans(ft) {}

  void add_edge(int u, int v) {
    G[u].push_back(edge(v));
    G[v].push_back(edge(u));
  }

  T dfs(int u, int p=-1) {
    T res = ident;
    int d = G[u].size();
    for (auto &e : G[u]) {
      if (e.v == p) continue;
      e.dp_sub = dfs(e.v, u);
      res = f_merge(res, e.dp_sub);
    }
    return f_trans(res);
  }

  void dfs2(int u, T par, int p=-1) {
    int d = G[u].size();
    rep(i, d) if (G[u][i].v == p) G[u][i].dp_sub = par;

    for (auto &e : G[u]) dp[u] = f_merge(dp[u], e.dp_sub);

    vector<T> res_l(d+1, ident), res_r(d+1, ident);
    rep(i, d)  res_l[i+1] = f_merge(res_l[i], G[u][i].dp_sub);
    drep(i, d) res_r[i] = f_merge(res_r[i+1], G[u][i].dp_sub);

    rep(i, d) {
      auto e = G[u][i];
      if (e.v == p) continue;
      dfs2(e.v, f_trans(f_merge(res_l[i], res_r[i+1])), u);
    }
  }

  vector<T> build() {
    dfs(0);
    dfs2(0, ident);
    return dp;
  }
};


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

  auto f_merge = [&] (mint a, mint b) {
    return a*b;
  };
  auto f_trans = [&] (mint a) {
    return a+1;
  };

  rerooting_dp<mint> G(N, mint(1), f_merge, f_trans);

  for (int i = 0; i < N-1; ++i) {
    int a, b;
    cin >> a >> b;
    a--; b--;
    G.add_edge(a, b);
  }
  
  auto dp = G.build();
  rep(i, N) cout << dp[i] << endl;
  return 0;
}


Measured memory_bytes: 30976