Educational DP Contest - Subtree

There is a tree with N vertices, numbered 1, 2, \ldots, N. For each i (1 \leq i \leq N - 1), the i-th edge connects Vertex x_i and y_i.

Taro has decided to paint each vertex in white or black, so that any black vertex can be reached from any other black vertex by passing through only black vertices.

You are given a positive integer M. For each v (1 \leq v \leq N), answer the following question:

* Assuming that Vertex v has to be black, find the number of ways in which the vertices can be painted, modulo M.

Constraints

* All values in input are integers.
* 1 \leq N \leq 10^5
* 2 \leq M \leq 10^9
* 1 \leq x_i, y_i \leq N
* The given graph is a tree.

Input

Input is given from Standard Input in the following format:


N M
x_1 y_1
x_2 y_2
:
x_{N - 1} y_{N - 1}


Output

Print N lines. The v-th (1 \leq v \leq N) line should contain the answer to the following question:

* Assuming that Vertex v has to be black, find the number of ways in which the vertices can be painted, modulo M.

Examples

Input

3 100
1 2
2 3


Output

3
4
3


Input

4 100
1 2
1 3
1 4


Output

8
5
5
5


Input

1 100


Output

1


Input

10 2
8 5
10 8
6 5
1 5
4 8
2 10
3 6
9 2
1 7


Output

0
0
1
1
1
0
1
0
1
1

Difficulty: UNKNOWN_DIFFICULTY

Starter code:

Solutions:
import sys
from collections import deque
stdin = sys.stdin

def ni():
	return int(ns())

def na():
	return list(map(int, stdin.readline().split()))

def naa(N):
	return [na() for _ in range(N)]

def ns():
	return stdin.readline().rstrip()

def make_tree_0index(N):
	edge_dic = {}
	for _ in range(N - 1):
		(x, y) = na()
		x -= 1
		y -= 1
		if x in edge_dic:
			edge_dic[x].append(y)
		else:
			edge_dic[x] = [y]
		if y in edge_dic:
			edge_dic[y].append(x)
		else:
			edge_dic[y] = [x]
	return edge_dic
(N, M) = na()
if N == 1:
	print(1)
	exit()
edge_dic = make_tree_0index(N)
parent_array = [-2] * N
parent_array[0] = -1
node1 = deque([0])
node2 = deque([0])
node3 = deque([0])
while len(node1):
	n = node1.popleft()
	for v in edge_dic[n]:
		if parent_array[v] == -2:
			parent_array[v] = n
			node1.append(v)
			node2.append(v)
			node3.append(v)
ans1 = [0] * N
while len(node2):
	n = node2.pop()
	ans1[n] = 1
	for v in edge_dic[n]:
		if parent_array[n] == v:
			continue
		ans1[n] = ans1[n] * (ans1[v] + 1) % M
ans2 = [0] * N
subans2 = [0] * N
while len(node3):
	n = node3.popleft()
	ans2[n] = 1
	if n != 0:
		ans2[n] = (ans2[n] * ans2[parent_array[n]] * subans2[n] + 1) % M
	reverse = [1]
	right = 1
	for v in edge_dic[n][::-1]:
		if parent_array[n] == v:
			continue
		right = right * (ans1[v] + 1) % M
		reverse.append(right)
	reverse.pop()
	left = 1
	for v in edge_dic[n]:
		if parent_array[n] == v:
			continue
		right = reverse.pop()
		subans2[v] = left * right % M
		left = left * (ans1[v] + 1) % M
ans = [a * b % M for (a, b) in zip(ans1, ans2)]
print('\n'.join(map(str, ans)))


class ReRooting(object):

	def processing(self, in_: list, v: int):
		return [in_[0] + 1]

	def merge(self, in1: list, in2: list):
		return [in1[0] * in2[0] % M]

	def adjustment(self, in_: list, v: int):
		return in_

	def solve(self):
		return [res for [res] in self.calc()]

	def __init__(self, V: int, e: list):
		(self.V, self.e) = (V, e)
		self.edge = [[] for _ in range(V)]
		self.par = [-1] * V
		self.order = []

	def add_edge(self, u: int, v: int):
		self.edge[u].append(v)
		self.edge[v].append(u)

	def topological_sort(self, root: int=0):
		from collections import deque
		que = deque([root])
		while que:
			v = que.popleft()
			self.order.append(v)
			for w in self.edge[v]:
				if w != self.par[v]:
					self.par[w] = v
					self.edge[w].remove(v)
					que.append(w)

	def bottom_up(self):
		accBU = [self.e for _ in range(self.V)]
		resBU = [None] * self.V
		for v in reversed(self.order):
			for c in self.edge[v]:
				accBU[v] = self.merge(accBU[v], self.processing(resBU[c], c))
			resBU[v] = self.adjustment(accBU[v], v)
		return (accBU, resBU)

	def top_down(self, resBU: list):
		accTD = [self.e for _ in range(self.V)]
		resTD = [self.e for _ in range(self.V)]
		for p in self.order:
			ac = self.e if p == self.order[0] else self.processing(resTD[p], p)
			for v in self.edge[p]:
				accTD[v] = ac[:]
				ac = self.merge(ac, self.processing(resBU[v], v))
			ac = self.e
			for v in reversed(self.edge[p]):
				accTD[v] = self.merge(accTD[v], ac)
				resTD[v] = self.adjustment(accTD[v], v)
				ac = self.merge(ac, self.processing(resBU[v], v))
		return resTD

	def calc(self):
		self.topological_sort()
		(accBU, resBU) = self.bottom_up()
		resTD = self.top_down(resBU)
		res = [None] * self.V
		for v in self.order:
			res[v] = self.e if v == self.order[0] else self.processing(resTD[v], v)
			res[v] = self.merge(accBU[v], res[v])
			res[v] = self.adjustment(res[v], v)
		return res
(N, M) = map(int, input().split())
RR = ReRooting(N, [1])
for _ in range(N - 1):
	(x, y) = map(int, input().split())
	RR.add_edge(x - 1, y - 1)
print(*RR.solve(), sep='\n')


import math, string, itertools, fractions, heapq, collections, re, array, bisect, sys, random, time, copy, functools
sys.setrecursionlimit(10 ** 7)
inf = 10 ** 20
eps = 1.0 / 10 ** 10
mod = 10 ** 9 + 7
dd = [(-1, 0), (0, 1), (1, 0), (0, -1)]
ddn = [(-1, 0), (-1, 1), (0, 1), (1, 1), (1, 0), (1, -1), (0, -1), (-1, -1)]

def LI():
	return [int(x) for x in sys.stdin.readline().split()]

def LI_():
	return [int(x) - 1 for x in sys.stdin.readline().split()]

def LF():
	return [float(x) for x in sys.stdin.readline().split()]

def LS():
	return sys.stdin.readline().split()

def I():
	return int(sys.stdin.readline())

def F():
	return float(sys.stdin.readline())

def S():
	return input()

def pf(s):
	return print(s, flush=True)

def main():
	(n, m) = LI()
	if n == 1:
		return 1
	e = collections.defaultdict(list)
	for _ in range(n - 1):
		(a, b) = LI_()
		e[a].append(b)
		e[b].append(a)
	rr = [None] * n
	fm = [None] * n

	def f(i, p):
		r = 1
		for c in e[i]:
			if c != p:
				r *= f(c, i) + 1
				r %= m
		fm[i] = r
		return r

	def g(i, p, pp):
		l = len(e[i])
		v = e[i]
		ta = [(pp if u == p else fm[u] if not fm[u] is None else f(u, i)) + 1 for u in v]
		if l == 1:
			rr[i] = ta[0] % m
			return
		aa = [None] * l
		aa[0] = ta[0]
		for j in range(1, l):
			aa[j] = aa[j - 1] * ta[j] % m
		ba = [None] * l
		ba[-1] = ta[-1]
		for j in range(l - 2, -1, -1):
			ba[j] = ba[j + 1] * ta[j] % m
		rr[i] = ba[0] % m
		if v[0] != p:
			g(v[0], i, ba[1])
		for (j, u) in enumerate(v[1:-1]):
			if u != p:
				g(u, i, aa[j] * ba[j + 2] % m)
		if v[-1] != p:
			g(v[-1], i, aa[-2])

	def h(i):
		l = len(e[i])
		v = e[i]
		ta = [(fm[u] if not fm[u] is None else f(u, i)) + 1 for u in v]
		if l == 1:
			rr[i] = ta[0] % m
			g(v[0], i, 1)
			return
		aa = [None] * l
		aa[0] = ta[0]
		for j in range(1, l):
			aa[j] = aa[j - 1] * ta[j] % m
		ba = [None] * l
		ba[-1] = ta[-1]
		for j in range(l - 2, -1, -1):
			ba[j] = ba[j + 1] * ta[j] % m
		rr[i] = ba[0] % m
		g(v[0], i, ba[1])
		for (j, u) in enumerate(v[1:-1]):
			g(u, i, aa[j] * ba[j + 2] % m)
		g(v[-1], i, aa[-2])
	h(1)
	return '\n'.join(map(str, rr))
print(main())


import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 7)
(N, MOD) = map(int, input().split())
G = [[] for _ in range(N + 1)]
for _ in range(N - 1):
	(x, y) = map(int, input().split())
	G[x].append(y)
	G[y].append(x)
G[0].append(1)
G[1].append(0)
DP1 = [0] * (N + 1)
parent = [-1] * (N + 1)
parent[1] = 0
order = []
stack = [1]
while stack:
	x = stack.pop()
	order.append(x)
	for next_ in G[x]:
		if next_ == parent[x]:
			continue
		parent[next_] = x
		stack.append(next_)
for v in order[::-1]:
	tmp = 1
	for next_ in G[v]:
		tmp *= DP1[next_] + 1
		tmp %= MOD
	DP1[v] = tmp
DP2 = [1] * (N + 1)
for x in order:
	n = len(G[x])
	lst1 = [1] * (n + 1)
	lst2 = [1] * (n + 1)
	for i in range(n):
		if G[x][i] == parent[x]:
			lst1[i + 1] = lst1[i] * DP2[x] % MOD
		else:
			lst1[i + 1] = lst1[i] * (DP1[G[x][i]] + 1) % MOD
		if G[x][n - 1 - i] == parent[x]:
			lst2[n - i - 1] = lst2[n - i] * DP2[x] % MOD
		else:
			lst2[n - i - 1] = lst2[n - i] * (DP1[G[x][n - 1 - i]] + 1) % MOD
	for i in range(n):
		if G[x][i] == parent[x]:
			continue
		tmp = lst1[i] * lst2[i + 1] % MOD
		tmp += 1
		DP2[G[x][i]] = tmp % MOD
		stack.append(G[x][i])
for i in range(1, N + 1):
	print(DP1[i] * DP2[i] % MOD)


class Graph:

	def __init__(self, n_vertices, edges, directed=True):
		self.n_vertices = n_vertices
		self.edges = edges
		self.directed = directed

	@property
	def adj(self):
		try:
			return self._adj
		except AttributeError:
			adj = [[] for _ in range(self.n_vertices)]
			if self.directed:
				for (u, v) in self.edges:
					adj[u].append(v)
			else:
				for (u, v) in self.edges:
					adj[u].append(v)
					adj[v].append(u)
			self._adj = adj
			return adj

class RootedTree(Graph):

	def __init__(self, n_vertices, edges, root_vertex):
		self.root = root_vertex
		super().__init__(n_vertices, edges, False)

	@property
	def parent(self):
		try:
			return self._parent
		except AttributeError:
			adj = self.adj
			parent = [None] * self.n_vertices
			parent[self.root] = -1
			stack = [self.root]
			for _ in range(self.n_vertices):
				v = stack.pop()
				for u in adj[v]:
					if parent[u] is None:
						parent[u] = v
						stack.append(u)
			self._parent = parent
			return parent

	@property
	def children(self):
		try:
			return self._children
		except AttributeError:
			children = [None] * self.n_vertices
			for (v, (l, p)) in enumerate(zip(self.adj, self.parent)):
				children[v] = [u for u in l if u != p]
			self._children = children
			return children

	@property
	def dfs_order(self):
		try:
			return self._dfs_order
		except AttributeError:
			order = [None] * self.n_vertices
			children = self.children
			stack = [self.root]
			for i in range(self.n_vertices):
				v = stack.pop()
				order[i] = v
				for u in children[v]:
					stack.append(u)
			self._dfs_order = order
			return order
from functools import reduce
from itertools import accumulate, chain

def rerooting(rooted_tree, merge, identity, finalize):
	N = rooted_tree.n_vertices
	parent = rooted_tree.parent
	children = rooted_tree.children
	order = rooted_tree.dfs_order
	dp_down = [None] * N
	for v in reversed(order[1:]):
		dp_down[v] = finalize(reduce(merge, (dp_down[c] for c in children[v]), identity), v)
	dp_up = [None] * N
	dp_up[0] = identity
	for v in order:
		if len(children[v]) == 0:
			continue
		temp = (dp_up[v],) + tuple((dp_down[u] for u in children[v])) + (identity,)
		left = accumulate(temp[:-2], merge)
		right = tuple(accumulate(reversed(temp[2:]), merge))
		for (u, l, r) in zip(children[v], left, reversed(right)):
			dp_up[u] = finalize(merge(l, r), v)
	res = [None] * N
	for (v, l) in enumerate(children):
		res[v] = reduce(merge, (dp_down[u] for u in children[v]), identity)
		res[v] = finalize(merge(res[v], dp_up[v]), v)
	return res

def solve(N, M, E):
	tree = RootedTree(N, E, 0)

	def merge(x, y):
		return x * y % M

	def finalize(x, v):
		return x + 1
	res = rerooting(tree, merge, 1, finalize)
	return [v - 1 for v in res]
(N, M) = map(int, input().split())
E = [tuple(map(lambda x: int(x) - 1, input().split())) for _ in range(N - 1)]
print(*solve(N, M, E), sep='\n')


import sys
from collections import defaultdict
sys.setrecursionlimit(10 ** 8)

class Graph(object):

	def __init__(self, N):
		self.N = N
		self.E = defaultdict(list)

	def add_edge(self, f, t, w=1):
		self.E[f].append((t, w))

def solve(N: int, M: int, x: 'List[int]', y: 'List[int]'):
	g = Graph(N)
	for (xx, yy) in zip(x, y):
		g.add_edge(xx - 1, yy - 1)
		g.add_edge(yy - 1, xx - 1)
	dp = [0] * N

	def dfs(node, par=-1):
		dp[node] = 1
		for (child, _) in g.E[node]:
			if child == par:
				continue
			dp[node] *= dfs(child, node) + 1
			dp[node] %= M
		return dp[node]
	ans = [0] * N

	def dfs_2(node, par=-1):
		ans[node] = 1
		for (child, _) in g.E[node]:
			ans[node] *= dp[child] + 1
			ans[node] %= M
		K = len(g.E[node])
		(left, right) = ([1] * K, [1] * K)
		for i in range(K):
			(t, w) = g.E[node][i]
			left[i] = left[i - 1] * (dp[t] + 1)
			left[i] %= M
		for i in range(K - 1, -1, -1):
			(t, w) = g.E[node][i]
			if i != K - 1:
				right[i] = right[i + 1] * (dp[t] + 1)
			else:
				right[i] = dp[t] + 1
			right[i] %= M
		for i in range(K):
			(child, _) = g.E[node][i]
			if child == par:
				continue
			dp[node] = 1
			if i:
				dp[node] *= left[i - 1]
			if i + 1 < K:
				dp[node] *= right[i + 1]
			dp[node] %= M
			dfs_2(child, node)
	dfs(0)
	dfs_2(0)
	for a in ans:
		print(a % M)
	return

def main():

	def iterate_tokens():
		for line in sys.stdin:
			for word in line.split():
				yield word
	tokens = iterate_tokens()
	N = int(next(tokens))
	M = int(next(tokens))
	x = [int()] * (N - 1)
	y = [int()] * (N - 1)
	for i in range(N - 1):
		x[i] = int(next(tokens))
		y[i] = int(next(tokens))
	solve(N, M, x, y)
main()


def main():
	(n, m) = map(int, input().split())
	ab = [list(map(int, input().split())) for _ in [0] * (n - 1)]
	g = [[] for _ in [0] * n]
	[g[a - 1].append(b - 1) for (a, b) in ab]
	[g[b - 1].append(a - 1) for (a, b) in ab]

	class rerooting:

		def __init__(self, tree, ini, monoid, add):

			def calc(i, j):
				root = tree_d[i][j] + 1
				try:
					return monoid(tc_l[i][root - 1], tc_r[i][root])
				except:
					return tc_l[i][root - 1]
			size = len(tree)
			(dp, order, q, anc) = ([ini] * size, [], [0], [-1] * n)
			(oa, qa, qp) = (order.append, q.append, q.pop)
			tree_d = [{k: j for (j, k) in enumerate(i)} for i in g]
			g_size = [len(i) for i in g]
			tc_l = [[ini] * (i + 1) for i in g_size]
			tc_r = [[ini] * i for i in g_size]
			while q:
				i = qp()
				a = anc[i]
				oa(i)
				for j in g[i]:
					if j != a:
						qa(j)
						anc[j] = i
			for i in order[:0:-1]:
				a = anc[i]
				(d, t) = (add(a, i, dp[i]), tree_d[a][i])
				(tc_l[a][t + 1], tc_r[a][t], dp[a]) = (d, d, monoid(dp[a], d))
			for j in range(1, g_size[0] + 1):
				tc_l[0][j] = monoid(tc_l[0][j], tc_l[0][j - 1])
			for j in range(g_size[0] - 2, 0, -1):
				tc_r[0][j] = monoid(tc_r[0][j], tc_r[0][j + 1])
			for i in order[1:]:
				a = anc[i]
				(d, c, length) = (tree_d[i][a], add(a, i, calc(a, i)), g_size[i])
				(tc_l[i][d + 1], tc_r[i][d]) = (c, c)
				for j in range(1, length + 1):
					tc_l[i][j] = monoid(tc_l[i][j], tc_l[i][j - 1])
				for j in range(length - 2, 0, -1):
					tc_r[i][j] = monoid(tc_r[i][j + 1], tc_r[i][j])
				dp[i] = tc_l[i][-1]
			(self.dp, self.tc_l, self.tc_r, self.tree_d, self.monoid) = (dp, tc_l, tc_r, tree_d, monoid)

		def DP_part(self, i, j):
			root = self.tree_d[i][j] + 1
			try:
				return self.monoid(self.tc_l[i][root - 1], self.tc_r[i][root])
			except:
				return self.tc_l[i][root - 1]

	def monoid1(x, y):
		return x * y % m

	def add1(i, j, x):
		return x + 1
	r1 = rerooting(g, 1, monoid1, add1)
	for i in r1.dp:
		print(i)
