#include <bits/stdc++.h>

using namespace std;

template<class e, class t, int N>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, const e(&literal)[N]) {
        std::array<e, N-1> buffer; //get buffer
        in >> buffer[0]; //skips whitespace
        if (N>2)
                in.read(&buffer[1], N-2); //read the rest
        if (strncmp(&buffer[0], literal, N-1)) //if it failed
                in.setstate(in.rdstate() | std::ios::badbit); //set the state
        return in;
}
template<class e, class t>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, const e& literal) {
        e buffer;  //get buffer
        in >> buffer; //read data
        if (buffer != literal) //if it failed
                in.setstate(in.rdstate() | std::ios::badbit); //set the state
        return in;
}
//redirect mutable char arrays to their normal function
template<class e, class t, int N>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, e(&carray)[N]) {
        return std::operator>>(in, carray);
}
template<class t> 
ostream & operator<<(ostream & out, vector<t> & a){
    for(auto x : a){
        out << x <<" ";
    }
    return out;
}
template<class t1, class t2> 
ostream & operator<<(ostream & out, map<t1,t2> & a){
    for(auto x : a){
        out << x <<" ";
    }
    return out;
}
template<class t1,class t2>
ostream & operator<<(ostream & out,const pair<t1,t2> & a){
    out << a.first<<" "<<a.second;
    return out;
}
template<class t1,class t2>
pair<t1,t2> operator+(const pair<t2,t1>& a,const pair<t1,t2> & b){
    return {a.first + b.first, a.second + b.second};
}
template<class t1,class t2>
pair<t1,t2> operator-(const pair<t2,t1>& a,const pair<t1,t2> & b){
    return {a.first - b.first, a.second - b.second};
}


#define PRAGMA 448
#ifdef PRAGMA
#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#endif
 
#ifdef LUCARIO
#define deb(...) fprintf(stderr,__VA_ARGS__)
#define deb1(x) cerr << #x << " = " << x << endl;
#else
#define deb(...) 0
#define deb1(x) 0
#endif
 
typedef pair<long long,long long> pll;
typedef pair<int,int> pii;
typedef pair<string,int> psi;

#define FIN ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define ll long long
#define ld long double
#define int long long
#define pb push_back
#define bs binary_search 
#define up upper_bound // >
#define lb lower_bound // >=
#define f first 
#define s second 
#define fst first 
#define snd second 
#define ff first.first
#define fs first.second
#define sf second.first
#define ss second.second
#define mp make_pair     
#define endl "\n" 
 
#define fore(i,a,b) for(ll i = a; i < (ll)b; i++)
#define rfore(i, a, b) for(ll i = b - 1; i >= (ll)a; i--)
#define bin(aaa,bbb) fore(_,0,bbb)cout<<((aaa & (1<<_)) != 0);cout<<endl;
#define mm(a,b) memset(a , b , sizeof a) 
#define trans(a,b) transform(a.begin(),a.end(),a.begin(),b) //::tolower ::toupper
#define bpop(n) __builtin_popcount(n)
#define np(a) next_permutation(a.begin(), a.end())
#define ALL(a) a.begin(),a.end() 
#define SZ(n) ((ll) (n).size())
#define sfind(s,t) (s.find(t) != string::npos)
 
#define infll (ll)(1e15+3)
#define infi  (ll)(1e9+4)
//#define pi 3.14159265359 
//#define mod (ll)(1e9+7)
int mod;
#define eps  1e-7
#define YES "YES"
#define NO "NO"

ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b,a%b); } 
ll lcm(ll a, ll b) { return a * (b / gcd(a, b)); }
ll fpow(ll b, ll e, ll m = mod){if(!e)return 1;ll q=fpow(b,e/2,m);q=(q*q)%m;return e&1?(b*q)%m:q;}

int por(int a,int b){
    return (a*b)%mod;
}

