import std.stdio, std.conv, std.string, std.bigint;
import std.math, std.random, std.datetime;
import std.array, std.range, std.algorithm, std.container, std.format;
string read(){ static string[] ss; while(!ss.length) ss = readln.chomp.split; string res = ss[0]; ss.popFront; return res; }

/*

双方向木DP

--------------------------------------------------------------------------------

辺は有向とし、根から葉に向かう向きとする

辺 edge の末端側にある部分木について、辺の先を黒とした場合の塗り方の個数を edge.value1 とする
辺 edge の根元側にある部分木について、辺の根本を黒とした場合の塗り方の個数を edge.value0 とする

value1の求め方は
辺の先が末端ノードであるとき、value1 = 1
そうでないとき、value1 = prod(ed; node1.edges) (ed.value1 + 1)
※真っ白という塗り方もあるので +1
※この立式は、prodの項数が0になる場合(＝末端ノードの場合)も包含できている

value0の求め方は
辺の根本が根であるとき、value0 = prod(ed; node0.edges) (ed.value1 + 1) ※prodは自分を含まない
そうでないとき、value0 = prod(ed; node0.edges) (ed.value1 + 1) * (node0.parentedge.value0 + 1) ※prodは自分を含まない

--------------------------------------------------------------------------------

ただし、このprodを愚直に計算すると、1つの頂点に多数の枝がついている場合にTLEになる
そこで以下の方法が考えられる

・セグメント木を使って処理する
・上からと下からの部分乗積を持っておき、prod(j; 0 .. i - 1) * prod(j; i + 1 .. n) のような立式にする
・全体の乗積を初めに計算して prod / x[i] のようにする ←これは、modが素数でないから無理

今回は、部分乗積を持っておく方針がよさそう。先程の式を、辺の根本であるノードの視点で見ると

自分が根であるとき、各 ed; edges について
 ed.value0 = prod(ed'; edges - {ed}) (ed'.value1 + 1)

そうでないとき、各 ed; edges について
 ed.value0 = prod(ed'; edges - {ed}) (ed'.value1 + 1) * (parentedge.value0 + 1)

これを立式すると

prod1[0] = 1;
foreach(j; 1 .. edges.length) prod1[j] = prod1[j - 1] * edges[j - 1].value;

prod2[edges.length - 1] = (parentedge? (parentedge.value0 + 1): 1);
foreach_reverse(j; 0 .. edges.length - 1) prod1[j] = prod1[j + 1] * edges[j + 1].value;

foreach(j; 0 .. edges.length) edges[0].value0 = prod1[j] * prod2[j];

--------------------------------------------------------------------------------

*/

long mod;

class Node{
	long id;
	Node[] nodes;
	Edge[] edges;
	Node parent;
	Edge parentedge;
	this(long id){
		this.id = id;
	}
	void treefy(Node parent, Edge edge){
		this.parent = parent;
		if(parent) this.parentedge = edge;
		foreach(nd; nodes){
			if(!parent || parent.id != nd.id){
				Edge ed = new Edge(this, nd);
				nd.treefy(this, ed);
				edges ~= ed;
			}
		}
	}
	
	void solve1(){
		long v = 1;
		foreach(ed; edges){
			ed.node1.solve1();
			v *= (ed.value1 + 1), v %= mod;
		}
		if(parentedge) parentedge.value1 = v;
	}
	
	void solve0(){
		long[] prod1 = new long[](edges.length);
		foreach(j; 0 .. edges.length){
			if(j == 0) prod1[j] = 1;
			else prod1[j] = prod1[j - 1] * (edges[j - 1].value1 + 1), prod1[j] %= mod;
			}
		
		long[] prod2 = new long[](edges.length);
		foreach_reverse(j; 0 .. edges.length){
			if(j == edges.length - 1) prod2[j] = 1;
			else prod2[j] = prod2[j + 1] * (edges[j + 1].value1 + 1), prod2[j] %= mod;
		}
		
		foreach(j; 0 .. edges.length){
			edges[j].value0 = prod1[j] * prod2[j], edges[j].value0 %= mod;
			if(parentedge) edges[j].value0 *= parentedge.value0 + 1, edges[j].value0 %= mod;
		}
		
		foreach(ed; edges) ed.node1.solve0();
	}
	
	long answer(){
		long res = (parentedge? (parentedge.value0 + 1): 1);
		foreach(ed; edges) res *= (ed.value1 + 1), res %= mod;
		return res % mod;
	}
	
	override string toString(){
		return this.id.to!string ~ "(" ~ (parentedge? parentedge.node0.id.to!string: "*") ~ ";" ~ edges.map!(ed => ed.node1.id.to!string ~ "(" ~ ed.value0.to!string ~ "|" ~ ed.value1.to!string ~ ")").array.join(",") ~ ")";
	}
}

class Edge{
	Node node0, node1;
	long value0, value1;
	this(Node node0, Node node1){
		this.node0 = node0;
		this.node1 = node1;
	}
}

void main(){
	long n = read.to!long;
	long m = read.to!long;
	mod = m;
	
	Node[] nodes;
	foreach(i; 0 .. n) nodes ~= new Node(i);
	debug writeln("nodes:", nodes);
	
	foreach(j; 0 .. n - 1){
		long x = read.to!long - 1;
		long y = read.to!long - 1;
		nodes[x].nodes ~= nodes[y];
		nodes[y].nodes ~= nodes[x];
	}
	debug writeln("nodes:", nodes);
	
	// 有向辺を作る
	nodes[0].treefy(null, null);
	debug writeln("nodes:", nodes);
	
	// 順向きの木DP(各辺のvalue1をセットする)
	nodes[0].solve1();
	debug writeln("nodes:", nodes);
	
	// 逆向きの木DP(各辺のvalue0をセットする)
	nodes[0].solve0();
	debug writeln("nodes:", nodes);
	
	foreach(nd; nodes) nd.answer.writeln;
}


Measured memory_bytes: 47612