main()


import sys
from collections import deque
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 9)
(N, mod) = map(int, input().split())
EDGE = [list(map(int, input().split())) for i in range(N - 1)]
if N == 1:
	print(1)
	sys.exit()
EDGELIST = [[] for i in range(N + 1)]
for (x, y) in EDGE:
	EDGELIST[x].append(y)
	EDGELIST[y].append(x)
SCORELIST = [[-1] * len(EDGELIST[i]) for i in range(N + 1)]
PRODLIST = [[-1] * len(EDGELIST[i]) for i in range(N + 1)]
PRODLIST_rev = [[-1] * len(EDGELIST[i]) for i in range(N + 1)]
EDICT = dict()
for i in range(1, N + 1):
	for j in range(len(EDGELIST[i])):
		EDICT[i, EDGELIST[i][j]] = j

def dp(x, y):
	if SCORELIST[y][EDICT[y, x]] != -1:
		return SCORELIST[y][EDICT[y, x]]
	ANS = 1
	for to in EDGELIST[x]:
		if to == y:
			continue
		ANS = ANS * dp(to, x) % mod
	SCORELIST[y][EDICT[y, x]] = ANS + 1
	return ANS + 1

def dp2(x, y):
	if PRODLIST[x][0] == -1:
		PRODLIST[x][0] = SCORELIST[x][0] % mod
		for i in range(1, len(EDGELIST[x])):
			PRODLIST[x][i] = PRODLIST[x][i - 1] * SCORELIST[x][i] % mod
		PRODLIST_rev[x][-1] = SCORELIST[x][-1]
		for i in range(len(EDGELIST[x]) - 2, -1, -1):
			PRODLIST_rev[x][i] = PRODLIST_rev[x][i + 1] * SCORELIST[x][i] % mod
	if len(EDGELIST[x]) == 1:
		ANS = 1
	elif EDICT[x, y] == 0:
		ANS = PRODLIST_rev[x][1]
	elif EDICT[x, y] == len(EDGELIST[x]) - 1:
		ANS = PRODLIST[x][EDICT[x, y] - 1]
	else:
		ANS = PRODLIST[x][EDICT[x, y] - 1] * PRODLIST_rev[x][EDICT[x, y] + 1] % mod
	SCORELIST[y][EDICT[y, x]] = ANS + 1
for to in EDGELIST[1]:
	dp(to, 1)
QUE = deque([1])
check = [0] * (N + 1)
while QUE:
	x = QUE.pop()
	if check[x] == 1:
		continue
	for to in EDGELIST[x]:
		if check[x] == 0 or check[to] == 0:
			dp2(x, to)
			QUE.append(to)
	check[x] = 1
for i in range(1, N + 1):
	print(PRODLIST[i][-1])


import sys
input = sys.stdin.readline
from collections import deque
nn = 200200
mod = 10 ** 9 + 7
fa = [1] * (nn + 1)
fainv = [1] * (nn + 1)
for i in range(nn):
	fa[i + 1] = fa[i] * (i + 1) % mod
fainv[-1] = pow(fa[-1], mod - 2, mod)
for i in range(nn)[::-1]:
	fainv[i] = fainv[i + 1] * (i + 1) % mod
inv = lambda i: fainv[i] * fa[i - 1] % mod
(N, mod) = map(int, input().split())
X = [[] for i in range(N)]
for i in range(N - 1):
	(x, y) = map(int, input().split())
	X[x - 1].append(y - 1)
	X[y - 1].append(x - 1)
P = [-1] * N
Q = deque([0])
R = []
while Q:
	i = deque.popleft(Q)
	R.append(i)
	for a in X[i]:
		if a != P[i]:
			P[a] = i
			X[a].remove(i)
			deque.append(Q, a)
unit = 1
td_unit = 1
merge = lambda a, b: a * b % mod
adj_bu = lambda a, i=-1: a + 1
adj_td = lambda a, i=-1: a + 1
calc = lambda i: merge(BU[i] - 1, TD[i])
SI = [1] * N
for i in R[1:][::-1]:
	SI[P[i]] += SI[i]
BU = [unit] * N
TD = [td_unit] * N
for i in R[1:][::-1]:
	BU[i] = adj_bu(BU[i], i)
	p = P[i]
	BU[p] = merge(BU[p], BU[i])
BU[R[0]] = adj_bu(BU[R[0]], R[0])
AX = [0] * N
for i in R:
	ac = unit
	for j in X[i]:
		AX[j] = ac
		ac = merge(ac, BU[j])
	ac = unit
	for j in X[i][::-1]:
		AX[j] = merge(AX[j], ac)
		TD[j] = adj_td(merge(merge(unit, TD[i]), AX[j]), j)
		ac = merge(ac, BU[j])
ANS = [calc(i) for i in range(N)]
print(*ANS)


from collections import deque

def resolve():
	(N, MOD) = map(int, input().split())
	G = [[] for i in range(N)]
	for i in range(N - 1):
		(x, y) = map(lambda x: int(x) - 1, input().split())
		G[x].append(y)
		G[y].append(x)
	P = [-1] * N
	q = deque([0])
	R = []
	while q:
		i = q.popleft()
		R.append(i)
		for to in G[i]:
			if to != P[i]:
				P[to] = i
				G[to].remove(i)
				q.append(to)
	unit = 1
	merge = lambda a, b: a * b % MOD
	adj_bu = lambda a, i: a + 1
	adj_td = lambda a, i, p: a + 1
	adj_fin = lambda a, i: a
	ME = [unit] * N
	dp1 = [0] * N
	for i in R[1:][::-1]:
		dp1[i] = adj_bu(ME[i], i)
		p = P[i]
		ME[p] = merge(ME[p], dp1[i])
	dp1[R[0]] = adj_fin(ME[R[0]], R[0])
	TD = [unit] * N
	for i in R:
		ac = TD[i]
		for j in G[i]:
			TD[j] = ac
			ac = merge(ac, dp1[j])
		ac = unit
		for j in G[i][::-1]:
			TD[j] = adj_td(merge(TD[j], ac), j, i)
			ac = merge(ac, dp1[j])
			dp1[j] = adj_fin(merge(ME[j], TD[j]), j)
	print(*dp1, sep='\n')
resolve()


import sys
sys.setrecursionlimit(10 ** 7)
input = sys.stdin.readline

def dfs(v, p):
	size[v] = len(G[v])
	dp[v] = [0] * size[v]
	res = 1
	for i in range(size[v]):
		nv = G[v][i]
		if nv == p:
			p_i[v] = i
			continue
		R = dfs(nv, v)
		dp[v][i] = R
		res = res * (R + 1) % MOD
	return res

def reroot(v, res_p, p):
	if p != -1:
		dp[v][p_i[v]] = res_p
	for i in range(size[v]):
		ans[v] = ans[v] * (dp[v][i] + 1) % MOD
	dp_L = [1] * (size[v] + 1)
	dp_R = [1] * (size[v] + 1)
	for i in range(size[v]):
		dp_L[i + 1] = dp_L[i] * (dp[v][i] + 1) % MOD
	for i in reversed(range(size[v])):
		dp_R[i] = dp_R[i + 1] * (dp[v][i] + 1) % MOD
	for i in range(size[v]):
		nv = G[v][i]
		if nv == p:
			continue
		reroot(nv, dp_L[i] * dp_R[i + 1] % MOD, v)
(N, MOD) = map(int, input().split())
G = [[] for i in range(N)]
for i in range(N - 1):
	(x, y) = map(lambda x: int(x) - 1, input().split())
	G[x].append(y)
	G[y].append(x)
dp = [[] for i in range(N)]
size = [-1] * N
p_i = [-1] * N
dp_L = [[] for i in range(N)]
dp_R = [[] for i in range(N)]
ans = [1] * N
z_root = dfs(0, -1)
reroot(0, 0, -1)
print(*ans, sep='\n')


import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 9)
(N, MOD) = map(int, input().split())
adjL = [[] for _ in range(N)]
for _ in range(N - 1):
	(x, y) = map(int, input().split())
	(x, y) = (x - 1, y - 1)
	adjL[x].append(y)
	adjL[y].append(x)

def ReRooting(adjL):

	def merge(val1, val2):
		return val1 * val2 % MOD

	def calcValue(val1):
		return (val1 + 1) % MOD
	numV = len(adjL)
	vRoot = 0
	useds = [False] * numV
	useds[vRoot] = True
	vs = [vRoot]
	pars = [-1] * numV
	stack = [vRoot]
	while stack:
		v = stack.pop()
		for v2 in adjL[v]:
			if not useds[v2]:
				useds[v2] = True
				vs.append(v2)
				pars[v2] = v
				stack.append(v2)
	anss = [0] * numV
	(dpUpFrom, dpDownTo, accLs, accRs) = ([1] * numV, [1] * numV, [1] * numV, [1] * numV)
	for v in reversed(vs):
		vPar = pars[v]
		tmp = 1
		for v2 in adjL[v]:
			if v2 == vPar:
				continue
			accLs[v2] = tmp
			tmp = merge(tmp, dpUpFrom[v2])
		tmp = 1
		for v2 in reversed(adjL[v]):
			if v2 == vPar:
				continue
			accRs[v2] = tmp
			tmp = merge(tmp, dpUpFrom[v2])
		anss[v] = tmp
		dpUpFrom[v] = calcValue(tmp)
	for v in vs:
		vPar = pars[v]
		dpDownToV = dpDownTo[v]
		anss[v] = merge(anss[v], dpDownToV)
		for v2 in adjL[v]:
			if v2 == vPar:
				continue
			tmp = merge(accLs[v2], accRs[v2])
			tmp = merge(tmp, dpDownToV)
			dpDownTo[v2] = calcValue(tmp)
	return anss
anss = ReRooting(adjL)
print('\n'.join(map(str, anss)))


import sys
input = sys.stdin.readline
from collections import deque
(N, M) = map(int, input().split())
X = [[] for i in range(N)]
for i in range(N - 1):
	(x, y) = map(int, input().split())
	X[x - 1].append(y - 1)
	X[y - 1].append(x - 1)
P = [-1] * N
Q = deque([0])
R = []
while Q:
	i = deque.popleft(Q)
	R.append(i)
	for a in X[i]:
		if a != P[i]:
			P[a] = i
			X[a].remove(i)
			deque.append(Q, a)
A = [0] * N
AA = [1] * N
for i in R[::-1]:
	a = 1
	for j in X[i]:
		a = a * (A[j] + 1) % M
	A[i] = a
for i in R:
	B = [1] * (len(X[i]) + 1)
	for j in range(len(X[i])):
		B[j + 1] = B[j] * (A[X[i][j]] + 1) % M
	a = 1
	for j in range(len(X[i]))[::-1]:
		t = a * B[j]
		a = a * (A[X[i][j]] + 1) % M
		AA[X[i][j]] = (AA[i] * t + 1) % M
for t in [a * aa % M for (a, aa) in zip(A, AA)]:
	print(t)


import sys
sys.setrecursionlimit(2147483647)
INF = float('inf')
MOD = 10 ** 9 + 7
input = lambda : sys.stdin.readline().rstrip()

def resolve():
	(n, MOD) = map(int, input().split())
	if n == 1:
		print(1)
		return
	E = [[] for _ in range(n)]
	nv_to_idx = [{} for _ in range(n)]
	for _ in range(n - 1):
		(u, v) = map(int, input().split())
		u -= 1
		v -= 1
		nv_to_idx[u][v] = len(E[u])
		nv_to_idx[v][u] = len(E[v])
		E[u].append(v)
		E[v].append(u)
	topological_sort = []
	parent = [None] * n
	stack = [(0, -1)]
	while stack:
		(v, p) = stack.pop()
		parent[v] = p
		topological_sort.append(v)
		for nv in E[v]:
			if nv == p:
				continue
			stack.append((nv, v))
	topological_sort.reverse()
	dp = [None] * n
	for v in topological_sort:
		res = 1
		for nv in E[v]:
			if nv == parent[v]:
				continue
			res = res * (dp[nv] + 1) % MOD
		dp[v] = res

	def rerooting(v, p):
		if p != -1 and v != -1:
			idx = nv_to_idx[p][v]
			p_res = 1
			if idx > 0:
				p_res *= cum_left[p][idx - 1]
			if idx < len(E[p]) - 1:
				p_res *= cum_right[p][idx + 1]
			dp[p] = p_res % MOD
		if cum_left[v] is None:
			left = [(dp[nv] + 1) % MOD for nv in E[v]]
			right = [(dp[nv] + 1) % MOD for nv in E[v]]
			k = len(E[v])
			for i in range(k - 1):
				left[i + 1] *= left[i]
				left[i + 1] %= MOD
			for i in range(k - 1, 0, -1):
				right[i - 1] *= right[i]
				right[i - 1] %= MOD
			cum_left[v] = left
			cum_right[v] = right
		dp[v] = cum_left[v][-1]
	ans = [None] * n
	stack = [(~0, -1), (0, -1)]
	cum_left = [None] * n
	cum_right = [None] * n
	while stack:
		(v, p) = stack.pop()
		if v >= 0:
			rerooting(v, p)
			ans[v] = dp[v]
			for nv in E[v]:
				if nv == p:
					continue
				stack.append((~nv, v))
				stack.append((nv, v))
		else:
			rerooting(p, ~v)
	print(*ans, sep='\n')
resolve()


import sys
sys.setrecursionlimit(100000)

def dfs1(v, p):
	val = 1
	pre_mul = [1]
	rev_mul = []
	for c in links[v]:
		if c == p:
			pre_mul.append(val)
			rev_mul.append(1)
			continue
		res = 1 + dfs1(c, v)
		val *= res
		val %= m
		pre_mul.append(val)
		rev_mul.append(res)
	dp[v] = val
	for i in range(len(rev_mul) - 2, -1, -1):
		rev_mul[i] *= rev_mul[i + 1]
		rev_mul[i] %= m
	rev_mul.append(1)
	pre_muls[v] = [pre_mul, rev_mul]
	return val

def dfs2(v, p, a):
	dp[v] = dp[v] * a % m
	pmv = pre_muls[v]
	for (i, c) in enumerate(links[v]):
		if c == p:
			continue
		pmc = pmv[0][i] * pmv[1][i + 1] % m
		pmc = pmc * a % m
		dfs2(c, v, pmc + 1)
(n, m) = map(int, input().split())
links = [[] for _ in range(n)]
dp = [0 for _ in range(n)]
pre_muls = [None for _ in range(n)]
for line in sys.stdin.readlines():
	(x, y) = map(int, line.split())
	x -= 1
	y -= 1
	links[x].append(y)
	links[y].append(x)
dfs1(0, None)
dfs2(0, None, 1)
print('\n'.join(map(str, dp)))


import sys
input = sys.stdin.buffer.readline
sys.setrecursionlimit(10 ** 7)
(N, mod) = map(int, input().split())
edge = [[] for _ in range(N)]
for _ in range(N - 1):
	(x, y) = map(int, input().split())
	x -= 1
	y -= 1
	edge[x].append(y)
	edge[y].append(x)
topo = []
parent = [-1] * N
node = [0]
while node:
	s = node.pop()
	topo.append(s)
	for t in edge[s]:
		if t == parent[s]:
			continue
		parent[t] = s
		node.append(t)
memo = [1] * N
res = [1] * N
for s in reversed(topo):
	for t in edge[s]:
		if t == parent[s]:
			continue
		res[s] = res[s] * memo[t] % mod
	memo[s] = res[s] + 1
TD = [1] * N
for s in topo:
	acc = TD[s]
	for t in edge[s]:
		if t == parent[s]:
			continue
		TD[t] = acc
		acc = acc * memo[t] % mod
	acc = 1
	for t in reversed(edge[s]):
		if t == parent[s]:
			continue
		TD[t] = (TD[t] * acc + 1) % mod
		acc = acc * memo[t] % mod
		res[t] = res[t] * TD[t] % mod
print(*res, sep='\n')


from collections import defaultdict
from operator import add, mul
import sys
input = sys.stdin.readline

class Reroot:

	def __init__(self, N, M):
		self.G = defaultdict(list)
		self.parents = [-1] * (N + 1)
		self.dp = defaultdict(lambda : defaultdict(int))
		self.ans = [0] * (N + 1)
		self.merge = lambda x, y: mul(x, y)
		self.add_root = lambda x: x
		self.e = 1
		self.M = M

	def add_edge(self, s, t):
		self.G[s].append(t)

	def build(self):
		self.dfs1(1)
		self.dfs2(1)
		return self.ans

	def dfs1(self, s):
		l = []
		q = [1]
		while q:
			s = q.pop()
			l.append(s)
			for t in self.G[s]:
				if t == self.parents[s]:
					continue
				self.parents[t] = s
				q.append(t)
		for s in l[::-1]:
			v = self.e
			for t in self.G[s]:
				if t == self.parents[s]:
					continue
				v = self.merge(v, self.dp[s][t] + 1)
			self.dp[self.parents[s]][s] = self.add_root(v)

	def dfs2(self, s):
		q = [(s, self.e)]
		while q:
			(s, dp_p) = q.pop()
			par = self.parents[s]
			for t in self.G[s]:
				if t == par:
					self.dp[s][t] = dp_p
			size = len(self.G[s])
			ac_l = [self.e] * (size + 1)
			ac_r = [self.e] * (size + 1)
			for (i, t) in enumerate(self.G[s]):
				ac_l[i + 1] = self.merge(ac_l[i], self.dp[s][t] + 1) % self.M
			for (i, t) in enumerate(self.G[s][::-1]):
				ac_r[size - i - 1] = self.merge(ac_r[size - i], self.dp[s][t] + 1) % self.M
			self.ans[s] = self.add_root(ac_l[size])
			for (i, t) in enumerate(self.G[s]):
				if t == par:
					continue
				q.append((t, self.add_root(self.merge(ac_l[i], ac_r[i + 1]) % self.M)))

def solve():
	(N, M) = map(int, input().split())
	tree = Reroot(N, M)
	for _ in range(N - 1):
		(a, b) = map(int, input().split())
		tree.add_edge(a, b)
		tree.add_edge(b, a)
	ans = tree.build()
	for i in range(1, N + 1):
		print(ans[i])
solve()


from collections import deque
(N, M) = map(int, input().split())
edge = [[] for _ in range(N)]
for _ in range(N - 1):
	(x, y) = map(int, input().split())
	edge[x - 1].append(y - 1)
	edge[y - 1].append(x - 1)
par = [-1] * N
TS = []
que = deque([0])
while que:
	v = que.popleft()
	TS.append(v)
	for w in edge[v]:
		if w == par[v]:
			continue
		par[w] = v
		edge[w].remove(v)
		que.append(w)
