#include <bits/stdc++.h>

#define rep(i,n) for(int i=0; i<(n); i++)
#define reps(i,x,n) for(int i=x; i<(n); i++)
#define rrep(i,n) for(int i=(n)-1; i>=0; i--)
#define all(X) (X).begin(),(X).end()
#define X first
#define Y second
#define pb push_back
#define eb emplace_back

using namespace std;
typedef long long int ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

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

template<class A, size_t N, class T> void Fill(A (&a)[N], const T &v){ fill( (T*)a, (T*)(a+N), v ); }

template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {os<<"{"; rep(i,t.size()) {os<<t[i]<<",";} os<<"}"; return os;}
template<class T,size_t n> ostream& operator<<(ostream &os, const array<T,n> &t) {os<<"{"; rep(i,n) {os<<t[i]<<",";} os<<"}"; return os;}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}

const ll INF = 1e9+7;

ll MOD = 1e9+7;

// n^m%MOD を求める。O( log(m) )
ll modpow(ll n, int m){
	ll ret=1;
	for(int i=1; i<=m; i<<=1, (n*=n)%=MOD){
		if( m&i ) (ret *= n) %= MOD;
	}
	return ret;
}

// 逆元を求める
ll modinv(ll n){
	return modpow( n, MOD-2 );
}

// 階乗を求める。O(1)  準備O( n*log(n) )
// fact[n]     : nの階乗
// fact.inv[n] : nの階乗の逆元
class FACTORIAL{
public:
	vector<ll> fact, inv;
	FACTORIAL(int MAX_NUM): fact(MAX_NUM), inv(MAX_NUM) {
		fact[0] = inv[0] = 1;
		for(ll i=1; i<MAX_NUM; i++){
			fact[i] = (fact[i-1] * i) % MOD;
			inv[i] = modinv( fact[i] );
		}
	}
	const ll& operator [ ] ( const int i ) const {
		return fact[i];
	}
} fact(200006); // nの最大値を指定


// 組み合わせ(Combinationを求める) O(1)
ll cmb(unsigned int n, unsigned int r){
	if( n < r ) return 0;
	return fact[n] * fact.inv[r] % MOD * fact.inv[n-r] % MOD;
}


template <typename T>
class Rerooting{
public:
	vector<vector<int>> edge;
	vector<map<int,T>> memo;
	vector<map<int,T>> sumL;
	vector<map<int,T>> sumR;

	struct Solver {
		virtual T init() const = 0;
		virtual T merge(T, T) const = 0;
		virtual T add_me(T) const = 0;
	};
	const Solver *solver;

	const T init_value;

	Rerooting(
			int N,
			const Solver *solver
	) :
		edge(N),
		memo(N),
		sumL(N),
		sumR(N),
		solver(solver),
		init_value(solver->init())
	{ }

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

	T solve(int n, int b = -1){
		if(memo[n].count(b)) return memo[n][b];

		if(b >= 0 && memo[b].count(n)){
			// b -> n が存在するとき、nが根のときの結果を使って高速化する
			solve(n, -1);  // sumL, sumR の計算がまだな場合は計算する
			auto ret = solver->merge(sumL[n][b], sumR[n][b]);
			return memo[n][b] = solver->add_me(ret);
		}

		T ret = init_value;
		for(auto t: edge[n]) if(t != b){
			ret = solver->merge(ret, solve(t, n));
		}

		if(b < 0){
			// nが根のときは、累積を計算しておく
			T sum = init_value;
			rep(i, edge[n].size()){
				int t = edge[n][i];
				sumL[n][t] = sum;
				sum = solver->merge(sum, solve(t,n));
			}
			sum = init_value;
			rrep(i, edge[n].size()){
				int t = edge[n][i];
				sumR[n][t] = sum;
				sum = solver->merge(sum, solve(t,n));
			}
		}

		return memo[n][b] = solver->add_me(ret);
	}
};

struct Solver: Rerooting<ll>::Solver {
	ll init() const override {
		return 1;
	}

	ll merge(ll a, ll b) const override {
		return a * b % MOD;
	}

	ll add_me(ll a) const override {
		return a + 1;
	}
};

int main(){
	ios_base::sync_with_stdio(false);

	int N, M;
	cin >> N >> M;
	MOD = M;
	Rerooting<ll> rr(N, new Solver());
	rep(i,N-1){
		int a, b;
		cin >> a >> b;
		a--; b--;
		rr.add_edge(a, b);
	}

	rep(i,N) cout << rr.solve(i) - 1 << "\n";

	return 0;
}

Measured memory_bytes: 78848