#include <stdio.h>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <math.h>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <list>
#include <iterator>
#include <assert.h>
#pragma warning(disable:4996) 

typedef long long ll;
#define MIN(a, b) ((a)>(b)? (b): (a))
#define MAX(a, b) ((a)<(b)? (b): (a))
#define LINF 9223300000000000000
#define INF 2140000000
//const long long MOD = 1000000007;
using namespace std;

long long MOD;
int n;
vector<vector<pair<int,int> > > g;   // to, edgeid

vector<ll> cntsave[2];    // [0]:check result of subtree whose top is the child of this edge
                          // [1]:check result of subtree whose top is the parent of this edge
                          // cnt[0]: all white
                          // cnt[1]: black exists, we can add white parent, we cannot add black parent
                          // cnt[2]: black exists, we can add white parent, we can add black parent
                          // cnt[3]: black exists, we cannot add white parent, we can add black parent
vector<ll> ans;

// concatinate childrens' info. to determine parent
void mult( const ll cnt0[4], const ll cnt1[4], ll cnt2[4] )    
{
    ll cnt[4];
    cnt[0] = (cnt0[0]*cnt1[0])%MOD;
    cnt[1] = (cnt0[0]*cnt1[1] + cnt0[1]*cnt1[0])%MOD;
    cnt[2] = (cnt0[0]*cnt1[2] + cnt0[2]*cnt1[0])%MOD;
    cnt[3] = (cnt0[2]*cnt1[2] + (cnt0[0]+cnt0[2])*cnt1[3] + cnt0[3]*(cnt1[0]+cnt1[2]) + cnt0[3]*cnt1[3])%MOD;
    int i;
    for(i=0; i<4; i++) {
        cnt2[i]=cnt[i];
    }
    return;
}

// determine parent from childrens' info.
void calc( const ll cnt0[4], ll res[4] )
{
    res[0] = cnt0[0];
    res[1] = (cnt0[1]+cnt0[2])%MOD;
    res[2] = (cnt0[0]+cnt0[2]+cnt0[3])%MOD;
    res[3] = 0;
    return;
}

void dfs( int par, int curr, ll cnt[4] )
{
    int siz=(int)g[curr].size();

    ll cntadd[4]={1,0,0,0};
    int i;
    for(i=0; i<siz; i++) {
        int next=g[curr][i].first;
        int edgeid=g[curr][i].second;
        if(par==next) continue;
        dfs( curr, next, &(cntsave[0][4*edgeid]) );
        mult(cntadd, &(cntsave[0][4*edgeid]), cntadd );
    }
    calc( cntadd, cnt );
    return;
}

void dfs2( int par, int curr )
{
    vector<pair<int, int> > z;
    int siz=(int)g[curr].size();
    int i;
    for(i=0; i<siz; i++) {
        int next=g[curr][i].first;
        int edgeid=g[curr][i].second;
        if(par==next) {
            z.push_back(make_pair(edgeid,1));
        }
        else {
            z.push_back(make_pair(edgeid,0));
        }
    }

    // 左から累積mult
    vector<ll> cntadd0(4*(siz+1));  
    cntadd0[0]=1;
    for(i=0; i<siz; i++) {
        mult(&(cntadd0[4*i]), &(cntsave[z[i].second][4*z[i].first]), &(cntadd0[4*(i+1)]));
    }

    // 右から累積mult
    vector<ll> cntadd1(4*(siz+1));   
    cntadd1[0]=1;
    for(i=0; i<siz; i++) {
        mult(&(cntadd1[4*i]), &(cntsave[z[siz-1-i].second][4*z[siz-1-i].first]), &(cntadd1[4*(i+1)]));
    }

    // calc result
    ll cnt[4];
    calc( &(cntadd0[4*siz]), cnt );
    ans[curr]=cnt[2];

    // go to children
    for(i=0; i<siz; i++) {
        int next=g[curr][i].first;
        int edgeid=g[curr][i].second;
        if(par==next) continue;

        ll cntadd[4];
        mult(&(cntadd0[4*i]), &(cntadd1[4*(siz-1-i)]), cntadd);
        calc( cntadd, &(cntsave[1][4*edgeid]) );

        dfs2( curr, next );
    }

    return;
}

int main(int argc, char* argv[])
{
    scanf("%d%lld", &n, &MOD);

    g.resize(n);
    cntsave[0].resize(4*(n-1));
    cntsave[1].resize(4*(n-1));
    ans.resize(n);

    int i;
    for(i=0; i<n-1; i++) {
        int a,b;
        scanf("%d%d", &a, &b);
        g[a-1].push_back(make_pair(b-1, i));
        g[b-1].push_back(make_pair(a-1, i));
    }

    ll cnt[4]={0};
    dfs( -1, 0, cnt );

    dfs2( -1, 0 );

    for(i=0; i<n; i++) {
        printf("%lld\n", ans[i]);
    }

    return 0;
}


Measured memory_bytes: 44800