unit = 1
merge = lambda a, b: a * b % M
adj_bu = lambda a, v: a + 1
adj_td = lambda a, v, p: a + 1
adj_fin = lambda a, v: a
accBU = [unit] * N
res = [0] * N
for v in reversed(TS[1:]):
	res[v] = adj_bu(accBU[v], v)
	p = par[v]
	accBU[p] = merge(accBU[p], res[v])
res[TS[0]] = adj_fin(accBU[TS[0]], TS[0])
resTD = [unit] * N
for p in TS:
	tmp = resTD[p]
	for v in edge[p]:
		resTD[v] = tmp
		tmp = merge(tmp, res[v])
	tmp = unit
	for v in reversed(edge[p]):
		resTD[v] = adj_td(merge(resTD[v], tmp), v, p)
		tmp = merge(tmp, res[v])
		res[v] = adj_fin(merge(accBU[v], resTD[v]), v)
print(*res, sep='\n')


import sys
input = sys.stdin.readline
(n, mod) = map(int, input().split())
ab = [list(map(int, input().split())) for i in range(n - 1)]
graph = [[] for i in range(n + 1)]
deg = [0] * (n + 1)
for (a, b) in ab:
	graph[a].append(b)
	graph[b].append(a)
	deg[a] += 1
	deg[b] += 1
root = 0
stack = []
dp = [[] for i in range(n + 1)]
dpacc1 = [[] for i in range(n + 1)]
dpacc2 = [[] for i in range(n + 1)]
order = [[] for i in range(n + 1)]
num = [0 for i in range(n + 1)]
for i in range(1, n + 1):
	if deg[i] == 1:
		stack.append(i)
		num[i] = 1
	elif not root:
		root = i
		deg[i] += 1
while stack:
	x = stack.pop()
	if dp[x]:
		num[x] = 1
		for z in dp[x]:
			num[x] *= z
			num[x] %= mod
	for y in graph[x]:
		if deg[y] > 1:
			deg[y] -= 1
			dp[y].append(num[x] + 1)
			order[y].append(x)
			if deg[y] == 1:
				stack.append(y)
stack = [root]
deg[root] -= 1
while stack:
	x = stack.pop()
	l = len(order[x])
	if dp[x]:
		for v in dp[x]:
			if not dpacc1[x]:
				dpacc1[x].append(v)
			else:
				dpacc1[x].append(dpacc1[x][-1] * v % mod)
		for v in dp[x][::-1]:
			if not dpacc2[x]:
				dpacc2[x].append(v)
			else:
				dpacc2[x].append(dpacc2[x][-1] * v % mod)
	for (i, y) in enumerate(order[x]):
		if deg[y] == 1:
			deg[y] -= 1
			if i == 0:
				val = dpacc2[x][l - 2]
			elif i == l - 1:
				val = dpacc1[x][l - 2]
			else:
				val = dpacc1[x][i - 1] * dpacc2[x][l - i - 2] % mod
			dp[y].append(val + 1)
			order[y].append(x)
			stack.append(y)
for i in range(1, n + 1):
	ans = 1
	for x in dp[i]:
		ans *= x
		ans %= mod
	print(ans)


(n, m, *t) = map(int, open(0).read().split())
e = [[] for _ in range(n)]
for (a, b) in zip(*[iter(t)] * 2):
	e[a - 1] += (b - 1,)
	e[b - 1] += (a - 1,)
o = []
s = [0]
f = [1] * n
for v in s:
	o += (v,)
	f[v] = 0
	t = []
	for w in e[v]:
		if f[w]:
			s += (w,)
			t += (w,)
	e[v] = t
dp1 = [0] * n
c = [[] for _ in range(n)]
for v in o[::-1]:
	(x, y) = ([1], [1])
	for w in e[v]:
		x += (x[-1] * (dp1[w] + 1) % m,)
	for w in e[v][::-1]:
		y += (y[-1] * (dp1[w] + 1) % m,)
	dp1[v] = x[-1]
	c[v] = (x, y[-2::-1])
dp2 = [1] + [0] * n
for v in o:
	for (w, x, y) in zip(e[v], *c[v]):
		dp2[w] = (dp2[v] * x * y + 1) % m
for (x, y) in zip(dp1, dp2):
	print(x * y % m)


import sys
sys.setrecursionlimit(10 ** 9)
input = sys.stdin.readline
(n, mod) = map(int, input().split())
graph = [[] for _ in range(n)]
for _ in range(n - 1):
	(a, b) = map(int, input().split())
	a -= 1
	b -= 1
	graph[a].append(b)
	graph[b].append(a)
ele_id = 1
dp = [[ele_id] * len(graph[i]) for i in range(n)]
ans = [ele_id] * n
add_func = lambda x: x + 1
merge_func = lambda a, b: a * b % mod

def dfs1(v, v_p):
	dp_cum = ele_id
	for (i, v_next) in enumerate(graph[v]):
		if v_next == v_p:
			continue
		dp[v][i] = dfs1(v_next, v)
		dp_cum = merge_func(dp_cum, dp[v][i])
	return add_func(dp_cum)

def dfs2(v, v_p, dp_vp):
	for (i, v_next) in enumerate(graph[v]):
		if v_next == v_p:
			dp[v][i] = dp_vp
	dp_l = [ele_id] * (len(graph[v]) + 1)
	dp_r = [ele_id] * (len(graph[v]) + 1)
	for i in range(len(graph[v])):
		dp_l[i + 1] = merge_func(dp_l[i], dp[v][i])
	for i in reversed(range(len(graph[v]))):
		dp_r[i] = merge_func(dp_r[i + 1], dp[v][i])
	ans[v] = add_func(dp_l[-1])
	for (i, v_next) in enumerate(graph[v]):
		if v_next == v_p:
			continue
		dfs2(v_next, v, add_func(merge_func(dp_l[i], dp_r[i + 1])))
dfs1(0, -1)
dfs2(0, -1, ele_id)
for ans_i in ans:
	print(ans_i - 1)


import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 6)

def dfs(v, p=-1):
	deg[v] = len(U[v])
	dp[v] = [0] * deg[v]
	ans = 1
	for i in range(deg[v]):
		u = U[v][i]
		if u == p:
			par[v] = i
			continue
		dp[v][i] = dfs(u, v)
		ans *= dp[v][i] + 1
		ans %= M
	return ans

def bfs(v, ans_p=0, p=-1):
	if p != -1:
		dp[v][par[v]] = ans_p
	lmul = [1] * (deg[v] + 1)
	rmul = [1] * (deg[v] + 1)
	for i in range(1, deg[v] + 1):
		lmul[i] = lmul[i - 1] * (dp[v][i - 1] + 1) % M
		rmul[-i - 1] = rmul[-i] * (dp[v][-i] + 1) % M
	ans[v] = rmul[0]
	for i in range(deg[v]):
		u = U[v][i]
		if u == p:
			continue
		bfs(u, lmul[i] * rmul[i + 1] % M, v)
(N, M) = map(int, input().split())
U = [list() for _ in range(N)]
for (x, y) in [map(int, input().split()) for _ in range(N - 1)]:
	U[x - 1].append(y - 1)
	U[y - 1].append(x - 1)
deg = [0] * N
par = [0] * N
dp = [None] * N
ans = [0] * N
dfs(0)
bfs(0)
print('\n'.join([str(x) for x in ans]))


def I():
	return int(input())

def MI():
	return map(int, input().split())

def LI():
	return list(map(int, input().split()))

def main():
	(N, M) = MI()
	adj = [[] for _ in range(N)]
	for i in range(N - 1):
		(x, y) = MI()
		x -= 1
		y -= 1
		adj[x].append(y)
		adj[y].append(x)
	import queue
	P = [-1] * N
	Q = queue.Queue()
	R = []
	Q.put(0)
	while not Q.empty():
		v = Q.get()
		R.append(v)
		for nv in adj[v]:
			if nv != P[v]:
				P[nv] = v
				adj[nv].remove(v)
				Q.put(nv)
	unit = 1
	merge = lambda a, b: a * b % M
	adj_bu = lambda a, v: a + 1
	adj_td = lambda a, v, p: a + 1
	adj_fin = lambda a, i: a
	ME = [unit] * N
	dp = [0] * N
	for v in R[1:][::-1]:
		dp[v] = adj_bu(ME[v], v)
		p = P[v]
		ME[p] = merge(ME[p], dp[v])
	dp[R[0]] = adj_fin(ME[R[0]], R[0])
	TD = [unit] * N
	for v in R:
		ac = TD[v]
		for nv in adj[v]:
			TD[nv] = ac
			ac = merge(ac, dp[nv])
		ac = unit
		for nv in adj[v][::-1]:
			TD[nv] = adj_td(merge(TD[nv], ac), nv, v)
			ac = merge(ac, dp[nv])
			dp[nv] = adj_fin(merge(ME[nv], TD[nv]), nv)
	for i in range(N):
		print(dp[i])
main()


import sys, bisect, math, itertools, heapq, collections
from operator import itemgetter
from functools import lru_cache
import copy
input = sys.stdin.readline
INF = float('inf')
mod = 10 ** 9 + 7
eps = 10 ** (-7)

def inp():
	return int(input())

def inpl():
	return list(map(int, input().split()))

def str_inp():
	return list(input()[:-1])
unit = 1

def merge(a, b):
	return a * b % M

def adj_bu(a, i):
	return a + 1

def adj_td(a, i, p):
	return a + 1

def adj_fin(a, i):
	return a
(n, M) = inpl()
graph = [[] for _ in range(n)]
for i in range(n - 1):
	(a, b) = inpl()
	graph[a - 1].append(b - 1)
	graph[b - 1].append(a - 1)
parent = [-1] * n
root = 0
queue = collections.deque([root])
sorted_graph = []
while queue:
	i = queue.popleft()
	sorted_graph.append(i)
	for a in graph[i]:
		if a != parent[i]:
			parent[a] = i
			graph[a].remove(i)
			queue.append(a)
BU = [unit] * n
res = [0] * n
for i in sorted_graph[1:][::-1]:
	res[i] = adj_bu(BU[i], i)
	p = parent[i]
	BU[p] = merge(BU[p], res[i])
res[sorted_graph[0]] = adj_fin(BU[sorted_graph[0]], sorted_graph[0])
TD = [unit] * n
for i in sorted_graph:
	tmp = TD[i]
	for j in graph[i]:
		TD[j] = tmp
		tmp = merge(tmp, res[j])
	tmp = unit
	for j in graph[i][::-1]:
		TD[j] = adj_td(merge(TD[j], tmp), j, i)
		tmp = merge(tmp, res[j])
		res[j] = adj_fin(merge(BU[j], TD[j]), j)
print(*res, sep='\n')


import sys
sys.setrecursionlimit(4100000)

def os():
	return input()

def oi():
	return int(input())

def oli():
	return map(int, input().split())

def olai():
	return list(map(int, input().split()))

def olas():
	return list(input().split())

def mlai(L):
	return [int(input()) for _ in range(L)]

def mlas(L):
	return [input() for _ in range(L)]

def ar(a, b, c=-1, d=-1, INIT=0):
	if c == -1:
		return [[INIT] * b for _ in range(a)]
	if d == -1:
		return [[[INIT] * c for _ in range(b)] for __ in range(a)]
	return [[[[INIT] * d for _ in range(c)] for __ in range(b)] for ___ in range(a)]
(n, m) = oli()
zero = 1

def step(x):
	return x + 1

def merge(x, y):
	return x * y % m
G = [[] for _ in range(100001)]
down_data = [zero for _ in range(100001)]
dat = [zero for _ in range(100001)]

def dfs(now, parent):
	cnt = 0
	for to in G[now]:
		if to == parent:
			continue
		cnt += 1
		dfs(to, now)
		down_data[now] = merge(down_data[now], step(down_data[to]))

def dfs_rev(now, parent, rev):
	left = []
	right = []
	cnt = 0
	for to in G[now]:
		if to == parent:
			continue
		if len(left) == 0:
			left.append(step(down_data[to]))
		else:
			left.append(merge(left[cnt - 1], step(down_data[to])))
		cnt += 1
	cnt = 0
	for to in reversed(G[now]):
		if to == parent:
			continue
		if len(right) == 0:
			right.append(step(down_data[to]))
		else:
			right.append(merge(right[cnt - 1], step(down_data[to])))
		cnt += 1
	cnt = 0
	dat[now] = merge(rev, down_data[now])
	for to in G[now]:
		if to == parent:
			continue
		x = zero if cnt == 0 else left[cnt - 1]
		y = zero if cnt == len(right) - 1 else right[len(right) - 2 - cnt]
		dfs_rev(to, now, step(merge(rev, merge(x, y))))
		cnt += 1

def calc(N):
	root = -1
	for i in range(1, N + 1):
		if len(G[i]) == 1 or len(G[i]) == 0:
			root = i
			break
	dfs(root, -1)
	dfs_rev(root, -1, zero)
for i in range(n - 1):
	(a, b) = oli()
	G[a].append(b)
	G[b].append(a)
calc(n)
for i in range(1, n + 1):
	print(dat[i])


import sys
input = sys.stdin.readline
from collections import deque
(N, m) = map(int, input().split())
X = [[] for i in range(N)]
for i in range(N - 1):
	(x, y) = map(int, input().split())
	X[x - 1].append(y - 1)
	X[y - 1].append(x - 1)
P = [-1] * N
Q = deque([0])
R = []
while Q:
	i = deque.popleft(Q)
	R.append(i)
	for a in X[i]:
		if a != P[i]:
			P[a] = i
			X[a].remove(i)
			deque.append(Q, a)
unit = 1
merge = lambda a, b: a * b % m
adj_bu = lambda a, i: a + 1
adj_td = lambda a, i, p: a + 1
adj_fin = lambda a, i: a
ME = [unit] * N
XX = [0] * N
TD = [unit] * N
for i in R[1:][::-1]:
	XX[i] = adj_bu(ME[i], i)
	p = P[i]
	ME[p] = merge(ME[p], XX[i])
XX[R[0]] = adj_fin(ME[R[0]], R[0])
for i in R:
	ac = TD[i]
	for j in X[i]:
		TD[j] = ac
		ac = merge(ac, XX[j])
	ac = unit
	for j in reversed(X[i]):
		TD[j] = adj_td(merge(TD[j], ac), j, i)
		ac = merge(ac, XX[j])
		XX[j] = adj_fin(merge(ME[j], TD[j]), j)
print(*XX, sep='\n')


from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
from bisect import bisect_right, bisect_left
import random
from itertools import permutations, accumulate, combinations, product
import sys
import string
from bisect import bisect_left, bisect_right
from math import factorial, ceil, floor, gamma, log
from operator import mul
from functools import reduce
from copy import deepcopy
sys.setrecursionlimit(2147483647)
INF = 10 ** 20

def LI():
	return list(map(int, sys.stdin.readline().split()))

def I():
	return int(sys.stdin.readline())

def LS():
	return sys.stdin.buffer.readline().rstrip().split()

def S():
	return sys.stdin.buffer.readline().rstrip().decode('utf-8')

def IR(n):
	return [I() for i in range(n)]

def LIR(n):
	return [LI() for i in range(n)]

def SR(n):
	pass

def LSR(n):
	return [LS() for i in range(n)]

def SRL(n):
	return [list(S()) for i in range(n)]

def MSRL(n):
	return [[int(j) for j in list(S())] for i in range(n)]
(n, mod) = LI()
G = [[] for _ in range(n)]
for _ in range(n - 1):
	(a, b) = LI()
	G[a - 1] += [b - 1]
	G[b - 1] += [a - 1]
dp = [-1] * n
par = [-1] * n

def f(u):
	ret = 1
	for v in G[u]:
		if v == par[u]:
			continue
		par[v] = u
		ret = ret * f(v)
	dp[u] = ret
	if u:
		return ret + 1
f(0)
ans = [0] * n
ans[0] = dp[0]
par_acc = [1] * n
dp2 = [1] * n
q = deque([0])
while q:
	u = q.pop()
	ans[u] = dp[u] * dp2[u] % mod
	L1 = [1]
	L2 = []
	D = {}
	cnt = 0
	for v in G[u]:
		if par[u] == v:
			continue
		L1 += [dp[v] + 1]
		L2 += [dp[v] + 1]
		D[cnt] = v
		q += [v]
		cnt += 1
	L2 += [1]
	if len(L1) > 2:
		for i in range(len(L1) - 2):
			L1[i + 2] = L1[i + 2] * L1[i + 1] % mod
			L2[-i - 3] = L2[-i - 3] * L2[-i - 2] % mod
	for j in D:
		dp2[D[j]] = (L1[j] * L2[j + 1] * dp2[u] + 1) % mod
print(*ans, sep='\n')


class ReRooting(object):

	def merge(self, a, b):
		return a * b % M

	def adj_bu(self, a, v: int):
		return a + 1

	def adj_td(self, a, v: int, p: int):
		return a + 1

	def adj_fin(self, a, v: int):
		return a

	def __init__(self, V: int, e: int):
		self.V = V
		self.e = e
		self.edge = [[] for _ in range(V)]
		self.par = [-1] * V
		self.order = []

	def add_edge(self, u: int, v: int):
		self.edge[u].append(v)
		self.edge[v].append(u)

	def topological_sort(self, root: int=0):
		from collections import deque
		que = deque([root])
		while que:
			v = que.popleft()
			self.order.append(v)
			for w in self.edge[v]:
				if w != self.par[v]:
					self.par[w] = v
					self.edge[w].remove(v)
					que.append(w)

	def bottom_up(self):
		root = self.order[0]
		accBU = [self.e] * self.V
		resBU = [self.e] * self.V
		for v in reversed(self.order):
			resBU[v] = self.adj_bu(accBU[v], v)
			if v == root:
				break
			p = self.par[v]
			accBU[p] = self.merge(accBU[p], resBU[v])
		return (accBU, resBU)

	def top_down(self, resBU: list):
		accTD = [self.e] * self.V
		resTD = [self.e] * self.V
		for p in self.order:
			ac = resTD[p]
			for v in self.edge[p]:
				accTD[v] = ac
				ac = self.merge(ac, resBU[v])
			ac = self.e
			for v in reversed(self.edge[p]):
				accTD[v] = self.merge(accTD[v], ac)
				ac = self.merge(ac, resBU[v])
				resTD[v] = self.adj_td(accTD[v], v, p)
		return resTD

	def solve(self):
		self.topological_sort()
		(accBU, resBU) = self.bottom_up()
		resTD = self.top_down(resBU)
		res = [self.adj_fin(self.merge(a, b), v) for (v, (a, b)) in enumerate(zip(accBU, resTD))]
		return res
