#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define mp make_pair
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
#define lli long long int
#define pii pair<int,int>
#define vii vector<pii>
#define pb push_back
#define eb emplace_back
#define em emplace
#define all(v)  v.begin(),v.end()
#define vi vector<int>
#define vl vector<lli>
#define vll vector<pair<lli,lli>>
#define pll pair<lli,lli>
#define vvi vector<vector<int>>
#define vvl vector<vector<lli>>
#define error(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); }
#define tk(args...) take(args);
#define posLSB(X) __builtin_ctz(X)
#define num1bit(X) __builtin_popcount(X)
#define numlead0(X) __builtin_clz(X)
int mod;
#define umreserve(X) X.reserve(32768); X.max_load_factor(0.25);
void err(istream_iterator<string> it) {} template<typename T, typename... Args> void err(istream_iterator<string> it, T a, Args... args) { cout << *it << " = " << a << "\n"; err(++it, args...);}
void take() {} template<typename T, typename... Args> void take( T & a, Args & ... args ) { cin>>a; take(args...); }
template<class T>
void printvec(vector<T> &a){
	for(T &x:a){
		cout<<x<<" ";
	}
	cout<<endl;
}
template<class T>
void printarr(T a[],lli n){
	for(lli i=0;i<n;i++){
		cout<<a[i]<<" ";
	}
	cout<<endl;
}
struct HASH{
  size_t operator()(const pair<int,int>&x)const{
    return (size_t) x.first * 37U + (size_t) x.second;
  }
};

#define endl "\n"

lli add(lli a, lli b) {
	a += b;
	if (a >= mod) a -= mod;
	return a;
}

lli mul(lli a, lli b) {
	return a * 1ll * b % mod;
}

inline bool setmin(lli &x, lli y) { return (y < x) ? x = y, 1 : 0; }
inline bool setmax(lli &x, lli y) { return (y > x) ? x = y, 1 : 0; }

lli power_mod(lli a,lli x){if(x==0) return 1;lli y=power_mod(a,x/2);lli ans=(y*y)%mod; if(x%2) ans=(ans*a)%mod;return ans;}
lli inv(lli a){return power_mod(a,mod-2);}
lli power(lli a, lli x){ if(x==0) return 1; lli y= power(a,x/2); lli ans=(y*y); if(x%2) ans*=a; return ans;}
vector<vector<int>> a;
vector<vector<int>> tree; // it is a good idea to convert the tree storage format into a directed graph since we want a clean list of sons of a node, without having to filter out the parent on the go, since we seek to create a prefix and suffix product array for each node, which only the sons.
vector<int> up;
vector<int> down;
vector<vector<int>> pref;
vector<vector<int>> suf;
void dfs(int u, int parent){
	for(int v:a[u]){
		if(v==parent)continue;
		tree[u].pb(v);
		dfs(v,u);
	}
	
}
void solve_down(int u){
	pref[u].assign(SZ(tree[u]),0);	
	suf[u].assign(SZ(tree[u]),0);
	down[u]=1;
	for(int v:tree[u]){
		solve_down(v);
		down[u]=mul(down[u],add(1,down[v]));
	}
	for(int i=0;i<tree[u].size();i++){
		int v=tree[u][i];
		pref[u][i]=add(1,down[v]);
		if(i!=0){
			pref[u][i]=mul(pref[u][i-1],pref[u][i]);
		}
	}
	for(int i=SZ(tree[u])-1;i>=0;i--){
		int v=tree[u][i];
		suf[u][i]=add(1,down[v]);
		if(i!=SZ(tree[u])-1){
			suf[u][i]=mul(suf[u][i+1],suf[u][i]);
		}
	}
}
void solve_up(int u){
	int sz = tree[u].size();
	if(u==0)up[u]=1;
	for(int i=0;i<sz;i++){
		int v=tree[u][i];
		up[v]=up[u];
		if(i-1>=0)up[v]=mul(up[v],pref[u][i-1]);
		if(i+1<sz)up[v]=mul(up[v],suf[u][i+1]);
		up[v]=add(up[v],1);
		solve_up(v);
	}
}
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	int n;
	cin>>n;
	cin>>mod; // since mod may not be prime, a^(mod-2) might not work for modular inverses.
	a.assign(n,vector<int>());
	up.assign(n,0);
	down.assign(n,0);
	tree.assign(n,vector<int>());
	pref.assign(n,vector<int>());
	suf.assign(n,vector<int>());
	for(int i=0;i<n-1;i++){
		int x,y;
		cin>>x>>y;
		x--;
		y--;
		a[x].pb(y);
		a[y].pb(x);
	}
	dfs(0,-1);
	solve_down(0);
	solve_up(0); // it would be a much better idea to simply solve for all the sons (wrt up[] array) while AT the parent.
	
	for(int i=0;i<n;i++){
		cout<<(mul(up[i],down[i]))<<endl;
	}
}


Measured memory_bytes: 27264