//
//  main.cpp
//

#include <algorithm>
#include <array>
#include <assert.h>
#include <iomanip>
#include <iostream>
#include <limits>
#include <math.h>
#include <memory>
#include <queue>
#include <random>
#include <set>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

using ll = int64_t;
using ull = uint64_t;

template<typename T>
vector<T> make_vec_nd(T init, size_t size) {
	return vector<T>(size, init);
}
template<typename T, typename... Args>
auto make_vec_nd(T init, size_t size, Args... rest) {
	auto inner = make_vec_nd(init, rest...);
	return vector<decltype(inner)>(size, inner);
}

struct Mod {
	static ll BASE;
	ll value = 0;
	static ll residue(ll value) { return (value % BASE + BASE) % BASE; }
	Mod(ll value)
	: value(residue(value)) {}
	Mod operator+(const Mod& rhs) const { return Mod(value + rhs.value); }
	void operator+=(const Mod& rhs) { *this = *this + rhs; }
	Mod operator-(const Mod& rhs) const { return Mod(value - rhs.value); }
	void operator-=(const Mod& rhs) { *this = *this - rhs; }
	Mod operator*(const Mod& rhs) const { return Mod(value * rhs.value); }
	void operator*=(const Mod& rhs) { *this = *this * rhs; }
};
ll Mod::BASE = 1000000007;

template<typename Monoid>
struct SegmentTree {
	using Op = function<Monoid(const Monoid& lhs, const Monoid& rhs)>;
	size_t width;
	vector<Monoid> node;
	Op op;
	Monoid unit;
	SegmentTree(const vector<Monoid>& elems, Op op, Monoid unit)
	: op(op)
	, unit(unit) {
		width = 1;
		while (width < elems.size()) {
			width *= 2;
		}
		node.resize(2 * width - 1, unit);
		for (size_t i = 0; i < elems.size(); i++) {
			node[i + width - 1] = elems[i];
		}
		for (size_t i = width - 2; i != numeric_limits<size_t>::max(); i--) {
			node[i] = op(node[2 * i + 1], node[2 * i + 2]);
		}
	}
	void update(size_t idx, Monoid elem) {
		idx += width - 1;
		node[idx] = elem;
		while (idx >= 1) {
			idx = (idx - 1) / 2;
			node[idx] = op(node[2 * idx + 1], node[2 * idx + 2]);
		}
	}
	Monoid query(size_t a, size_t b, size_t root) const {
		assert(0 <= a && b <= width);
		size_t left = root, right = root;
		while (left < width - 1) {
			left = 2 * left + 1;
		}
		left -= (width - 1);
		while (right < width - 1) {
			right = 2 * right + 2;
		}
		right -= (width - 1);
		right++;
		if (right <= a || b <= left) {
			return unit;
		}
		if (a <= left && right <= b) {
			return node[root];
		}
		Monoid ans_l = query(a, b, 2 * root + 1);
		Monoid ans_r = query(a, b, 2 * root + 2);
		return op(ans_l, ans_r);
	}
};

struct RootTree {
	struct Node {
		ll parent = -1;
		vector<ll> child;
	};
	vector<Node> nodes;
	RootTree(ll n) { nodes = vector<Node>(n, Node{(ll)-1, {}}); }
	void set_child(ll p, ll c) {
		assert(0 <= p && p < nodes.size());
		assert(0 <= c && c < nodes.size());
		assert(nodes[c].parent == -1);
		nodes[p].child.push_back(c);
		nodes[c].parent = p;
	}
};

void to_tree(ll root, const vector<vector<ll>>& neighbours, RootTree& tree,
			 vector<bool>& visited) {
	visited[root] = true;
	for (ll c : neighbours[root]) {
		if (visited[c]) {
			continue;
		}
		tree.set_child(root, c);
		to_tree(c, neighbours, tree, visited);
	}
}

Mod calc_subtrees(ll root, vector<SegmentTree<Mod>>& subtrees, const RootTree& tree) {
    Mod ans = 1; // 自分を塗る場合
    for (ll child_idx = 0; child_idx < tree.nodes[root].child.size(); child_idx++) {
        ll child = tree.nodes[root].child[child_idx];
        Mod child_res = calc_subtrees(child, subtrees, tree);
        subtrees[root].update(child_idx, child_res);
        ans *= child_res;
    }
    ans += 1; // 自分を塗らない場合
    return ans;
}

void calc_ans(ll vertex, Mod mult, vector<Mod>& ans, const vector<SegmentTree<Mod>>& subtrees, const RootTree& tree) {
    // mult = 親を塗り、vertexを塗らない方法の数
    Mod cnt = subtrees[vertex].query(0, tree.nodes[vertex].child.size(), 0); // 親を塗らない方法の数
    cnt += cnt * mult; // 親を塗る方法の数を加算
    ans[vertex] = cnt;
    for (ll child_idx = 0; child_idx < tree.nodes[vertex].child.size(); child_idx++) {
        ll child = tree.nodes[vertex].child[child_idx];
        Mod next_mult = 1; // vertexを塗り、childを塗らない方法の数を入れる
        next_mult *= subtrees[vertex].query(0, child_idx, 0);
        next_mult *= subtrees[vertex].query(child_idx+1, tree.nodes[vertex].child.size(), 0);
        // ここまでで、vertexを塗り、childと親を塗らない方法の数
        next_mult += next_mult * mult; // 親を塗る方法の数を加算
        calc_ans(child, next_mult, ans, subtrees, tree);
    }
}

int main() {
	ll N, M;
	cin >> N >> M;
	Mod::BASE = M;
	vector<vector<ll>> neighbours(N);
	for (ll i = 0; i < N - 1; i++) {
		ll x, y;
		cin >> x >> y;
		x--;
		y--;
		neighbours[x].push_back(y);
		neighbours[y].push_back(x);
	}
	RootTree tree(N);
	vector<bool> visited(N);
	to_tree(0, neighbours, tree, visited);
	vector<SegmentTree<Mod>> subtrees;
	for (ll p = 0; p < N; p++) {
		ll child_cnt = tree.nodes[p].child.size();
		subtrees.push_back(
			SegmentTree<Mod>(vector<Mod>(child_cnt, (Mod)1),
							 [](Mod lhs, Mod rhs) { return lhs * rhs; }, (Mod)1));
	}
    calc_subtrees(0, subtrees, tree);
    vector<Mod> ans(N, 1);
    calc_ans(0, (Mod)0, ans, subtrees, tree);
    for (ll i = 0; i < N; i++) {
        cout << ans[i].value << endl;
    }
}



Measured memory_bytes: 32776