(N, M) = map(int, input().split())
RR = ReRooting(N, 1)
for _ in range(N - 1):
	(x, y) = map(int, input().split())
	RR.add_edge(x - 1, y - 1)
print(*RR.solve(), sep='\n')


def ReRooting(nodeCount, edges, identity, merge, addNode):
	adjacents = [[] for _ in range(nodeCount)]
	indexForAdjacents = [[] for _ in range(nodeCount)]
	for (u, v) in edges:
		indexForAdjacents[v].append(len(adjacents[u]))
		indexForAdjacents[u].append(len(adjacents[v]))
		adjacents[u].append(v)
		adjacents[v].append(u)
	childSubtreeRes = [[identity] * len(adjacents[i]) for i in range(nodeCount)]
	nodeRes = [identity] * nodeCount
	parents = [-1] * nodeCount
	order = [0] * nodeCount
	index = 0
	stack = [0]
	for node in stack:
		order[index] = node
		index += 1
		for adjacent in adjacents[node]:
			if adjacent == parents[node]:
				continue
			stack.append(adjacent)
			parents[adjacent] = node
	for node in order[::-1]:
		parent = parents[node]
		result = identity
		parentIndex = -1
		for j in range(len(adjacents[node])):
			if adjacents[node][j] == parent:
				parentIndex = j
				continue
			result = merge(result, childSubtreeRes[node][j])
		if parentIndex >= 0:
			childSubtreeRes[parent][indexForAdjacents[node][parentIndex]] = addNode(result, node)
	for node in order:
		accumsFromTail = [identity] * len(adjacents[node])
		for j in range(len(accumsFromTail) - 1, 0, -1):
			accumsFromTail[j - 1] = merge(childSubtreeRes[node][j], accumsFromTail[j])
		accum = identity
		for j in range(len(accumsFromTail)):
			result = addNode(merge(accum, accumsFromTail[j]), node)
			childSubtreeRes[adjacents[node][j]][indexForAdjacents[node][j]] = result
			accum = merge(accum, childSubtreeRes[node][j])
		nodeRes[node] = addNode(accum, node)
	return nodeRes
(n, mod) = map(int, input().split())
edge = []
for _ in range(n - 1):
	(x, y) = map(int, input().split())
	x -= 1
	y -= 1
	edge.append((x, y))

def merge(a, b):
	return a * b % mod

def addNode(a, id):
	return a + 1
for i in ReRooting(n, edge, 1, merge, addNode):
	print(i - 1)


import sys
sys.setrecursionlimit(10 ** 8)
(N, M) = map(int, input().split())
XY = [tuple(map(int, input().split())) for i in range(N - 1)]
es = [[] for _ in range(N)]
for (i, (x, y)) in enumerate(XY):
	(x, y) = (x - 1, y - 1)
	es[x].append((y, i))
	es[y].append((x, i))
if N == 1:
	print(1)
	exit()
dpdn = [-1] * (N - 1)
parent = [-1] * N

def dfs(v, p=-1):
	ret = 1
	for (to, i) in es[v]:
		if to == p:
			continue
		parent[to] = v
		r = dfs(to, v)
		dpdn[i] = r
		ret *= r
	ret += 1
	ret %= M
	return ret
dfs(0)
dpup = [-1] * (N - 1)
from collections import deque
q = deque([(0, -1)])
while q:
	(v, e) = q.popleft()
	lc = [1]
	for (_, i) in es[v]:
		if i == e:
			continue
		lc.append(lc[-1] * dpdn[i] % M)
	rc = [1]
	for (_, i) in reversed(es[v]):
		if i == e:
			continue
		rc.append(rc[-1] * dpdn[i] % M)
	rc.reverse()
	p = 1 if e == -1 else dpup[e]
	j = 0
	for (to, i) in es[v]:
		if i == e:
			continue
		dpup[i] = (p * lc[j] * rc[j + 1] + 1) % M
		j += 1
		q.append((to, i))
ans = []
for v in range(N):
	r = 1
	for (to, i) in es[v]:
		if to == parent[v]:
			r *= dpup[i]
		else:
			r *= dpdn[i]
	r %= M
	ans.append(r)
print(*ans, sep='\n')


from collections import deque
import sys
input = sys.stdin.buffer.readline
(n, m) = map(int, input().split())
deg = [0] * (n + 1)
graph = [[] for _ in range(n + 1)]
for _ in range(n - 1):
	(x, y) = map(int, input().split())
	graph[x].append(y)
	graph[y].append(x)
	deg[x] += 1
	deg[y] += 1
dp1 = [0] * (n + 1)
dp2 = [0] * (n + 1)
start = 1
par = [-1] * (n + 1)
que = deque([start])
topo = []
while que:
	v = que.popleft()
	topo.append(v)
	for i in range(deg[v]):
		u = graph[v][i]
		if par[v] == u:
			continue
		par[u] = v
		que.append(u)
dpl = [[] for _ in range(n + 1)]
dpr = [[] for _ in range(n + 1)]
edge_num = [{} for _ in range(n + 1)]
for v in topo[::-1]:
	temp = 1
	for i in range(deg[v]):
		u = graph[v][i]
		edge_num[v][u] = i
		if u == par[v]:
			dpl[v].append(temp)
			continue
		temp *= dp1[u] + 1
		temp %= m
		dpl[v].append(temp)
	dp1[v] = temp
	temp = 1
	for i in range(deg[v] - 1, -1, -1):
		u = graph[v][i]
		if u == par[v]:
			dpr[v].append(temp)
			continue
		temp *= dp1[u] + 1
		temp %= m
		dpr[v].append(temp)
dp = [0] * (n + 1)
for v in topo:
	p = par[v]
	if p == -1:
		dp[v] = dp1[v]
		dp[v] %= m
		continue
	idx = edge_num[p][v]
	num = deg[p]
	dp2[v] = 1
	if idx - 1 >= 0:
		dp2[v] *= dpl[p][idx - 1]
		dp2[v] %= m
	if num - 2 - idx >= 0:
		dp2[v] *= dpr[p][num - 2 - idx]
		dp2[v] %= m
	pp = par[p]
	if pp != -1:
		dp2[v] *= dp2[p] + 1
		dp2[v] %= m
	dp[v] = dp1[v] * (dp2[v] + 1)
	dp[v] %= m
print(*dp[1:], sep='\n')


import sys
input = sys.stdin.readline
from collections import deque
from functools import reduce
f = lambda a: (a + 1) % M
g = lambda a, b: a * b % M
init = 1
(N, M) = map(int, input().split())
X = [[] for i in range(N)]
for i in range(N - 1):
	(x, y) = map(int, input().split())
	X[x - 1].append(y - 1)
	X[y - 1].append(x - 1)
P = [-1] * N
Q = deque([0])
T = []
while Q:
	i = deque.popleft(Q)
	T.append(i)
	for a in X[i]:
		if a != P[i]:
			P[a] = i
			X[a].remove(i)
			deque.append(Q, a)
BU = [0] * N
TD = [1] * N
for i in T[::-1]:
	BU[i] = reduce(g, [f(BU[j]) for j in X[i]]) if len(X[i]) else init
for i in T:
	B = [1] * (len(X[i]) + 1)
	for (k, j) in enumerate(X[i]):
		B[k + 1] = g(B[k], f(BU[j]))
	a = init
	for k in range(len(X[i]))[::-1]:
		j = X[i][k]
		TD[j] = f(g(TD[i], g(a, B[k])))
		a = g(a, f(BU[j]))
for t in [g(a, b) for (a, b) in zip(BU, TD)]:
	print(t)


INF = 10 ** 11
import sys
sys.setrecursionlimit(100000000)
(N, M) = map(int, input().split())
MOD = M
G = [[] for _ in range(N)]
for _ in range(N - 1):
	(x, y) = map(int, input().split())
	x -= 1
	y -= 1
	G[x].append(y)
	G[y].append(x)
deg = [0] * N
dp = [None] * N
parents = [0] * N
ans = [0] * N

def dfs(v, p=-1):
	deg[v] = len(G[v])
	res = 1
	dp[v] = [0] * deg[v]
	for (i, e) in enumerate(G[v]):
		if e == p:
			parents[v] = i
			continue
		dp[v][i] = dfs(e, v)
		res *= dp[v][i] + 1
		res %= MOD
	return res

def bfs(v, res_p=0, p=-1):
	if p != -1:
		dp[v][parents[v]] = res_p
	dpl = [1] * (deg[v] + 1)
	dpr = [1] * (deg[v] + 1)
	for i in range(deg[v]):
		dpl[i + 1] = dpl[i] * (dp[v][i] + 1) % MOD
	for i in range(deg[v] - 1, -1, -1):
		dpr[i] = dpr[i + 1] * (dp[v][i] + 1) % MOD
	ans[v] = dpr[0]
	for i in range(deg[v]):
		e = G[v][i]
		if e == p:
			continue
		bfs(e, dpl[i] * dpr[i + 1] % MOD, v)
dfs(0)
bfs(0)
print('\n'.join(map(str, ans)))


import sys
input = sys.stdin.readline
from collections import deque
(N, M) = map(int, input().split())
X = [[] for i in range(N)]
for i in range(N - 1):
	(x, y) = map(int, input().split())
	X[x - 1].append(y - 1)
	X[y - 1].append(x - 1)
P = [-1] * N
Q = deque([0])
R = []
while Q:
	i = deque.popleft(Q)
	R.append(i)
	for a in X[i]:
		if a != P[i]:
			P[a] = i
			X[a].remove(i)
			deque.append(Q, a)
BU = [0] * N
TD = [1] * N
for i in R[::-1]:
	a = 1
	for j in X[i]:
		a = a * (BU[j] + 1) % M
	BU[i] = a
for i in R:
	c = len(X[i])
	AL = [1] * (c + 1)
	AR = [1] * (c + 1)
	for j in range(c):
		AL[j + 1] = AL[j] * (BU[X[i][j]] + 1) % M
	for j in range(c)[::-1]:
		AR[j] = AR[j + 1] * (BU[X[i][j]] + 1) % M
	for j in range(c):
		TD[X[i][j]] = (TD[i] * AL[j] * AR[j + 1] + 1) % M
for i in range(N):
	print(BU[i] * TD[i] % M)


from collections import *
import sys
sys.setrecursionlimit(10 ** 6)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep='\n')

def MI():
	return map(int, sys.stdin.readline().split())

def LI():
	return list(map(int, sys.stdin.readline().split()))

def LLI(rows_number):
	return [LI() for _ in range(rows_number)]
(n, m) = MI()
to = defaultdict(list)
dp = {}

def dfs(u=0, pu=-1):
	res = 1
	for v in to[u]:
		if v == pu:
			continue
		res *= dfs(v, u) + 1
		res %= m
	if pu != -1:
		dp[pu, u] = res
	return res

def main():
	for _ in range(n - 1):
		(x, y) = map(int1, input().split())
		to[x].append(y)
		to[y].append(x)
	dfs()
	que = deque()
	que.append([0, -1])
	while que:
		(u, pu) = que.popleft()
		tn = len(to[u])
		ll = [0] * tn
		rr = [0] * tn
		for (i, v) in enumerate(to[u]):
			ll[i] = rr[i] = dp[u, v] + 1
		for i in range(1, tn):
			ll[i] = ll[i - 1] * ll[i] % m
			rr[tn - 1 - i] = rr[tn - i] * rr[tn - 1 - i] % m
		ll += [1]
		rr += [1]
		for (i, v) in enumerate(to[u]):
			if v == pu:
				continue
			dp[v, u] = ll[i - 1] * rr[i + 1] % m
			que.append([v, u])
	for u in range(n):
		ans = 1
		for v in to[u]:
			ans = ans * (dp[u, v] + 1) % m
		print(ans)
main()


from collections import deque
import sys
sys.setrecursionlimit(10 ** 9 + 7)

def dfs1(pos, par, e=1):
	for child in tree[pos]:
		if child == par:
			continue
		tmp = st_val[child]
		e *= 1 + tmp
		e %= MOD
	st_val[pos] = e
	return st_val[pos]

def dfs2(pos, par, e=1):
	for child in tree[pos]:
		if child == par:
			ind = compress[par][pos]
			tmp = ruiseki_l[par][ind] * ruiseki_r[par][len(tree[par]) - ind - 1]
		else:
			tmp = st_val[child]
		e *= 1 + tmp
		e %= MOD
		ind = compress[pos][child]
		re_subtree_val[pos][ind] = 1 + tmp
	for i in range(len(tree[pos])):
		ruiseki_l[pos][i + 1] = ruiseki_l[pos][i] * re_subtree_val[pos][i]
		ruiseki_l[pos][i + 1] %= MOD
	for i in range(len(tree[pos])):
		ruiseki_r[pos][i + 1] = ruiseki_r[pos][i] * re_subtree_val[pos][-i - 1]
		ruiseki_r[pos][i + 1] %= MOD
	ans[pos] = e

def topological_sort(root, par=-1):
	q = deque([(root, par)])
	res = [(root, par)]
	while q:
		(pos, par) = q.pop()
		for child in tree[pos]:
			if child == par:
				continue
			else:
				q.append((child, pos))
				res.append((child, pos))
	return res
(n, m) = map(int, input().split())
MOD = m
info = [list(map(int, input().split())) for i in range(n - 1)]
tree = [[] for i in range(n)]
for i in range(n - 1):
	(a, b) = info[i]
	a -= 1
	b -= 1
	tree[a].append(b)
	tree[b].append(a)
preorder_list = topological_sort(0, par=-1)
st_val = [0] * n
for (pos, par) in reversed(preorder_list):
	dfs1(pos, par)
re_subtree_val = [[1] * len(tree[i]) for i in range(n)]
ruiseki_l = [[1] * (len(tree[i]) + 1) for i in range(n)]
ruiseki_r = [[1] * (len(tree[i]) + 1) for i in range(n)]
compress = [{v: j for (j, v) in enumerate(tree[i])} for i in range(n)]
ans = [0] * n
for (pos, par) in preorder_list:
	dfs2(pos, par)
for i in range(n):
	print(ans[i] % MOD)


from functools import reduce

def rerooting(N, adj, merge, identity, finalize):
	order = [None] * N
	parent = [None] * N
	parent[0] = -1
	stack = [0]
	for i in range(N):
		v = stack.pop()
		order[i] = v
		for u in adj[v]:
			if parent[u] is None:
				parent[u] = v
				stack.append(u)
	dp_down = [None] * N
	for v in reversed(order[1:]):
		p = parent[v]
		dp_down[v] = finalize(reduce(merge, (dp_down[c] for c in adj[v] if c != p), identity))
	dp_up = [None] * N
	dp_up[0] = identity
	for v in order:
		if len(adj[v]) == 1 and adj[v][0] == parent[v]:
			continue
		p = parent[v]
		left = [dp_up[v]]
		for u in adj[v]:
			if u != p:
				left.append(merge(left[-1], dp_down[u]))
		right = [identity]
		for u in reversed(adj[v]):
			if u != p:
				right.append(merge(dp_down[u], right[-1]))
		i = 0
		for u in adj[v]:
			if u != p:
				dp_up[u] = finalize(merge(left[i], right[-i - 2]))
				i += 1
	for (v, l) in enumerate(adj):
		order[v] = reduce(merge, (dp_down[u] for u in adj[v] if u != parent[v]), identity)
		order[v] = finalize(merge(order[v], dp_up[v]))
	return order

def solve(N, M, E):
	adj = [[] for _ in range(N)]
	for (a, b) in E:
		adj[a].append(b)
		adj[b].append(a)

	def merge(x, y):
		return x * y % M

	def finalize(x):
		return x + 1
	res = rerooting(N, adj, merge, 1, finalize)
	return [v - 1 for v in res]
(N, M) = map(int, input().split())
E = [tuple(map(lambda x: int(x) - 1, input().split())) for _ in range(N - 1)]
print(*solve(N, M, E), sep='\n')


import sys
input = sys.stdin.readline
sys.setrecursionlimit(100000000)
MOD = 10 ** 9 + 7
INF = 10 ** 10
MAXN = 100005
G = [[] for _ in range(MAXN)]
dp = [[] for _ in range(MAXN)]
deg = [0] * MAXN
parents = [-1] * MAXN
result = [0] * MAXN

def dfs1(v, mod, p=-1):
	ans = 1
	for i in range(deg[v]):
		e = G[v][i]
		if e == p:
			parents[v] = i
			continue
		dp[v][i] = dfs1(e, mod, v)
		ans *= dp[v][i] + 1
		ans %= mod
	return ans % mod

def dfs2(v, mod, res_p=1, p=-1):
	if p != -1:
		dp[v][parents[v]] = res_p
	cuml = [1] * (deg[v] + 1)
	cumr = [1] * (deg[v] + 1)
	for i in range(deg[v]):
		cuml[i + 1] = cuml[i] * (1 + dp[v][i]) % mod
	for i in range(deg[v] - 1, -1, -1):
		cumr[i] = cumr[i + 1] * (1 + dp[v][i]) % mod
	result[v] = cumr[0]
	for i in range(deg[v]):
		e = G[v][i]
		if e == p:
			continue
		dfs2(e, mod, cuml[i] * cumr[i + 1] % mod, v)

def main():
	(n, m) = map(int, input().split())
	for _ in range(n - 1):
		(x, y) = map(int, input().split())
		x -= 1
		y -= 1
		G[x].append(y)
		G[y].append(x)
	for i in range(n):
		deg[i] = len(G[i])
		dp[i] = [1] * deg[i]
	dfs1(0, m)
	dfs2(0, m)
	for i in range(n):
		print(result[i])
main()


import sys
sys.setrecursionlimit(10 ** 7)
input = sys.stdin.readline

class Tree:

	def __init__(self, crdinal, adjgrph, root):
		self.n = crdinal
		self.g = adjgrph
		self.root = root
		self.parent = [-1] * self.n
		self.depth = [-1] * self.n
		self.subsize = [1] * self.n
		self.result = [1] * self.n
		s = [self.root]
		while s:
			v = s.pop()
			if self.depth[v] == -1:
				if v == self.root:
					self.depth[v] = 0
				else:
					self.depth[v] = self.depth[self.parent[v]] + 1
					s.append(v)
				for w in self.g[v]:
					if self.depth[w] == -1:
						self.parent[w] = v
						s.append(w)
			else:
				self.subsize[self.parent[v]] += self.subsize[v]
				self.calc(v)

	def calc(self, v):
		self.result[self.parent[v]] *= self.result[v] + 1
		self.result[self.parent[v]] %= m
		return None

	def wanted(self):
		return self.parent

	def rerooting(self) -> list:
		cum1 = [[1] for i in range(n)]
		cum2 = [[1] for i in range(n)]
		FromParent = [0] * n
		ans = [0] * n
		ans[0] = self.result[0]
		s = [self.root]
		while s:
			v = s.pop()
			if v != self.root:
				ans[v] = (FromParent[v] + 1) * self.result[v]
				ans[v] %= m
			for w in self.g[v]:
				if w != self.parent[v]:
					cum1[v].append(cum1[v][-1] * (self.result[w] + 1) % m)
					s.append(w)
				else:
					cum1[v].append(cum1[v][-1] * (FromParent[v] + 1) % m)
			for w in self.g[v][::-1]:
				if w != self.parent[v]:
					cum2[v].append(cum2[v][-1] * (self.result[w] + 1) % m)
				else:
					cum2[v].append(cum2[v][-1] * (FromParent[v] + 1) % m)
			cum2[v] = cum2[v][::-1]
			for (i, w) in enumerate(self.g[v]):
				FromParent[w] = cum1[v][i] * cum2[v][i + 1] % m
		return ans
