#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
 
using tpl = tuple<int, int, int>;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

void fastStream(){cin.tie(0);std::ios_base::sync_with_stdio(0);}


int N;
int mod;
pii es[100010];
vector<pii> G[100010];

ll dp1[100010];
ll dp2[100010][2];
int pars[100010];
vector<ll> muls[100100];
map<int, int> from_pos_to_graph_id[100100];


ll rec1(int pos, int par){
    if(dp1[pos] >= 0) return dp1[pos];
    pars[pos] = par;
    ll res = 0;
    // この頂点を黒でぬる場合
    {
        ll tmp = 1;
        for(pii p : G[pos]){
            int to = p.first;
            if(to == par) continue;        
            (tmp *= rec1(to, pos)) %= mod;
        }
        (res += tmp) %= mod;
    }
    // この頂点を白でぬる場合
    (res += 1) %= mod;
    return dp1[pos] = res;
}

ll rec2(int eid, int ang){ // angは0ならfirstにいるという意味
    if(dp2[eid][ang] >= 0) return dp2[eid][ang];
    ll res = 0;
    int pos = (ang == 0) ? es[eid].first : es[eid].second;
    int par = (ang == 1) ? es[eid].first : es[eid].second;

    // par方面だけ削除した結果を出して終了
    int par_graph_idx = from_pos_to_graph_id[pos][par];
    res = muls[pos][par_graph_idx];
    if(pos != 0){
        // par方面だけ削除して、本来のparの方向の結果を掛け算する
        int next_edge = G[pos][from_pos_to_graph_id[pos][pars[pos]]].second;
        // for(int i = 0; i < (int)G[pos].size(); i++){
        //     if(G[pos][i].first == pars[pos]){
        //         next_edge = G[pos][i].second;
        //         break;
        //     }
        // }
        (res *= rec2(next_edge, es[next_edge].first != pars[pos])) %= mod;
    }
    (res += 1) %= mod;
    return dp2[eid][ang] = res;
}

int main() {

    cin >> N >> mod;
    for(int i = 0; i < N - 1; i++){
        int x, y;
        cin >> x >> y;
        x--; y--;
        es[i] = pii(x, y);
        G[x].push_back(pii(y, i));
        G[y].push_back(pii(x, i));
    }
    memset(dp1, -1, sizeof(dp1));
    memset(dp2, -1, sizeof(dp2));

    /*
      最初に適当な根から値を計算する
      その次に、もし前ノードの位置が以前に計算した親ノードの位置でない場合、
      再計算を行う
     */
    cout << (rec1(0, -1) - 1 + mod) % mod<< endl;

    // 各ノードについて、親ノードを除いて、あるエッジ以外を除いた掛け算の結果を計算しておく
    vector<ll> prefix(N);
    vector<ll> suffix(N);
    for(int i = 0; i < N; i++){
        for(int j = 0; j < (int)G[i].size(); j++){
            ll a = (j - 1 >= 0 ? prefix[j - 1] : 1);
            ll b = ((G[i][j].first == pars[i]) ? 1 : rec1(G[i][j].first, -1));
            prefix[j] = (a * b) % mod;
        }
        for(int j = (int)G[i].size() - 1; j >= 0; j--){
            ll a = (j + 1 < (int)G[i].size() ? suffix[j + 1] : 1);
            ll b = (G[i][j].first == pars[i]) ? 1 : rec1(G[i][j].first, -1);
            suffix[j] = (a * b) % mod;
        }
        for(int j = 0; j < (int)G[i].size(); j++){
            ll a = (j - 1 >= 0) ? prefix[j - 1] : 1;
            ll b = (j + 1 < (int)G[i].size()) ? suffix[j + 1] : 1;
            muls[i].push_back((a * b) % mod);
        }
    }

    for(int i = 0; i < N; i++){
        for(int j = 0; j < (int)G[i].size(); j++){
            int to = G[i][j].first;
            from_pos_to_graph_id[i][to] = j;
        }
    }

    for(int i = 1; i < N; i++){
        // 各ノードから初めて、各エッジについての計算を行う
        // 親ノードのindexを求める
        int par_index = -1;
        int par_edge_id = -1;
        for(int j = 0; j < (int)G[i].size(); j++){
            if(pars[i] == G[i][j].first){
                par_index = j;
                par_edge_id = G[i][j].second;
                break;
            }
        }

        ll ans = (muls[i][par_index] * rec2(par_edge_id, es[par_edge_id].first != pars[i])) % mod;
        cout << ans << endl;
    }

    return 0;
}


Measured memory_bytes: 36864