// Slower C++ solution:
#pragma GCC optimize("O3")

#include <bits/stdc++.h>

#define ll long long

#define rep(i,n) for(ll i=0;i<(n);i++)

#define pll pair<ll,ll>

#define pq priority_queue

#define pb push_back

#define eb emplace_back

#define fi first

#define se second

#define ios ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);

#define lb(c,x) distance(c.begin(),lower_bound(all(c),x))

#define ub(c,x) distance(c.begin(),upper_bound(all(c),x))



using namespace std;



template<class T> inline bool chmax(T& a,T b){if(a<b){a=b;return 1;}return 0;}

template<class T> inline bool chmin(T& a,T b){if(a>b){a=b;return 1;}return 0;}



const ll mod=1e9+7;



ll n, m, x, y;

vector<ll> edge[110000];

ll dp1[110000];

ll dp2[110000];



void dfs1(ll x, ll last = -1){

    ll prod= 1;

    for(auto to:edge[x]){

        if(to == last)continue;

        dfs1(to, x);

        prod = prod * dp1[to] % m;

    }

    dp1[x] = prod + 1;

}



void dfs2(ll x, ll last = -1){

    if(last == -1)dp2[x] = 1;

    vector<ll> lprod= vector<ll>(edge[x].size(), 1);

    vector<ll> rprod= vector<ll>(edge[x].size(), 1);

    for(ll i = 0;i < edge[x].size();i++){

        ll to = edge[x][i];

        if(i-1 >= 0)lprod[i] = lprod[i-1];

        if(to == last)continue;

        lprod[i] *= dp1[to];lprod[i] %= m;

    }

    for(ll i = (ll)edge[x].size() - 1;i >= 0;i--){

        ll to = edge[x][i];

        if(i+1 < rprod.size())rprod[i] = rprod[i+1];

        if(to == last)continue;

        rprod[i] *= dp1[to];rprod[i] %= m;

    }

    for(ll i = 0;i < edge[x].size();i++){

        ll to = edge[x][i];

        if(to == last)continue;

        ll rest_prod = 1;

        if(i-1 >= 0)rest_prod = rest_prod * lprod[i-1] % m;

        if(i+1 < rprod.size())rest_prod = rest_prod * rprod[i+1] % m;

        dp2[to] = (dp2[x] * rest_prod + 1) % m;

        dfs2(to, x);

    }

}



ll ans[110000];



void dfs3(ll x, ll last = -1){

    ans[x] = dp2[x];

    for(auto to:edge[x]){

        if(to == last)continue;

        ans[x] *= dp1[to];

        ans[x] %= m;

        dfs3(to, x);

    }

}



int main(){

    cin >> n >> m;

    for(ll i = 0;i < n-1;i++){

        cin >> x >> y;

        edge[x].push_back(y);

        edge[y].push_back(x);

    }



    dfs1(1);

    dfs2(1);

    dfs3(1);



    for(ll i = 1;i <= n;i++){

        cout << ans[i] << endl;

    }

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 3.745670055557551x):
#pragma GCC optimize("O3")

#include <bits/stdc++.h>

#define ll long long

#define rep(i,n) for(ll i=0;i<(n);i++)

#define pll pair<ll,ll>

#define pii pair<int,int>

#define pq priority_queue

#define pb push_back

#define eb emplace_back

#define fi first

#define se second

#define endl '\n'

#define ios ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);

#define lb(c,x) distance(c.begin(),lower_bound(all(c),x))

#define ub(c,x) distance(c.begin(),upper_bound(all(c),x))



using namespace std;





template <typename T>

struct ReRooting

{

  using F = function<T(T, int)>;

  using F2 = function<T(T, T)>;

  int V;

  vector<vector<int>> E;

  vector<vector<T>> dp;

  //dp_v = g(merge(f(dp_c1,c1), f(dp_c2,c2), ..., f(dp_ck,ck)) , v)

  F f, g;

  F2 merge;

  T mi; //identity of merge

 

  ReRooting(int V_, F f_, F2 merge_, T mi_, F g_ = [](T a, int b) { return a; })

      : V(V_), f(f_), merge(merge_), mi(mi_), g(g_)

  {

    E.resize(V);

    dp.resize(V);

  }

 

  void add_E(int a, int b) //辺を追加

  {

    E[a].push_back(b);

    E[b].push_back(a);

  }

 

  T dfs1(int p, int v)

  {

    T res = mi;

    for (int i = 0; i < E[v].size(); ++i)

    {

      if (E[v][i] == p)

        continue;

      dp[v][i] = dfs1(v, E[v][i]);

      res = merge(res, f(dp[v][i], E[v][i]));

    }

    return g(res, v);

  }

 

  void dfs2(int p, int v, T add)

  {

    for (int i = 0; i < E[v].size(); ++i)

    {

      if (E[v][i] == p)

      {

        dp[v][i] = add;

        break;

      }

    }

 

    vector<T> pL(E[v].size() + 1), pR(E[v].size() + 1);

    pL[0] = mi;

    for (int i = 0; i < E[v].size(); ++i)

      pL[i + 1] = merge(pL[i], f(dp[v][i], E[v][i]));

    pR[E[v].size()] = mi;

    for (int i = E[v].size(); i > 0; --i)

      pR[i - 1] = merge(pR[i], f(dp[v][i - 1], E[v][i - 1]));

 

    for (int i = 0; i < E[v].size(); ++i)

    {

      if (E[v][i] == p)

        continue;

      T val = merge(pL[i], pR[i + 1]);

      dfs2(v, E[v][i], g(val, v));

    }

  }

 

  void calc(int root = 0) //根を頂点0とした前計算

  {

    for (int i = 0; i < V; ++i)

      dp[i].resize(E[i].size());

    dfs1(-1, root);

    dfs2(-1, root, mi);

  }

 

  T solve(int v) //根を頂点vとしたときの解を得る

  {

    T ans = mi;

    for (int i = 0; i < E[v].size(); ++i)

    {

      ans = merge(ans, f(dp[v][i], E[v][i]));

    }

    return g(ans, v);

  }

};





int main(){

    int n,m;

    cin >> n >> m;

    auto f=[&](ll a,int v){

        return (a+1)%m;

    };

    auto merge=[&](ll a,ll b){

        return a*b%m;

    };

    ReRooting<ll> re(n,f,merge,1);

    rep(i,n-1){

        int x,y;

        cin >> x >> y;

        x--; y--;

        re.add_E(x,y);

    }

    re.calc();

    rep(i,n){

        cout << re.solve(i) << endl;

    }

    return 0;

}