(n, m) = map(int, input().split())
g = [[] for _ in range(n)]
for _ in range(n - 1):
	(x, y) = map(int, input().split())
	g[x - 1].append(y - 1)
	g[y - 1].append(x - 1)
T1 = Tree(n, g, 0)
ans = T1.rerooting()
for x in T1.rerooting():
	print(x)


from collections import defaultdict

class ReRooting:

	def __init__(self, f, g, merge, ie):
		self.tree = defaultdict(list)
		self.f = f
		self.g = g
		self.merge = merge
		self.ie = ie
		self.dp = defaultdict(dict)

	def add_edge(self, u, v):
		self.tree[u].append(v)
		self.tree[v].append(u)

	def __dfs1(self, u, p):
		o = []
		s = [(u, -1)]
		while s:
			(u, p) = s.pop()
			o.append((u, p))
			for v in self.tree[u]:
				if v == p:
					continue
				s.append((v, u))
		for (u, p) in reversed(o):
			r = self.ie
			for v in self.tree[u]:
				if v == p:
					continue
				r = self.merge(r, self.f(self.dp[u][v], v))
			self.dp[p][u] = self.g(r, u)

	def __dfs2(self, u, p, a):
		s = [(u, p, a)]
		while s:
			(u, p, a) = s.pop()
			self.dp[u][p] = a
			pl = [0] * (len(self.tree[u]) + 1)
			pl[0] = self.ie
			for (i, v) in enumerate(self.tree[u]):
				pl[i + 1] = self.merge(pl[i], self.f(self.dp[u][v], v))
			pr = [0] * (len(self.tree[u]) + 1)
			pr[-1] = self.ie
			for (i, v) in reversed(list(enumerate(self.tree[u]))):
				pr[i] = self.merge(pr[i + 1], self.f(self.dp[u][v], v))
			for (i, v) in enumerate(self.tree[u]):
				if v == p:
					continue
				r = self.merge(pl[i], pr[i + 1])
				s.append((v, u, self.g(r, v)))

	def build(self, root=1):
		self.__dfs1(root, -1)
		self.__dfs2(root, -1, self.ie)

	def slv(self, u):
		r = self.ie
		for v in self.tree[u]:
			r = self.merge(r, self.f(self.dp[u][v], v))
		return r

def atcoder_dp_dp_v():
	(N, M) = map(int, input().split())
	XY = [list(map(int, input().split())) for _ in range(N - 1)]
	f = lambda x, y: x
	g = lambda x, y: x + 1
	merge = lambda x, y: x * y % M
	rr = ReRooting(f, g, merge, 1)
	for (x, y) in XY:
		rr.add_edge(x, y)
	rr.build()
	for u in range(1, N + 1):
		print(rr.slv(u))
atcoder_dp_dp_v()


import sys
input = sys.stdin.readline
(N, MOD) = map(int, input().split())
G = [[] for _ in range(N + 1)]
for _ in range(N - 1):
	(x, y) = map(int, input().split())
	G[x].append(y)
	G[y].append(x)
G[0].append(1)
G[1].append(0)
DP1 = [0] * (N + 1)
parent = [-1] * (N + 1)
parent[1] = 0
order = []
order_append = order.append
stack = [1]
stack_pop = stack.pop
stack_append = stack.append
while stack:
	x = stack_pop()
	order_append(x)
	for next_ in G[x]:
		if next_ == parent[x]:
			continue
		parent[next_] = x
		stack_append(next_)
for v in order[::-1]:
	tmp = 1
	for next_ in G[v]:
		tmp *= DP1[next_] + 1
		tmp %= MOD
	DP1[v] = tmp
DP2 = [1] * (N + 1)
for x in order:
	n = len(G[x])
	p = parent[x]
	lst1 = [1] * (n + 1)
	lst2 = [1] * (n + 1)
	for i in range(n):
		if G[x][i] == p:
			lst1[i + 1] = lst1[i] * DP2[x] % MOD
		else:
			lst1[i + 1] = lst1[i] * (DP1[G[x][i]] + 1) % MOD
		if G[x][n - 1 - i] == p:
			lst2[n - i - 1] = lst2[n - i] * DP2[x] % MOD
		else:
			lst2[n - i - 1] = lst2[n - i] * (DP1[G[x][n - 1 - i]] + 1) % MOD
	for i in range(n):
		if G[x][i] == p:
			continue
		tmp = lst1[i] * lst2[i + 1] % MOD
		tmp += 1
		DP2[G[x][i]] = tmp
for i in range(1, N + 1):
	print(DP1[i] * DP2[i] % MOD)


import sys

def getpar(Edge, p):
	N = len(Edge)
	par = [0] * N
	par[0] = -1
	par[p] - 1
	stack = [p]
	visited = set([p])
	while stack:
		vn = stack.pop()
		for vf in Edge[vn]:
			if vf in visited:
				continue
			visited.add(vf)
			par[vf] = vn
			stack.append(vf)
	return par

def topological_sort_tree(E, r):
	Q = [r]
	L = []
	visited = set([r])
	while Q:
		vn = Q.pop()
		L.append(vn)
		for vf in E[vn]:
			if vf not in visited:
				visited.add(vf)
				Q.append(vf)
	return L

def getcld(p):
	res = [[] for _ in range(len(p))]
	for (i, v) in enumerate(p[1:], 1):
		res[v].append(i)
	return res
(N, M) = map(int, input().split())
Edge = [[] for _ in range(N)]
for _ in range(N - 1):
	(a, b) = map(int, sys.stdin.readline().split())
	a -= 1
	b -= 1
	Edge[a].append(b)
	Edge[b].append(a)
P = getpar(Edge, 0)
L = topological_sort_tree(Edge, 0)
C = getcld(P)
dp1 = [1] * N
for l in L[N - 1:0:-1]:
	p = P[l]
	dp1[p] = dp1[p] * (dp1[l] + 1) % M
dp2 = [1] * N
dp2[0] = dp1[0]
info = [0] * (N + 1)
vidx = [0] * N
vmull = [None] * N
vmulr = [None] * N
for i in range(N):
	Ci = C[i]
	res = [1]
	for (j, c) in enumerate(Ci, 1):
		vidx[c] = j
		res.append(res[-1] * (1 + dp1[c]) % M)
	vmulr[i] = res + [1]
	res = [1]
	for c in Ci[::-1]:
		res.append(res[-1] * (1 + dp1[c]) % M)
	vmull[i] = [1] + res[::-1]
for l in L[1:]:
	p = P[l]
	pp = P[p]
	vi = vidx[l]
	res = vmulr[p][vi - 1] * vmull[p][vi + 1] % M
	res = res * (1 + info[pp]) % M
	dp2[l] = dp1[l] * (res + 1) % M
	info[p] = res % M
print(*dp2, sep='\n')


import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
import itertools
(N, MOD) = map(int, readline().split())
m = map(int, read().split())
XY = zip(m, m)
mult = lambda x, y: x * y % MOD
graph = [[] for _ in range(N + 1)]
for (x, y) in XY:
	graph[x].append(y)
	graph[y].append(x)
root = 1
parent = [0] * (N + 1)
order = []
stack = [root]
while stack:
	x = stack.pop()
	order.append(x)
	for y in graph[x]:
		if y == parent[x]:
			continue
		parent[y] = x
		stack.append(y)
dp1 = [0] * (N + 1)
for v in order[::-1]:
	x = 1
	for w in graph[v]:
		x *= dp1[w] + 1
		x %= MOD
	dp1[v] = x
dp2 = [1] * (N + 1)
for v in order:
	p = parent[v]
	arr = [dp1[c] + 1 if c != p else dp2[v] for c in graph[v]]
	from_left = [1] + list(itertools.accumulate(arr, mult))[:-1]
	from_right = list(itertools.accumulate(reversed(arr), mult))[-2::-1] + [1]
	prod = [x * y % MOD for (x, y) in zip(from_left, from_right)]
	for (c, x) in zip(graph[v], prod):
		if c != p:
			dp2[c] = 1 + x
answer = '\n'.join((str(x * y % MOD) for (x, y) in zip(dp1[1:], dp2[1:])))
print(answer)


from collections import deque
(N, M) = map(int, input().split())
d = [list() for _ in range(N + 1)]
for _ in range(N - 1):
	(a, b) = map(int, input().split())
	d[a].append(b)
	d[b].append(a)
queue = deque([1])
vs = set([1])
vs_bfs = list()
parents = [0] * (N + 1)
while queue:
	v = queue.popleft()
	vs_bfs.append(v)
	for u in d[v]:
		if u in vs:
			continue
		parents[u] = v
		vs.add(u)
		queue.append(u)
dp = [0 for _ in range(N + 1)]
dpl = [1 for _ in range(N + 1)]
dpr = [1 for _ in range(N + 1)]
for v in vs_bfs[::-1]:
	t = 1
	for u in d[v]:
		if u == parents[v]:
			continue
		dpl[u] = t
		t = t * (dp[u] + 1) % M
	t = 1
	for u in d[v][::-1]:
		if u == parents[v]:
			continue
		dpr[u] = t
		t = t * (dp[u] + 1) % M
	dp[v] = t
dp2 = [0] * (N + 1)
for v in vs_bfs:
	if v == 1:
		dp2[v] = 1
		continue
	p = parents[v]
	dp2[v] = (dp2[p] * (dpl[v] * dpr[v]) + 1) % M
r = [0] * N
for i in range(1, N + 1):
	r[i - 1] = str(dp[i] * dp2[i] % M)
print('\n'.join(r))


from collections import defaultdict

class ReRooting:

	def __init__(self, f, g, merge, ie):
		self.tree = defaultdict(list)
		self.f = f
		self.g = g
		self.merge = merge
		self.ie = ie
		self.dp = defaultdict(dict)

	def add_edge(self, u, v):
		self.tree[u].append(v)
		self.tree[v].append(u)

	def __dfs1(self, u, p):
		o = []
		s = [(u, -1)]
		while s:
			(u, p) = s.pop()
			o.append((u, p))
			for v in self.tree[u]:
				if v == p:
					continue
				s.append((v, u))
		for (u, p) in reversed(o):
			r = self.ie
			for v in self.tree[u]:
				if v == p:
					continue
				r = self.merge(r, self.f(self.dp[u][v], v))
			self.dp[p][u] = self.g(r, u)

	def __dfs2(self, u, p, a):
		s = [(u, p, a)]
		while s:
			(u, p, a) = s.pop()
			self.dp[u][p] = a
			pl = [0] * (len(self.tree[u]) + 1)
			pl[0] = self.ie
			for (i, v) in enumerate(self.tree[u]):
				pl[i + 1] = self.merge(pl[i], self.f(self.dp[u][v], v))
			pr = [0] * (len(self.tree[u]) + 1)
			pr[-1] = self.ie
			for (i, v) in reversed(list(enumerate(self.tree[u]))):
				pr[i] = self.merge(pr[i + 1], self.f(self.dp[u][v], v))
			for (i, v) in enumerate(self.tree[u]):
				if v == p:
					continue
				r = self.merge(pl[i], pr[i + 1])
				s.append((v, u, self.g(r, u)))

	def build(self, root=1):
		self.__dfs1(root, -1)
		self.__dfs2(root, -1, self.ie)

	def slv(self, u):
		r = self.ie
		for v in self.tree[u]:
			r = self.merge(r, self.f(self.dp[u][v], v))
		return self.g(r, u)

def atcoder_dp_dp_v():
	(N, M) = map(int, input().split())
	XY = [list(map(int, input().split())) for _ in range(N - 1)]
	f = lambda x, y: x
	g = lambda x, y: x + 1
	merge = lambda x, y: x * y % M
	rr = ReRooting(f, g, merge, 1)
	for (x, y) in XY:
		rr.add_edge(x, y)
	rr.build()
	for u in range(1, N + 1):
		print(rr.slv(u) - 1)

def atcoder_abc60_f():
	N = int(input())
	AB = [list(map(int, input().split())) for _ in range(N - 1)]
	M = 10 ** 9 + 7
	from functools import reduce
	fact = [1]
	for i in range(1, 10 ** 6):
		fact.append(fact[-1] * i % M)

	def f(x, _):
		c = x[0]
		s = x[1]
		c *= pow(fact[s], M - 2, M)
		c %= M
		return (c, s)

	def g(x, _):
		c = x[0]
		s = x[1]
		c *= fact[s]
		c %= M
		return (c, s + 1)

	def merge(x, y):
		return (x[0] * y[0] % M, x[1] + y[1])
	rr = ReRooting(f, g, merge, (1, 0))
	for (a, b) in AB:
		rr.add_edge(a, b)
	rr.build()
	for u in range(1, N + 1):
		print(rr.slv(u)[0])

def codeforces_1324_f():
	N = int(input())
	A = list(map(int, input().split()))
	UV = [list(map(int, input().split())) for _ in range(N - 1)]
	f = lambda x, v: max(x, 0)

	def g(x, v):
		return x + (1 if A[v - 1] == 1 else -1)

	def merge(x, y):
		return x + y
	rr = ReRooting(f, g, merge, 0)
	for (u, v) in UV:
		rr.add_edge(u, v)
	rr.build()
	ans = []
	for u in range(1, N + 1):
		ans.append(rr.slv(u))
	print(*ans)
atcoder_dp_dp_v()


(n, m) = map(int, input().split())
mod = m
import sys
input = sys.stdin.readline
from collections import deque
graph = [[] for _ in range(n + 1)]
for _ in range(n - 1):
	(a, b) = map(int, input().split())
	graph[a].append(b)
	graph[b].append(a)
ini = 1

def calc(a, b):
	p = a * b % mod
	return p

def calc1(c, p):
	p_num = ini
	for i in graph[c]:
		if i == p:
			continue
		p_num = calc(p_num, dp1[i])
	p_num += 1
	dp1[c] = p_num % mod

def calc2(p):
	arr = [dp1[c] if c != parent[p] else dp2[p] for c in graph[p]]
	left = [ini]
	for i in arr[:-1]:
		left.append(calc(left[-1], i))
	right = [ini]
	for i in arr[:0:-1]:
		right.append(calc(right[-1], i))
	right = right[::-1]
	prod = []
	for (a, b) in zip(left, right):
		prod.append(calc(a, b))
	for (c, x) in zip(graph[p], prod):
		if c != parent[p]:
			dp2[c] = (x + 1) % mod
root = 1
order = []
parent = [0] * (n + 1)
stack = deque()
stack.append(root)
while stack:
	x = stack.pop()
	order.append(x)
	for y in graph[x]:
		if y == parent[x]:
			continue
		stack.append(y)
		parent[y] = x
dp1 = [None] * (n + 1)
for i in order[::-1]:
	calc1(i, parent[i])
dp2 = [None] * (n + 1)
dp2[root] = ini
for i in order:
	calc2(i)
for i in range(1, n + 1):
	ans = calc(dp1[i] - 1, dp2[i])
	print(ans)


import sys
input = lambda : sys.stdin.readline().strip()
(n, m) = map(int, input().split())
mod = m
G = [[] for i in range(n)]
for i in range(n - 1):
	(a, b) = map(int, input().split())
	(a, b) = (a - 1, b - 1)
	G[a].append(b)
	G[b].append(a)
from collections import deque

def dfs(root):
	que = deque()
	que.append((root, -1))
	order = []
	while que:
		(cur, prev) = que.popleft()
		order.append(cur)
		for to in G[cur]:
			if to != prev:
				que.append((to, cur))
	return order
order = dfs(0)
child = set()
down = [1] * n
for cur in reversed(order):
	tmp = 1
	for to in G[cur]:
		if to in child:
			tmp *= down[to] + 1
			tmp %= mod
	down[cur] = tmp
	child.add(cur)
ans = [0] * n
que = deque()
que.append((0, -1, 1))
while que:
	(cur, prev, parent) = que.popleft()
	left = [1]
	for to in G[cur]:
		tmp = down[to]
		if to == prev:
			tmp = parent
		left.append(left[-1] * (tmp + 1) % mod)
	right = [1]
	for to in reversed(G[cur]):
		tmp = down[to]
		if to == prev:
			tmp = parent
		right.append(right[-1] * (tmp + 1) % mod)
	ans[cur] = left[-1]
	m = len(G[cur])
	for (i, to) in enumerate(G[cur]):
		if to != prev:
			que.append((to, cur, left[i] * right[m - i - 1]))
print(*ans, sep='\n')


def getN():
	return int(input())

def getNM():
	return map(int, input().split())

def getList():
	return list(map(int, input().split()))

def getArray(intn):
	return [int(input()) for i in range(intn)]

def input():
	return sys.stdin.readline().rstrip()

def rand_N(ran1, ran2):
	return random.randint(ran1, ran2)

def rand_List(ran1, ran2, rantime):
	return [random.randint(ran1, ran2) for i in range(rantime)]

def rand_ints_nodup(ran1, ran2, rantime):
	ns = []
	while len(ns) < rantime:
		n = random.randint(ran1, ran2)
		if not n in ns:
			ns.append(n)
	return sorted(ns)

def rand_query(ran1, ran2, rantime):
	r_query = []
	while len(r_query) < rantime:
		n_q = rand_ints_nodup(ran1, ran2, 2)
		if not n_q in r_query:
			r_query.append(n_q)
	return sorted(r_query)
from collections import defaultdict, deque, Counter
from sys import exit
from decimal import *
from heapq import heapify, heappop, heappush
from math import sqrt
from fractions import gcd
import random
import string
import copy
from itertools import combinations, permutations, product
from operator import mul, itemgetter
from functools import reduce
from bisect import bisect_left, bisect_right
import sys
sys.setrecursionlimit(1000000000)
mod = 10 ** 9 + 7
(N, mod) = getNM()
X = [[] for i in range(N)]
for i in range(N - 1):
	(x, y) = getNM()
	X[x - 1].append(y - 1)
	X[y - 1].append(x - 1)