#define oper por
#define NEUT 1
struct STree { // segment tree for min over integers
    vector<int> st;int n;
    STree(int n): st(4*n+5,NEUT), n(n) {}
    void init(int k, int s, int e, int *a){
        if(s+1==e){st[k]=a[s];return;}
        int m=(s+e)/2;
        init(2*k,s,m,a);init(2*k+1,m,e,a);
        st[k]=oper(st[2*k],st[2*k+1]);
    }
    void upd(int k, int s, int e, int p, int v){
        if(s+1==e){st[k]=v;return;}
        int m=(s+e)/2;
        if(p<m)upd(2*k,s,m,p,v);
        else upd(2*k+1,m,e,p,v);
        st[k]=oper(st[2*k],st[2*k+1]);
    }
    int query(int k, int s, int e, int a, int b){
        if(s>=b||e<=a)return NEUT;
        if(s>=a&&e<=b)return st[k];
        int m=(s+e)/2;
        return oper(query(2*k,s,m,a,b),query(2*k+1,m,e,a,b));
    }
    void dump(int n){
        fore(i,0,n){
            cout<<st[i]<<" ";
        }
        cout<<endl;
    }

    void init(int *a){init(1,0,n,a);}
    void upd(int p, int v){upd(1,0,n,p,v);}
    int query(int a, int b){return query(1,0,n,a,b);}
}; // usage: STree rmq(n);rmq.init(x);rmq.upd(i,v);rmq.query(s,e);


int res[100005];
int a[100005];
vector<int> g[100004];
int n;

int dfs(int i, int p){
    if(SZ(g[i]) == 1 && i != 0)return a[i] = 2;
    a[i] = 1;
    for(auto x : g[i]){
        if(x == p)continue;
        a[i] = (a[i]*dfs(x,i))%mod;
    }
    a[i]++;
    return a[i];
}


void solve(int i, int p, int cur){
    STree st(SZ(g[i]));
    fore(j,0,SZ(g[i])){
        if(g[i][j] == p){
            st.upd(j,cur);
        }else{
            st.upd(j,a[g[i][j]]);
        }
    }

    res[i] = st.query(0,SZ(g[i]));
    fore(j,0,SZ(g[i]))if(g[i][j] != p){
        st.upd(j,1);
        solve(g[i][j],i,(st.query(0,SZ(g[i]))+1)%mod);
        st.upd(j,a[g[i][j]]);
    }
}


int32_t main(int32_t argc, char const *argv[]){
    FIN;
    cin>>n>>mod;
    fore(i,0,n-1){
        int u,v;cin>>u>>v; u--;v--;
        g[u].pb(v);
        g[v].pb(u);
    }
    dfs(0,-1);
    solve(0,-1,1);
    fore(i,0,n){
        cout<<res[i]<<endl;
    }

    return 0;    
}




/*
Para las DP:

sLos arreglos donde estén los valores en lo posible se declaran como INT
siempre hacer int &r = dp...    
int res y trabapiijas todo con res
luego haces return r = res
cuando se trabaja se hace solve(...)+a[x];

break;
Fórmulas:

priority_queue < int,vector<int>,greater<int> > q; calse contenedor y comparacion
continue
break
cero = r/k  - (l/k + (l%k!=0)) +1; cantidad de números divisibles por k en el intervalo [l, r]
en un arreglo sircularde largo n si das saltos de largo m para volver al inicion nesesitas
n/gcd(n,m)
cantidad de inmeros en un rango lower_bound(r) -lowerbound(l-1)
upper_bound primer elemento mayor estricto
lower_bound primer elemento mayor o igual
Al hacer BFS con distancia recordar simpre antes de visitar preguntar si ya llegue antes con
un peso menor 
setprecision(15)
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
getline(cin,s); donde s es un string
si luego se van a haces unuevos cins hacer cin.ignore

__builtin_popcount(3) cantidad de unos en la reprewsentacion binaria
__builtin_clz() cantidad de 0 a la izquierda del primer numero
 __builtin_ffs evuelve 1+ el indise del uno menos significativo

TCL
 
tuple 
    tuple<tipo> nombre
    get<pos>(nombre) //forma de acceder

vector
    vector<tipo> nombre(cantidad,contenido)
    vector<int> nombre = {...}
    nombre.resize(tam,contenido si se agregan) //cambia el tamaño a tam
    nombre.pop_back() elimina el ultimo elemento
    nombre.back() // ultimo elemnto

set
    erase(it/elem)
    insert(elem)

rectas en un set

recta = az+by+c = 0 
recta entre 2 puntos
a = y1-y0 y b = x0-x1 => c = x1*y0-y1*x0

if(a<0 || (a==0 && b<0)) {
    a=-a;
    b=-b;
    c=-c;
}
d = gcd(a,b)
a,b /= gcd(a,b);
c,d /= gcd(d,c)

luego


*/

Measured memory_bytes: 31360