class Reroot:

	def __init__(self, graph):
		self.graph = copy.deepcopy(graph)
		self.unit = 1
		self.merge = lambda a, b: a * b % mod
		self.adj_bu = lambda a, i: a + 1
		self.adj_td = lambda a, i, p: a + 1
		self.adj_fin = lambda a, i: a
		P = [-1] * N
		Q = deque([0])
		R = []
		while Q:
			i = deque.popleft(Q)
			R.append(i)
			for a in self.graph[i]:
				if a != P[i]:
					P[a] = i
					self.graph[a].remove(i)
					deque.append(Q, a)
		ME = [self.unit] * N
		XX = [0] * N
		for i in R[1:][::-1]:
			XX[i] = self.adj_bu(ME[i], i)
			p = P[i]
			ME[p] = self.merge(ME[p], XX[i])
		XX[R[0]] = self.adj_fin(ME[R[0]], R[0])
		TD = [self.unit] * N
		for i in R:
			ac = TD[i]
			for j in self.graph[i]:
				TD[j] = ac
				ac = self.merge(ac, XX[j])
			ac = self.unit
			for j in self.graph[i][::-1]:
				TD[j] = self.adj_td(self.merge(TD[j], ac), j, i)
				ac = self.merge(ac, XX[j])
				XX[j] = self.adj_fin(self.merge(ME[j], TD[j]), j)
		self.res = XX
tree = Reroot(X)
for i in tree.res:
	print(i)


def reroot(nodeCount, edges, identity, merge, addNode, root=0):
	adjacents = [list() for _ in range(nodeCount)]
	indexForAdjacents = [list() for _ in range(nodeCount)]
	for (u, v) in edges:
		indexForAdjacents[u].append(len(adjacents[v]))
		indexForAdjacents[v].append(len(adjacents[u]))
		adjacents[u].append(v)
		adjacents[v].append(u)
	childSubtreeRes = [[identity] * len(adjacents[i]) for i in range(nodeCount)]
	nodeRes = [identity] * nodeCount
	parents = [-1] * nodeCount
	order = [0] * nodeCount
	index = 0
	stack = [root]
	while stack:
		node = stack.pop()
		order[index] = node
		index += 1
		for adjacent in adjacents[node]:
			if adjacent == parents[node]:
				continue
			stack.append(adjacent)
			parents[adjacent] = node
	for node in reversed(order):
		parent = parents[node]
		result = identity
		parentIndex = -1
		for j in range(len(adjacents[node])):
			if adjacents[node][j] == parent:
				parentIndex = j
				continue
			result = merge(result, childSubtreeRes[node][j])
		if parentIndex >= 0:
			childSubtreeRes[parent][indexForAdjacents[node][parentIndex]] = addNode(result, node)
	for node in order:
		accumsFromTail = [identity] * len(adjacents[node])
		for j in range(len(adjacents[node]) - 1, 0, -1):
			accumsFromTail[j - 1] = merge(childSubtreeRes[node][j], accumsFromTail[j])
		accum = identity
		for j in range(len(adjacents[node])):
			result = addNode(merge(accum, accumsFromTail[j]), node)
			childSubtreeRes[adjacents[node][j]][indexForAdjacents[node][j]] = result
			accum = merge(accum, childSubtreeRes[node][j])
		nodeRes[node] = addNode(accum, node)
	return nodeRes
int1 = lambda x: int(x) - 1
(n, mod) = map(int, input().split())
merge = lambda u, v: u * v % mod
addNode = lambda val, id: val + 1
edges = [tuple(map(int1, input().split())) for _ in range(n - 1)]
res = list(map(int1, reroot(n, edges, 1, merge, addNode)))
print(*res, sep='\n')


import math, string, itertools, fractions, heapq, collections, re, array, bisect, sys, copy, functools
sys.setrecursionlimit(10 ** 7)
inf = 10 ** 20
eps = 1.0 / 10 ** 10
mod = 10 ** 9 + 7
dd = [(-1, 0), (0, 1), (1, 0), (0, -1)]
ddn = [(-1, 0), (-1, 1), (0, 1), (1, 1), (1, 0), (1, -1), (0, -1), (-1, -1)]

def LI():
	return list(map(int, sys.stdin.readline().split()))

def LLI():
	return [tuple(map(int, l.split())) for l in sys.stdin]

def LI_():
	return [int(x) - 1 for x in sys.stdin.readline().split()]

def LF():
	return [float(x) for x in sys.stdin.readline().split()]

def LS():
	return sys.stdin.readline().split()

def I():
	return int(sys.stdin.readline())

def F():
	return float(sys.stdin.readline())

def S():
	return input()

def pf(s):
	return print(s, flush=True)

def main():
	(n, m) = LI()
	if n == 1:
		return 1
	e = collections.defaultdict(list)
	for _ in range(n - 1):
		(a, b) = LI_()
		e[a].append(b)
		e[b].append(a)
	w = [None] * n
	d = [None] * n

	def f(i, p):
		r = 1
		s = [1]
		t = []
		for c in e[i]:
			if c == p:
				s.append(r)
				t.append(1)
				continue
			u = f(c, i) + 1
			r *= u
			r %= m
			s.append(r)
			t.append(u)
		for j in range(len(t) - 2, -1, -1):
			t[j] *= t[j + 1]
			t[j] %= m
		t.append(1)
		d[i] = [s, t]
		w[i] = r
		return r

	def g(i, p, k):
		w[i] *= k
		w[i] %= m
		(s, t) = d[i]
		for (j, c) in enumerate(e[i]):
			if c == p:
				continue
			g(c, i, s[j] * t[j + 1] * k % m + 1)
	f(0, -1)
	g(0, -1, 1)
	return '\n'.join(map(str, w))
print(main())


def ReRooting(n, e, identify):
	edges = [[] for _ in range(n)]
	indexedges = [[] for _ in range(n)]
	for (u, v) in e:
		indexedges[v].append(len(edges[u]))
		indexedges[u].append(len(edges[v]))
		edges[u].append(v)
		edges[v].append(u)
	dp = [identify] * n
	subdp = [len(edges[i]) * [identify] for i in range(n)]
	parents = [-1] * n
	order = [0]
	for node in order:
		for mode in edges[node]:
			if mode == parents[node]:
				continue
			order.append(mode)
			parents[mode] = node

	def merge1(a, b):
		return a * b % mod

	def addnode1(a, id):
		return a + 1
	for node in order[1:][::-1]:
		parent = parents[node]
		ans = identify
		indexparent = -1
		for j in range(len(edges[node])):
			mode = edges[node][j]
			if parent == mode:
				indexparent = j
				continue
			ans = merge1(ans, subdp[node][j])
		subdp[parent][indexedges[node][indexparent]] = addnode1(ans, node)

	def merge2(a, b):
		return a * b % mod

	def addnode2(a, id):
		return a + 1
	for node in order:
		b = [identify] * len(edges[node])
		for i in range(len(edges[node]) - 1, 0, -1):
			b[i - 1] = merge2(b[i], subdp[node][i])
		bb = identify
		for i in range(len(edges[node])):
			ans = merge2(bb, b[i])
			subdp[edges[node][i]][indexedges[node][i]] = addnode2(ans, node)
			bb = merge2(bb, subdp[node][i])
		dp[node] = addnode2(bb, node)
	return dp
(n, mod) = map(int, input().split())
edges = [] * n
for _ in range(n - 1):
	(a, b) = map(int, input().split())
	a -= 1
	b -= 1
	edges.append([a, b])
for i in ReRooting(n, edges, 1):
	print(i - 1)


import sys
sys.setrecursionlimit(100000)
(N, M) = map(int, input().split())
G = [[] for _ in range(N)]
for _ in range(N - 1):
	(x, y) = map(int, input().split())
	G[x - 1].append(y - 1)
	G[y - 1].append(x - 1)
dp = [0] * N
fm_bm = [[] for _ in range(N)]

def tdc(p, v):
	if G[v] == [p]:
		dp[v] = 1
		return 1
	res = 1
	fm = [1]
	bm = []
	C = list(set(G[v]) - set([p]))
	for u in C:
		val = 1 + tdc(v, u)
		val %= M
		res *= val
		res %= M
		fm.append(res)
		bm.append(val)
	dp[v] = res
	bm.append(1)
	for i in range(len(bm) - 1, 0, -1):
		bm[i - 1] *= bm[i]
		bm[i - 1] %= M
	fm_bm[v] = [fm, bm]
	return dp[v]
r = 0
tdc(-1, r)
ans = [0] * N
ans[r] = dp[r]

def buc(p, v, a):
	if G[v] == [p]:
		return 0
	C = list(set(G[v]) - set([p]))
	(fm, bm) = fm_bm[v]
	for (i, u) in enumerate(C):
		rev_dp = fm[i] * bm[i + 1] % M
		rev_dp = rev_dp * a % M + 1
		ans[u] = dp[u] * rev_dp % M
		buc(v, u, rev_dp)
buc(-1, r, 1)
print('\n'.join(map(str, ans)))


import sys
sys.setrecursionlimit(1000000)

def input():
	return sys.stdin.readline()
(n, m) = [int(i) for i in input().split()]
e = [[] for _ in range(n)]
for _ in range(n - 1):
	(a, b) = [int(i) - 1 for i in input().split()]
	e[a].append(b)
	e[b].append(a)
dp1 = [0] * n

def dfs1(i=0, r=-1):
	s = 1
	for j in e[i]:
		if j != r:
			s *= dfs1(j, i)
			s %= m
	dp1[i] = s
	return s + 1
dfs1()
dp2 = [0] * n
dp2[0] = dp1[0]

def dfs2(i=0, r=-1, s=1):
	a = [1]
	for j in e[i]:
		if j != r:
			a.append(a[-1] * (dp1[j] + 1) % m)
	b = [1]
	for j in reversed(e[i]):
		if j != r:
			b.append(b[-1] * (dp1[j] + 1) % m)
	b.reverse()
	k = 0
	for j in e[i]:
		if j != r:
			l = (a[k] * b[k + 1] * s + 1) % m
			dp2[j] = l * dp1[j] % m
			dfs2(j, i, l)
			k += 1
dfs2()
print('\n'.join(map(str, dp2)))


def examA():
	N = I()
	H = LI()
	dp = [inf] * N
	dp[0] = 0
	for i in range(N - 1):
		dp[i + 1] = min(dp[i + 1], dp[i] + abs(H[i + 1] - H[i]))
		if i < N - 2:
			dp[i + 2] = min(dp[i + 2], dp[i] + abs(H[i + 2] - H[i]))
	ans = dp[-1]
	print(ans)
	return

def examB():
	(N, K) = LI()
	H = LI()
	dp = [inf] * N
	dp[0] = 0
	for i in range(N):
		for k in range(1, K + 1):
			if i + k >= N:
				break
			if dp[i + k] > dp[i] + abs(H[i + k] - H[i]):
				dp[i + k] = dp[i] + abs(H[i + k] - H[i])
	ans = dp[-1]
	print(ans)
	return

def examC():
	N = I()
	A = [0] * N
	B = [0] * N
	C = [0] * N
	for i in range(N):
		(A[i], B[i], C[i]) = LI()
	dp = [[0] * 3 for _ in range(N + 1)]
	for i in range(N):
		dp[i + 1][0] = max(dp[i][1], dp[i][2]) + A[i]
		dp[i + 1][1] = max(dp[i][0], dp[i][2]) + B[i]
		dp[i + 1][2] = max(dp[i][1], dp[i][0]) + C[i]
	ans = max(dp[N])
	print(ans)
	return

def examD():
	ans = 0
	print(ans)
	return

def examE():
	ans = 0
	print(ans)
	return

def examF():
	S = SI()
	N = len(S)
	T = SI()
	M = len(T)
	dp = [[0] * (M + 1) for _ in range(N + 1)]
	for i in range(N):
		for j in range(M):
			if S[i] == T[j]:
				dp[i + 1][j + 1] = max(dp[i + 1][j + 1], dp[i][j] + 1)
			dp[i + 1][j + 1] = max(dp[i + 1][j + 1], dp[i + 1][j], dp[i][j + 1])
	i = N
	j = M
	ans = []
	while i > 0 and j > 0:
		if dp[i][j] == dp[i - 1][j]:
			i -= 1
		elif dp[i][j] == dp[i][j - 1]:
			j -= 1
		else:
			ans.append(S[i - 1])
			i -= 1
			j -= 1
	print(''.join(ans[::-1]))
	return

def examG():

	def topological_sort(n, outs, ins):
		q = deque((v1 for v1 in range(n) if ins[v1] == 0))
		res = []
		while q:
			v1 = q.popleft()
			res.append(v1)
			for v2 in outs[v1]:
				ins[v2] -= 1
				if ins[v2] == 0:
					q.append(v2)
		return res
	(N, M) = LI()
	V = [[] for _ in range(N)]
	start = [0] * N
	for _ in range(M):
		(x, y) = LI()
		x -= 1
		y -= 1
		V[x].append(y)
		start[y] += 1
	Order = topological_sort(N, V, start)
	dp = [0] * N
	for i in Order:
		for v in V[i]:
			dp[v] = max(dp[v], dp[i] + 1)
	ans = max(dp)
	print(ans)
	return

def examH():
	(H, W) = LI()
	A = [SI() for _ in range(H)]
	dp = [[0] * W for _ in range(H)]
	dp[0][0] = 1
	for i in range(H):
		for j in range(W):
			if A[i][j] == '#':
				continue
			dp[i][j] %= mod
			if i + 1 < H and dp[i + 1][j] != '#':
				dp[i + 1][j] += dp[i][j]
			if j + 1 < W and dp[i][j + 1] != '#':
				dp[i][j + 1] += dp[i][j]
	ans = dp[-1][-1]
	print(ans)
	return

def examI():
	N = I()
	P = LFI()
	dp = [[0] * (N + 1) for _ in range(N + 1)]
	dp[0][0] = 1
	for i in range(N):
		for j in range(i + 1):
			dp[i + 1][j + 1] += dp[i][j] * P[i]
			dp[i + 1][j] += dp[i][j] * (1 - P[i])
	ans = 0
	for v in dp[N][1 + N // 2:]:
		ans += v
	print(ans)
	return

def examJ():
	N = I()
	A = LI()
	dp = [[[0] * (N + 1) for _ in range(N + 1)] for _ in range(N + 1)]
	S = Counter(A)
	print(S)
	dp[S[1]][S[2]][S[3]] = 0
	que = deque()
	que.append((S[1], S[2], S[3]))
	used = defaultdict(set)
	while que:
		(n1, n2, n3) = que.popleft()
		if used[n1, n2, n3]:
			continue
		used[n1, n2, n3] = True
		now = n1 + n2 + n3
		if n1 > 0:
			dp[n1 - 1][n2][n3] += dp[n1][n2][n3] + N / now * n1 / now
			que.append((n1 - 1, n2, n3))
		if n2 > 0:
			dp[n1 + 1][n2 - 1][n3] += dp[n1][n2][n3] + N / now * n2 / now
			que.append((n1 + 1, n2 - 1, n3))
		if n3 > 0:
			dp[n1][n2 + 1][n3 - 1] += dp[n1][n2][n3] + N / now * n3 / now
			que.append((n1, n2 + 1, n3 - 1))
	ans = dp[0][0][0]
	print(ans)
	return

def examK():
	(N, K) = LI()
	A = LI()
	dp = [-1] * (K + 1)
	for i in range(1, K + 1):
		flag = False
		for a in A:
			if a > i:
				break
			if dp[i - a] == -1:
				flag = True
				break
		if flag:
			dp[i] = 1
	ans = dp[K]
	if ans == 1:
		print('First')
	else:
		print('Second')
	return

def examM():
	(N, K) = LI()
	A = LI()
	dp = [[0] * (K + 1) for _ in range(N + 1)]
	dp[0][0] = 1
	for i in range(N):
		cum = [0] * (K + 1)
		cum[0] = dp[i][0]
		for c in range(K):
			cum[c + 1] = cum[c] + dp[i][c + 1]
		for j in range(K + 1):
			if j <= A[i]:
				dp[i + 1][j] = cum[j]
			else:
				dp[i + 1][j] = cum[j] - cum[j - A[i] - 1]
			dp[i + 1][j] %= mod
	ans = dp[N][K] % mod
	print(ans)
	return

def examN():
	N = I()
	A = LI()
	cumA = [0] * (N + 1)
	for i in range(N):
		cumA[i + 1] = cumA[i] + A[i]
	dp = [[inf] * N for _ in range(N)]
	for i in range(N):
		dp[0][i] = 0
	for i in range(N - 1):
		for j in range(N - i - 1):
			for k in range(i + 1):
				cur = dp[i - k][j + k + 1] + dp[k][j] + cumA[i + j + 2] - cumA[j]
				dp[i + 1][j] = min(dp[i + 1][j], cur)
	ans = dp[N - 1][0]
	print(ans)
	return

def examO():
	N = I()
	A = [LI() for _ in range(N)]
	loop = 2 ** N
	dp = [[0] * loop for _ in range(N + 1)]
	dp[0][0] = 1
	for mask in range(loop):
		cur = 0
		for j in range(N):
			if mask & 1 << j == 1 << j:
				cur += 1
		for i in range(N):
			if mask & 1 << i == 0 and A[i][cur] == 1:
				dp[cur + 1][mask | 1 << i] += dp[cur][mask]
				dp[cur + 1][mask | 1 << i] %= mod
	ans = dp[N][loop - 1]
	print(ans)
	return

def examP():

	def dfs_dp(n, s, fords, visited):
		W = 1
		B = 1
		visited[s] = True
		for v in fords[s]:
			if visited[v]:
				continue
			cur = dfs_dp(n, v, fords, visited)
			W *= sum(cur)
			B *= cur[0]
			W %= mod
			B %= mod
		return (W, B)
	N = I()
	V = [[] for _ in range(N)]
	for _ in range(N - 1):
		(x, y) = LI()
		x -= 1
		y -= 1
		V[x].append(y)
		V[y].append(x)
	visited = [False] * N
	ans = dfs_dp(N, 0, V, visited)
	print(sum(ans) % mod)
	return

def examQ():

	class segment_:

		def __init__(self, A, n, segfunc):
			self.ide_ele = 0
			self.num = 1 << (n - 1).bit_length()
			self.seg = [self.ide_ele] * 2 * self.num
			self.segfunc = segfunc
			for i in range(n):
				self.seg[i + self.num] = A[i]
			for i in range(self.num - 1, 0, -1):
				self.seg[i] = self.segfunc(self.seg[2 * i], self.seg[2 * i + 1])

		def update(self, k, r):
			k += self.num
			self.seg[k] = r
			while k:
				k >>= 1
				self.seg[k] = self.segfunc(self.seg[k * 2], self.seg[k * 2 + 1])

		def update1(self, k):
			k += self.num
			self.seg[k] += 1
			while k:
				k >>= 1
				self.seg[k] = self.segfunc(self.seg[k * 2], self.seg[k * 2 + 1])

		def updateneg1(self, k):
			k += self.num
			self.seg[k] -= 1
			while k:
				k >>= 1
				self.seg[k] = self.segfunc(self.seg[k * 2], self.seg[k * 2 + 1])

		def query(self, p, q):
			if q < p:
				return self.ide_ele
			p += self.num
			q += self.num
			res = self.ide_ele
			while p < q:
				if p & 1 == 1:
					res = self.segfunc(res, self.seg[p])
					p += 1
				if q & 1 == 1:
					q -= 1
					res = self.segfunc(res, self.seg[q])
				p >>= 1
				q >>= 1
			return res
	N = I()
	H = LI()
	maxH = max(H)
	A = LI()
	Seg_max = segment_([0] * (maxH + 1), N + 1, lambda a, b: max(a, b))
	dp = [0] * (maxH + 1)
	cur = 0
	for i in range(N):
		h = H[i]
		cur = Seg_max.query(0, h + 1)
		dp[i] = cur + A[i]
		Seg_max.update(h, dp[i])
	ans = max(dp)
	print(ans)
	return

def examR():

	def list_dot(A1, A2):
		res = [[0] * len(A2) for _ in range(len(A1))]
		for i in range(len(A1)):
			for j in range(len(A2)):
				cur = 0
				for k in range(len(A1[0])):
					cur += A1[i][k] * A2[k][j]
				res[i][j] = cur % mod
		return res
	(N, K) = LI()
	A = [LI() for _ in range(N)]
	now = [[1] * N]
	while K > 0:
		if K % 2 == 1:
			now = list_dot(now, A)
		K //= 2
		A = list_dot(A, A)
	ans = 0
	for i in now:
		for k in i:
			ans += k
			ans %= mod
	print(ans)
	return

def examS():

	class ModInt:

		def __init__(self, x):
			self.x = x % MOD

		def __str__(self):
			return str(self.x)
		__repr__ = __str__

		def __add__(self, other):
			return ModInt(self.x + other.x) if isinstance(other, ModInt) else ModInt(self.x + other)

		def __sub__(self, other):
			return ModInt(self.x - other.x) if isinstance(other, ModInt) else ModInt(self.x - other)

		def __mul__(self, other):
			return ModInt(self.x * other.x) if isinstance(other, ModInt) else ModInt(self.x * other)

		def __truediv__(self, other):
			return ModInt(self.x * pow(other.x, MOD - 2, MOD)) if isinstance(other, ModInt) else ModInt(self.x * pow(other, MOD - 2, MOD))

		def __pow__(self, other):
			return ModInt(pow(self.x, other.x, MOD)) if isinstance(other, ModInt) else ModInt(pow(self.x, other, MOD))
		__radd__ = __add__

		def __rsub__(self, other):
			return ModInt(other.x - self.x) if isinstance(other, ModInt) else ModInt(other - self.x)
		__rmul__ = __mul__

		def __rtruediv__(self, other):
			return ModInt(other.x * pow(self.x, MOD - 2, MOD)) if isinstance(other, ModInt) else ModInt(other * pow(self.x, MOD - 2, MOD))

		def __rpow__(self, other):
			return ModInt(pow(other.x, self.x, MOD)) if isinstance(other, ModInt) else ModInt(pow(other, self.x, MOD))

	def ketadp(a, D):
		n = len(a)
		dp = [[[ModInt(0)] * D for _ in range(2)] for _ in range(n + 1)]
		dp[0][0][0] = 1
		for (i, less, hasD) in itertools.product(range(n), (0, 1), range(D)):
			max_d = 9 if less else int(a[i])
			for d in range(max_d + 1):
				less_ = less or d < max_d
				hasD_ = (hasD + d) % D
				dp[i + 1][less_][hasD_] += dp[i][less][hasD]
		ans = sum((dp[n][less][0] for less in (0, 1)))
		return ans
	K = SI()
	D = I()
	ans = ketadp(K, D)
	ans = ans - 1
	print(ans)
	return

def examT():
	return

def examU():
	N = I()
	A = [LI() for _ in range(N)]
	mask = 2 ** N
	cst = [0] * mask
	for i in range(mask):
		cur = 0
		for j in range(N):
			for k in range(j + 1, N):
				if i & 1 << j == 1 << j and i & 1 << k == 1 << k:
					cur += A[j][k]
		cst[i] = cur
	dp = [0] * mask
	for m in range(mask):
		maskT = m
		while maskT > 0:
			cur = dp[m - maskT] + cst[maskT]
			dp[m] = max(dp[m], cur)
			maskT = maskT - 1 & m
	ans = dp[-1]
	print(ans)
	return

def examV():
	(N, M) = LI()
	V = [set() for _ in range(N)]
	for _ in range(N - 1):
		(a, b) = LI()
		a -= 1
		b -= 1
		V[a].add(b)
		V[b].add(a)
	B = [0] * N
	ans = [0] * N
	if N == 1:
		print(1)
		return

	def dfs1(s, p):
		B[s] = 1
		for ne in V[s]:
			if ne == p:
				continue
			B[s] *= dfs1(ne, s) + 1
			B[s] %= M
		return B[s]

	def dfs2(s, p):
		rep = 1
		for to in V[s]:
			rep *= B[to] + 1
			rep %= M
		ans[s] = rep
		n = len(V[s])
		L = [0] * n
		R = [0] * n
		for (i, ne) in enumerate(V[s]):
			L[i] = R[i] = B[ne] + 1
		for i in range(1, n):
			L[i] *= L[i - 1]
			L[i] %= M
		for i in range(1, n - 1)[::-1]:
			R[i] *= R[i + 1]
			R[i] %= M
		for (i, ne) in enumerate(V[s]):
			if ne != p:
				B[s] = 1
				if i:
					B[s] *= L[i - 1]
					B[s] %= M
				if i + 1 < n:
					B[s] *= R[i + 1]
				B[s] %= M
				dfs2(ne, s)
		return
	ans[0] = dfs1(0, -1)
	dfs2(0, -1)
	for v in ans:
		print(v % M)
	return

def examX():
	N = I()
	W = [[] for _ in range(N)]
	for i in range(N):
		W[i] = LI()
	W.sort(key=lambda x: x[1])
	maxS = W[-1][1]
	print(W)
	dp = [[0] * (maxS + 2) for _ in range(N + 1)]
	for i in range(N):
		ns = W[i][1]
		nw = W[i][0]
		nv = W[i][2]
		for j in range(maxS + 2):
			dp[i + 1][j] = max(dp[i + 1][j], dp[i][j])
		for j in range(ns + 1):
			dp[i + 1][min(j + nw, maxS + 1)] = max(dp[i + 1][j], dp[i][j] + nv)
	ans = max(dp[N])
	print(dp)
	print(ans)
	return
import sys, copy, bisect, itertools, heapq, math
from heapq import heappop, heappush, heapify
from collections import Counter, defaultdict, deque

def I():
	return int(sys.stdin.readline())

def LI():
	return list(map(int, sys.stdin.readline().split()))

def LFI():
	return list(map(float, sys.stdin.readline().split()))

def LSI():
	return list(map(str, sys.stdin.readline().split()))

def LS():
	return sys.stdin.readline().split()

def SI():
	return sys.stdin.readline().strip()
global mod, mod2, inf, alphabet, MOD
mod = 10 ** 9 + 7
mod2 = 998244353
MOD = mod
inf = 10 ** 18
alphabet = [chr(ord('a') + i) for i in range(26)]
sys.setrecursionlimit(10 ** 6)
examV()


import itertools
import sys
import heapq
sys.setrecursionlimit(10 ** 5 + 1)
(n, m) = map(int, input().split())
graph = [[] for _ in range(n)]
for i in range(n - 1):
	(a, b) = map(lambda x: int(x) - 1, input().split())
	graph[a].append(b)
	graph[b].append(a)
rooted = [[] for _ in range(n)]
rev_rooted = [[] for _ in range(n)]
que = [(0, -1, 0)]
bfs_target = []
while que:
	(node, parent, distance) = que.pop()
	heapq.heappush(bfs_target, (-distance, node))
	for child in graph[node]:
		if child != parent:
			que.append((child, node, distance + 1))
			rooted[node].append(child)
			rev_rooted[child].append(node)

def mod(v):
	if v >= m:
		return v % m
	return v
dp = [1] * n
while bfs_target:
	node = heapq.heappop(bfs_target)[1]
	for parent in rev_rooted[node]:
		dp[parent] = mod(dp[parent] * (dp[node] + 1))
		que.append(parent)
rev_dp = [0] * n
que = [0]
while que:
	node = que.pop()
	cp = [1]
	rev_cp = [1]
	for (i, child) in enumerate(rooted[node]):
		cp.append(mod(cp[i] * (dp[child] + 1)))
	for (i, child) in enumerate(reversed(rooted[node])):
		rev_cp.append(mod(rev_cp[i] * (dp[child] + 1)))
	rev_cp = rev_cp[::-1]
	for (i, child) in enumerate(rooted[node]):
		rev_dp[child] = mod(cp[i] * rev_cp[i + 1] * (rev_dp[node] + 1))
		que.append(child)
for (v1, v2) in zip(dp, rev_dp):
	print(mod(v1 * (v2 + 1)))


import sys
input = lambda : sys.stdin.readline().rstrip()
sys.setrecursionlimit(max(1000, 10 ** 9))
write = lambda x: sys.stdout.write(x + '\n')
from collections import defaultdict
(n, M) = map(int, input().split())
ns = defaultdict(list)
for _ in range(n - 1):
	(u, v) = map(int, input().split())
	ns[u - 1].append(v - 1)
	ns[v - 1].append(u - 1)
bs = {}
cump0 = defaultdict(list)
cump1 = defaultdict(list)

def sub(u, p):
	if (p, u) in bs:
		return bs[p, u]
	b = 1
	ps = []
	for v in ns[u]:
		if v == p:
			continue
		bb = sub(v, u)
		b *= 1 + bb
		b %= M
		ps.append(bb)
	v0 = 1
	v1 = 1
	l = len(ps)
	for i in range(l):
		cump0[u].append(v0)
		cump1[u].append(v1)
		v0 *= ps[i] + 1
		v1 *= ps[l - 1 - i] + 1
		v0 %= M
		v1 %= M
	cump0[u].append(v0)
	cump1[u].append(v1)
	bs[p, u] = b % M
	return b
ans = [None] * n

def sub2(u, p):
	i = 0
	for v in ns[u]:
		if v == p:
			continue
		b1 = bs[p, u]
		b2 = bs[u, v]
		b3 = bs[u, p]
		if p >= 0:
			bb = cump0[u][i] * cump1[u][-(i + 2)] * (1 + b3) % M
		else:
			bb = cump0[u][i] * cump1[u][-(i + 2)] % M
		bs[v, u] = bb
		ans[v] = bs[u, v] * (1 + bb) % M
		sub2(v, u)
		i += 1
sub(0, -1)
bs[0, -1] = 1
ans[0] = bs[-1, 0]
sub2(0, -1)
write('\n'.join(map(str, ans)))


import sys
sys.setrecursionlimit(10 ** 6)

def input():
	return sys.stdin.buffer.readline()[:-1]
(n, m) = map(int, input().split())
adj = [[] for _ in range(n)]
for _ in range(n - 1):
	(a, b) = map(int, input().split())
	adj[a - 1].append(b - 1)
	adj[b - 1].append(a - 1)
dp = [1 for _ in range(n)]

def dfs1(x, p):
	for c in adj[x]:
		if c == p:
			continue
		dfs1(c, x)
		dp[x] *= dp[c] + 1
		dp[x] %= m
	return
dfs1(0, -1)
ans = [0 for _ in range(n)]
ans[0] = dp[0]

def dfs2(x, p):
	l = len(adj[x])
	cuml = [1 for _ in range(l + 2)]
	cumr = [1 for _ in range(l + 2)]
	for i in range(l):
		cuml[i + 1] = cuml[i] * (dp[adj[x][i]] + 1) % m
	for i in range(l - 1, -1, -1):
		cumr[i + 1] = cumr[i + 2] * (dp[adj[x][i]] + 1) % m
	pres_x = dp[x]
	for (i, c) in enumerate(adj[x]):
		if c == p:
			continue
		pres_c = dp[c]
		dp[x] = cuml[i] * cumr[i + 2] % m
		dp[c] *= dp[x] + 1
		dp[c] %= m
		ans[c] = dp[c]
		dfs2(c, x)
		dp[x] = pres_x
		dp[c] = pres_c
	return
dfs2(0, -1)
print(*ans, sep='\n')


class Tree:

	def __init__(self, n, edge):
		self.n = n
		self.tree = [[] for _ in range(n)]
		for e in edge:
			self.tree[e[0] - 1].append(e[1] - 1)
			self.tree[e[1] - 1].append(e[0] - 1)

	def setroot(self, root):
		self.root = root
		self.parent = [None for _ in range(self.n)]
		self.parent[root] = -1
		self.depth = [None for _ in range(self.n)]
		self.depth[root] = 0
		self.order = []
		self.order.append(root)
		stack = [root]
		while stack:
			node = stack.pop()
			for adj in self.tree[node]:
				if self.parent[adj] is None:
					self.parent[adj] = node
					self.depth[adj] = self.depth[node] + 1
					self.order.append(adj)
					stack.append(adj)

	def rerooting(self, func, merge, ti, ei):
		dp = [ti for _ in range(self.n)]
		lt = [ei for _ in range(self.n)]
		rt = [ei for _ in range(self.n)]
		inv = [ei for _ in range(self.n)]
		self.setroot(0)
		for node in self.order[::-1]:
			tmp = ti
			for adj in self.tree[node]:
				if self.parent[adj] == node:
					lt[adj] = tmp
					tmp = func(tmp, dp[adj])
			tmp = ti
			for adj in self.tree[node][::-1]:
				if self.parent[adj] == node:
					rt[adj] = tmp
					tmp = func(tmp, dp[adj])
			dp[node] = tmp
		for node in self.order:
			if node == 0:
				continue
			merged = merge(lt[node], rt[node])
			par = self.parent[node]
			inv[node] = func(merged, inv[par])
			dp[node] = func(dp[node], inv[node])
		return dp
import sys
input = sys.stdin.readline
(N, M) = map(int, input().split())
E = [tuple(map(int, input().split())) for _ in range(N - 1)]
T = Tree(N, E)

def func(node, adj):
	return node * (adj + 1) % M

def merge(lt, rt):
	return lt * rt % M
ti = 1
ei = 0
D = T.rerooting(func, merge, ti, ei)
print('\n'.join(map(str, D)))


class ReRooting:

	def __init__(self, size, root=0, identDp=1, identCum=1):
		self.size = size
		self.edges = [[] for _ in range(self.size + 1)]
		self.root = root
		self.identDp = identDp
		self.identCum = identCum

	def addEdge(self, fr, to):
		self.edges[fr].append(to)
		self.edges[to].append(fr)

	def lift(self, top, bottom):
		return top * (bottom + 1) % M

	def merge(self, left, right):
		return left * right % M

	def sol(self):
		N = self.size
		edges = self.edges
		st = [self.root]
		parent = [-1] * (N + 1)
		child = [[] for _ in range(N + 1)]
		order = []
		while st:
			v = st.pop()
			order.append(v)
			for to in edges[v]:
				if parent[v] == to:
					continue
				parent[to] = v
				child[v].append(to)
				st.append(to)
		dp = [self.identDp] * (N + 1)
		left = [self.identCum] * (N + 1)
		right = [self.identCum] * (N + 1)
		for v in order[::-1]:
			tmp = self.identCum
			for ch in child[v]:
				left[ch] = tmp
				tmp = self.lift(tmp, dp[ch])
			tmp = self.identCum
			for ch in reversed(child[v]):
				right[ch] = tmp
				tmp = self.lift(tmp, dp[ch])
			dp[v] = tmp
		fromParent = [0] * (N + 1)
		for v in order:
			if v == self.root:
				continue
			fromParent[v] = self.lift(self.merge(left[v], right[v]), fromParent[parent[v]])
			dp[v] = self.lift(dp[v], fromParent[v])
		return dp[:N]
(N, M) = map(int, input().split())
tree = ReRooting(N, 0, 1, 1)
for _ in range(N - 1):
	(fr, to) = map(int, input().split())
	tree.addEdge(fr - 1, to - 1)
ans = tree.sol()
print(*ans, sep='\n')


import sys
input = sys.stdin.readline
from collections import deque

def main():
	(n, mod) = map(int, input().split())
	Edges = [[] for _ in range(n)]
	for _ in range(n - 1):
		(x, y) = map(int, input().split())
		x -= 1
		y -= 1
		Edges[x].append(y)
		Edges[y].append(x)
	Stack = [0]
	Par = [-1] * n
	Order = []
	while Stack:
		v = Stack.pop()
		Order.append(v)
		for c in Edges[v]:
			if c != Par[v]:
				Stack.append(c)
				Par[c] = v
	child = set()
	DP = [1] * n
	for v in Order[::-1]:
		for to in Edges[v]:
			if to == Par[v]:
				continue
			DP[v] *= DP[to] + 1
			DP[v] %= mod
	Ans = [0] * n
	que = deque()
	que.append((0, -1, 1))
	while que:
		(v, par, par_cnt) = que.popleft()
		Left = [1]
		for to in Edges[v]:
			tmp = DP[to]
			if to == par:
				tmp = par_cnt
			Left.append(Left[-1] * (tmp + 1) % mod)
		Right = [1]
		for to in reversed(Edges[v]):
			tmp = DP[to]
			if to == par:
				tmp = par_cnt
			Right.append(Right[-1] * (tmp + 1) % mod)
		Ans[v] = Left[-1]
		m = len(Edges[v])
		for (i, to) in enumerate(Edges[v]):
			if to != par:
				que.append((to, v, Left[i] * Right[m - i - 1] % mod))
	print(*Ans, sep='\n')
main()


import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, radians
from itertools import accumulate, permutations, combinations, product, islice
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left
from fractions import gcd
from heapq import heappush, heappop
from functools import reduce

def input():
	return sys.stdin.readline().strip()

def INT():
	return int(input())

def MAP():
	return map(int, input().split())

def LIST():
	return list(map(int, input().split()))

def ZIP(n):
	return zip(*(MAP() for _ in range(n)))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
(N, M) = MAP()
mod = M
tree = [[] for _ in range(N + 1)]
for _ in range(N - 1):
	(a, b) = MAP()
	tree[a].append(b)
	tree[b].append(a)
root = 1
parent = [0] * (N + 1)
order = []
stack = [root]
while stack:
	x = stack.pop()
	order.append(x)
	for y in tree[x]:
		if y == parent[x]:
			continue
		parent[y] = x
		stack.append(y)
dp_d = [0] * (N + 1)
for v in order[::-1]:
	x = 1
	for node in tree[v]:
		x = x * (dp_d[node] + 1) % mod
	dp_d[v] = x
dp_u = [1] * (N + 1)
modmul = lambda x, y: x * y % mod
for v in order:
	p = parent[v]
	val = [dp_d[node] + 1 if node != p else dp_u[v] for node in tree[v]]
	left = [1] + list(accumulate(val, modmul))[:-1]
	right = list(accumulate(val[::-1], modmul))[-2::-1] + [1]
	contrib = [x * y % mod for (x, y) in zip(left, right)]
	for (node, c) in zip(tree[v], contrib):
		if node != p:
			dp_u[node] = 1 + c
ans = []
for (xd, xu) in zip(dp_d[1:], dp_u[1:]):
	ans.append(xd * xu % mod)
print(*ans, sep='\n')


def main():
	import sys
	input = sys.stdin.readline
	(N, mod) = map(int, input().split())
	adj = [[] for _ in range(N + 1)]
	for _ in range(N - 1):
		(a, b) = map(int, input().split())
		adj[a].append(b)
		adj[b].append(a)

	def op(a, b):
		return a * (b + 1) % mod

	def cum_merge(a, b):
		return a * b % mod

	def Rerooting(adj):
		N = len(adj) - 1
		st = [1]
		seen = [0] * (N + 1)
		seen[1] = 1
		par = [0] * (N + 1)
		child = [[] for _ in range(N + 1)]
		seq = []
		while st:
			v = st.pop()
			seq.append(v)
			for u in adj[v]:
				if not seen[u]:
					seen[u] = 1
					par[u] = v
					child[v].append(u)
					st.append(u)
		seq.reverse()
		dp = [1] * (N + 1)
		left = [1] * (N + 1)
		right = [1] * (N + 1)
		for v in seq:
			tmp = 1
			for u in child[v]:
				left[u] = tmp
				tmp = op(tmp, dp[u])
			tmp = 1
			for u in reversed(child[v]):
				right[u] = tmp
				tmp = op(tmp, dp[u])
			dp[v] = tmp
		seq.reverse()
		from_par = [0] * (N + 1)
		for v in seq:
			if v == 1:
				continue
			from_par[v] = op(cum_merge(left[v], right[v]), from_par[par[v]])
			dp[v] = op(dp[v], from_par[v])
		return dp
	dp = Rerooting(adj)
	for i in range(1, N + 1):
		print(dp[i])
main()


from collections import defaultdict
from operator import add, mul
import sys
sys.setrecursionlimit(1000000)
d = defaultdict(list)
(N, M) = map(int, input().split())
for _ in range(N - 1):
	(a, b) = map(int, input().split())
	d[a].append(b)
	d[b].append(a)
q = [1]
parents = [-1] * (N + 1)
dp = defaultdict(lambda : defaultdict(int))
ans = [0] * (N + 1)
merge = lambda x, y: mul(x, y)
add_root = lambda x: x
e = 1

def dfs1(s):
	l = []
	q = [1]
	while q:
		s = q.pop()
		l.append(s)
		for t in d[s]:
			if t == parents[s]:
				continue
			parents[t] = s
			q.append(t)
	for s in l[::-1]:
		v = e
		for t in d[s]:
			if t == parents[s]:
				continue
			v = merge(v, dp[s][t] + 1)
		dp[parents[s]][s] = add_root(v)

def dfs2(s):
	q = [(s, e)]
	while q:
		(s, dp_p) = q.pop()
		par = parents[s]
		for t in d[s]:
			if t == par:
				dp[s][t] = dp_p
		size = len(d[s])
		ac_l = [e] * (size + 1)
		ac_r = [e] * (size + 1)
		for (i, t) in enumerate(d[s]):
			ac_l[i + 1] = merge(ac_l[i], dp[s][t] + 1) % M
		for (i, t) in enumerate(d[s][::-1]):
			ac_r[size - i - 1] = merge(ac_r[size - i], dp[s][t] + 1) % M
		ans[s] = add_root(ac_l[size])
		for (i, t) in enumerate(d[s]):
			if t == par:
				continue
			q.append((t, add_root(merge(ac_l[i], ac_r[i + 1]) % M)))
dfs1(1)
dfs2(1)
for i in range(1, N + 1):
	print(ans[i])


import itertools
import sys
input = sys.stdin.readline
(N, MOD) = map(int, input().split())
XY = [list(map(int, input().split())) for i in range(N - 1)]
prod = lambda x, y: x * y % MOD
tree = [[] for i in range(N)]
for (x, y) in XY:
	tree[x - 1].append(y - 1)
	tree[y - 1].append(x - 1)
root = 0
parent = [-1] * (N + 1)
order = []
stack = [root]
while stack:
	node = stack.pop()
	order.append(node)
	for child in tree[node]:
		if child == parent[node]:
			continue
		parent[child] = node
		stack.append(child)
dp_down = [0] * N
for node in order[::-1]:
	res = 1
	for child in tree[node]:
		res *= dp_down[child] + 1
		res %= MOD
	dp_down[node] = res
dp_up = [1] * N
for node in order:
	par = parent[node]
	arr = [dp_down[c] + 1 if c != par else dp_up[node] for c in tree[node]]
	left = [1] + list(itertools.accumulate(arr, prod))[:-1]
	right = list(itertools.accumulate(reversed(arr), prod))[-2::-1] + [1]
	upper_cases = [l * r % MOD for (l, r) in zip(left, right)]
	for (c, res) in zip(tree[node], upper_cases):
		if c != par:
			dp_up[c] = res + 1
ans = [d * u % MOD for (d, u) in zip(dp_down, dp_up)]
print(*ans, sep='\n')


from collections import defaultdict, deque
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 9 + 7)

def get_par_tree(tree: list, par: int) -> list:
	n = len(tree)
	ans = [-1] * n
	visited = [False] * n
	visited[par] = True
	q = deque([par])
	while q:
		pos = q.popleft()
		for next_pos in tree[pos]:
			if visited[next_pos]:
				continue
			visited[next_pos] = True
			ans[next_pos] = pos
			q.append(next_pos)
	return ans

def topological_sort_tree(tree: list, par) -> list:
	n = len(tree)
	ans = [par]
	visited = [False] * n
	visited[par] = True
	q = deque([par])
	while q:
		pos = q.popleft()
		for next_pos in tree[pos]:
			if visited[next_pos]:
				continue
			visited[next_pos] = True
			ans.append(next_pos)
			q.append(next_pos)
	return ans

def dfs1():
	visited = [False] * n
	for pos in tp_list[::-1]:
		visited[pos] = True
		for next_pos in graph[pos]:
			if visited[next_pos]:
				continue
			b1[next_pos] *= 1 + b1[pos]
			b1[next_pos] %= MOD

def dfs2():
	for pos in tp_list:
		cnt = 0
		b = 1
		par = par_list[pos]
		for next_pos in graph[pos]:
			if next_pos == par:
				d = child_pos[par][pos]
				tmp_b = ruiseki_child_l[par][d] * ruiseki_child_r[par][-d - 2]
				tmp_b %= MOD
				b *= 1 + tmp_b
				b %= MOD
				child_pos[pos][next_pos] = cnt
				child_val[pos].append(1 + tmp_b)
				cnt += 1
			else:
				b *= 1 + b1[next_pos]
				child_pos[pos][next_pos] = cnt
				child_val[pos].append(1 + b1[next_pos])
				cnt += 1
				b %= MOD
		b2[pos] = b
		ruiseki_child_l[pos] += child_val[pos]
		ruiseki_child_r[pos] += child_val[pos][::-1]
		for i in range(len(child_val[pos])):
			ruiseki_child_r[pos][i + 1] = ruiseki_child_r[pos][i] * ruiseki_child_r[pos][i + 1]
			ruiseki_child_l[pos][i + 1] = ruiseki_child_l[pos][i] * ruiseki_child_l[pos][i + 1]
			ruiseki_child_r[pos][i + 1] %= MOD
			ruiseki_child_l[pos][i + 1] %= MOD
(n, m) = map(int, input().split())
MOD = m
info = [list(map(int, input().split())) for i in range(n - 1)]
graph = [[] for i in range(n)]
dag = [[] for i in range(n)]
for i in range(n - 1):
	(a, b) = info[i]
	a -= 1
	b -= 1
	graph[b].append(a)
	graph[a].append(b)
par_list = get_par_tree(graph, 0)
tp_list = topological_sort_tree(graph, 0)
b1 = [1] * n
dfs1()
child_pos = defaultdict(lambda : defaultdict(dict))
child_val = [[] for i in range(n)]
ruiseki_child_l = [[1] for i in range(n)]
ruiseki_child_r = [[1] for i in range(n)]
b2 = [0] * n
dfs2()
for num in b2:
	print(num % MOD)


import sys, os, io
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
(N, M) = map(int, input().split())
edge = [[] for _ in range(N)]
for i in range(N - 1):
	(a, b) = list(map(int, input().split()))
	edge[a - 1].append(b - 1)
	edge[b - 1].append(a - 1)

def dfs(start):
	stack = [start]
	parent = [N] * N
	parent[start] = -1
	while stack:
		v = stack[-1]
		marker = 0
		for u in edge[v]:
			if u == parent[v]:
				continue
			if parent[u] == N:
				marker = 1
				parent[u] = v
				stack.append(u)
			else:
				ans[v] *= ans[u] + 1
				ans[v] %= M
		if marker == 0:
			stack.pop()
	return

def dfs2(start):
	stack = [start]
	parent = [N] * N
	parent[start] = -1
	p_value = [0] * N
	while stack:
		v = stack.pop()
		cum1 = [1] * (len(edge[v]) + 1)
		cum2 = [1] * (len(edge[v]) + 1)
		for (i, u) in enumerate(edge[v]):
			if u == parent[v]:
				cum1[i + 1] = cum1[i] * (p_value[v] + 1) % M
			else:
				cum1[i + 1] = cum1[i] * (ans[u] + 1) % M
		for (i, u) in enumerate(edge[v][::-1]):
			if u == parent[v]:
				cum2[-i - 2] = cum2[-i - 1] * (p_value[v] + 1) % M
			else:
				cum2[-i - 2] = cum2[-i - 1] * (ans[u] + 1) % M
		for (i, u) in enumerate(edge[v]):
			if u == parent[v]:
				continue
			parent[u] = v
			p_value[u] = cum1[i] * cum2[i + 1] % M
			ans[u] *= p_value[u] + 1
			ans[u] %= M
			stack.append(u)
		ans[v] %= M
	return
ans = [1] * N
dfs(0)
dfs2(0)
print(*ans, sep='\n')


import sys
from collections import deque
readline = sys.stdin.readline
(N, M) = map(int, readline().split())
G = [[] for i in range(N)]
for i in range(N - 1):
	(x, y) = map(int, readline().split())
	G[x - 1].append((y - 1, 2 * i))
	G[y - 1].append((x - 1, 2 * i + 1))
G0 = [None] * N
V = [(0, -1)]
used = [0] * N
used[0] = 1
que = deque([0])
while que:
	v = que.popleft()
	g = []
	for e in G[v]:
		(w, d) = e
		if used[w]:
			continue
		g.append(e)
		V.append(e)
		used[w] = 1
		que.append(w)
	G0[v] = g
memo = [0] * (2 * N + 1)
for (v, e) in reversed(V):
	r = 1
	for (w, d) in G0[v]:
		r = r * (1 + memo[d]) % M
	memo[e] = r
lv = [0] * (2 * N)
rv = [0] * (2 * N)
for (v, e) in V:
	s = 1 + memo[e ^ 1]
	for (w, d) in G0[v]:
		lv[d] = s
		s = s * (1 + memo[d]) % M
	s = 1
	for (w, d) in reversed(G0[v]):
		rv[d] = s
		s = s * (1 + memo[d]) % M
	for (w, d) in G0[v]:
		memo[d ^ 1] = lv[d] * rv[d] % M
ans = []
for v in range(N):
	r = 1
	for (w, d) in G[v]:
		r = r * (1 + memo[d]) % M
	ans.append('%d\n' % r)
sys.stdout.writelines(ans)


import itertools
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 7)
(N, MOD) = map(int, input().split())
if N == 1:
	print(1)
	exit()
graph = [set() for _ in range(N)]
for row in sys.stdin.readlines():
	(x, y) = map(int, row.split())
	graph[x - 1].add(y - 1)
	graph[y - 1].add(x - 1)
ldp = [None] * N
rdp = [None] * N

def dfs_1(v=0, parent=None):
	graph[v].discard(parent)
	ldp[v] = [1] * (len(graph[v]) + 1)
	rdp[v] = [1] * (len(graph[v]) + 1)
	vals = [dfs_1(w, v) + 1 for w in graph[v]]
	for (i, x) in enumerate(vals, 1):
		ldp[v][i] = ldp[v][i - 1] * x % MOD
	for (i, x) in enumerate(reversed(vals), 1):
		rdp[v][-i - 1] = rdp[v][-i] * x % MOD
	return ldp[v][-1]
dfs_1()
dp = [None] * N
q = [(0, 1)]
while q:
	(v, x) = q.pop()
	dp[v] = x * ldp[v][-1] % MOD
	for (w, L, R) in zip(graph[v], ldp[v][:-1], rdp[v][1:]):
		q.append((w, x * L * R % MOD + 1))
print('\n'.join(map(str, dp)))


import sys
input = sys.stdin.readline
import math
import bisect
import heapq
from collections import defaultdict
from collections import deque
from collections import Counter
from functools import lru_cache
INF = float('inf')
AZ = 'abcdefghijklmnopqrstuvwxyz'

def I():
	return int(input().strip())

def S():
	return input().strip()

def IL():
	return list(map(int, input().split()))

def SL():
	return list(map(str, input().split()))

def ILs(n):
	return list((int(input()) for _ in range(n)))

def SLs(n):
	return list((input().strip() for _ in range(n)))

def ILL(n):
	return [list(map(int, input().split())) for _ in range(n)]

def SLL(n):
	return [list(map(str, input().split())) for _ in range(n)]
(N, MOD) = IL()

def DD(arg):
	return defaultdict(arg)

def inv(n):
	return pow(n, MOD - 2, MOD)
kaijo_memo = []

def kaijo(n):
	if len(kaijo_memo) > n:
		return kaijo_memo[n]
	if len(kaijo_memo) == 0:
		kaijo_memo.append(1)
	while len(kaijo_memo) <= n:
		kaijo_memo.append(kaijo_memo[-1] * len(kaijo_memo) % MOD)
	return kaijo_memo[n]
gyaku_kaijo_memo = []

def gyaku_kaijo(n):
	if len(gyaku_kaijo_memo) > n:
		return gyaku_kaijo_memo[n]
	if len(gyaku_kaijo_memo) == 0:
		gyaku_kaijo_memo.append(1)
	while len(gyaku_kaijo_memo) <= n:
		gyaku_kaijo_memo.append(gyaku_kaijo_memo[-1] * pow(len(gyaku_kaijo_memo), MOD - 2, MOD) % MOD)
	return gyaku_kaijo_memo[n]

def nCr(n, r):
	if n == r:
		return 1
	if n < r or r < 0:
		return 0
	ret = 1
	ret = ret * kaijo(n) % MOD
	ret = ret * gyaku_kaijo(r) % MOD
	ret = ret * gyaku_kaijo(n - r) % MOD
	return ret

def factorization(n):
	arr = []
	temp = n
	for i in range(2, int(-(-n ** 0.5 // 1)) + 1):
		if temp % i == 0:
			cnt = 0
			while temp % i == 0:
				cnt += 1
				temp //= i
			arr.append([i, cnt])
	if temp != 1:
		arr.append([temp, 1])
	if arr == []:
		arr.append([n, 1])
	return arr

def make_divisors(n):
	divisors = []
	for i in range(1, int(n ** 0.5) + 1):
		if n % i == 0:
			divisors.append(i)
			if i != n // i:
				divisors.append(n // i)
	return divisors

def make_primes(N):
	max = int(math.sqrt(N))
	seachList = [i for i in range(2, N + 1)]
	primeNum = []
	while seachList[0] <= max:
		primeNum.append(seachList[0])
		tmp = seachList[0]
		seachList = [i for i in seachList if i % tmp != 0]
	primeNum.extend(seachList)
	return primeNum

def gcd(a, b):
	while b:
		(a, b) = (b, a % b)
	return a

def lcm(a, b):
	return a * b // gcd(a, b)

def count_bit(n):
	count = 0
	while n:
		n &= n - 1
		count += 1
	return count

def base_10_to_n(X, n):
	if X // n:
		return base_10_to_n(X // n, n) + [X % n]
	return [X % n]

def base_n_to_10(X, n):
	return sum((int(str(X)[-i - 1]) * n ** i for i in range(len(str(X)))))

def base_10_to_n_without_0(X, n):
	X -= 1
	if X // n:
		return base_10_to_n_without_0(X // n, n) + [X % n]
	return [X % n]

def int_log(n, a):
	count = 0
	while n >= a:
		n //= a
		count += 1
	return count
order = []
d = [INF] * N

def bfs(graph, start):
	N = len(graph)
	d[start] = 0
	q = deque([start])
	while q:
		u = q.popleft()
		order.append(u)
		for v in graph[u]:
			if d[v] != INF:
				continue
			d[v] = d[u] + 1
			q.append(v)
graph = [[] for i in range(N)]
for _ in range(N - 1):
	(a, b) = IL()
	graph[a - 1].append(b - 1)
	graph[b - 1].append(a - 1)
bfs(graph, 0)
dp = [0 for i in range(N)]
cum = [None for i in range(N)]
for x in order[::-1]:
	cum1 = [1]
	for y in graph[x]:
		if d[x] < d[y]:
			cum1.append(cum1[-1] * (dp[y] + 1) % MOD)
	cum2 = [1]
	for y in graph[x][::-1]:
		if d[x] < d[y]:
			cum2.append(cum2[-1] * (dp[y] + 1) % MOD)
	dp[x] = cum1[-1]
	cum[x] = [cum1, cum2]
factor = [1 for i in range(N)]
for x in order:
	i = 0
	for y in graph[x]:
		if d[x] < d[y]:
			dpinved = cum[x][0][i] * cum[x][1][len(cum[x][0]) - 2 - i]
			factor[y] = (dpinved * factor[x] + 1) % MOD
			i += 1
for i in range(N):
	print(dp[i] * factor[i] % MOD)