#include <algorithm>
#include <cmath>
#include <complex>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
#include <functional>
#include <cstring>
#include <regex>
#include <random>
#include <cassert>
#include <stack>
using namespace std;

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define repr(i, s, n) for (int i = (s); i < (int)(n); i++)
#define revrep(i, n) for (int i = (n) - 1; i >= 0; i--)
#define revrepr(i, s, n) for (int i = (n) - 1; i >= s; i--)
#define debug(x) cerr << #x << ": " << x << "\n"
#define popcnt(x) __builtin_popcount(x)

using ll = long long;
using P = pair<int, int>;

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

template<class T>
istream& operator >>(istream &is, vector<T> &v) {
    for (int i = 0; i < (int)v.size(); i++) cin >> v.at(i);
    return is;
}

template<class T, class U>
ostream& operator <<(ostream &os, pair<T, U> p) {
    cout << '(' << p.first << ", " << p.second << ')';
    return os;
}

template<class T>
void print(const vector<T> &v, const string &delimiter) { rep(i, v.size()) cout << (0 < i ? delimiter : "") << v.at(i); cout << endl; }

template<class T>
void print(const vector<vector<T>> &vv, const string &delimiter) { for (const auto &v: vv) print(v, delimiter); }

struct ModInt {
    static ll mod;
    ll val;
    ModInt(ll v = 0) : val(v % mod) {}
    ModInt operator-() const { return ModInt(val ? mod - val : val); }
    ModInt &operator+=(ModInt a) {
        if ((val += a.val) >= mod) val -= mod;
        return *this;
    }
    ModInt &operator-=(ModInt a) {
        if ((val -= a.val) < 0) val += mod;
        return *this;
    }
    ModInt &operator*=(ModInt a) {
        val = (__uint128_t(val) * a.val) % mod;
        return *this;
    }
    ModInt &operator/=(ModInt a) {
        ll u = 1, v = a.val, s = 0, t = mod;
        while (v) {
            ll q = t / v;
            swap(s -= u * q, u);
            swap(t -= v * q, v);
        }
        a.val = (s < 0 ? s + mod : s);
        val /= t;
        return (*this) *= a;
    }
    ModInt inv() const { return ModInt(1) /= (*this); }
    bool operator<(ModInt x) const { return val < x.val; }
};
ll ModInt::mod = 1e9 + 7;

ostream &operator<<(ostream &os, ModInt a) {
    os << a.val;
    return os;
}
ModInt operator+(ModInt a, ModInt b) { return a += b; }
ModInt operator-(ModInt a, ModInt b) { return a -= b; }
ModInt operator*(ModInt a, ModInt b) { return a *= b; }
ModInt operator/(ModInt a, ModInt b) { return a /= b; }
ModInt pow(ModInt a, ll e) {
    ModInt x(1);
    for (; e > 0; e /= 2) {
        if (e % 2 == 1) x *= a;
        a *= a;
    }
    return x;
}

ModInt comb(int n, int k) {
    ModInt x = 1, y = 1;
    rep(i, k) {
        x *= n - i;
        y *= i + 1;
    }
    return x / y;
}

template<class T>
class ReRooting {
public:
    int node_count;

private:
    vector<vector<int>> adjacents;
    vector<vector<int>> index_for_adjacent;

    vector<T> res;
    vector<vector<T>> DP;

    T identity;
    function<T(T, T)> operate;
    function<T(T, int)> operate_node;

public:
    ReRooting(int _node_count,
              vector<vector<int>> _edges,
              T _identity,
              function<T(T, T)> _operate,
              function<T(T, int)> _operate_node) :
              node_count(_node_count),
              identity(_identity),
              operate(_operate),
              operate_node(_operate_node)
    {
        adjacents = vector<vector<int>>(node_count);
        index_for_adjacent = vector<vector<int>>(node_count);
        for (auto e: _edges) {
            index_for_adjacent[e[0]].push_back(adjacents[e[1]].size());
            index_for_adjacent[e[1]].push_back(adjacents[e[0]].size());
            adjacents[e[0]].push_back(e[1]);
            adjacents[e[1]].push_back(e[0]);
        }

        DP = vector<vector<T>>(adjacents.size());
        res = vector<T>(adjacents.size());
        rep(i, adjacents.size()) DP[i] = vector<T>(adjacents[i].size());

        if (node_count > 1) initialize();
        else if (node_count == 1) res[0] = operate_node(identity, 0);
    }

    T query(int node) { return res[node]; }

private:
    void initialize() {
        vector<int> parents(node_count);
        vector<int> order(node_count);

        int index = 0;
        stack<int> stk;
        stk.push(0);
        parents[0] = -1;
        while (!stk.empty()) {
            int node = stk.top(); stk.pop();
            order[index++] = node;
            for (int adj: adjacents[node]) {
                if (adj == parents[node]) continue;
                stk.push(adj);
                parents[adj] = node;
            }
        }

        revrepr(i, 1, order.size()) {
            int node = order[i];
            int parent = parents[node];

            T accum = identity;
            int parent_index = -1;
            rep(j, adjacents[node].size()) {
                if (adjacents[node][j] == parent) {
                    parent_index = j;
                    continue;
                }
                accum = operate(accum, DP[node][j]);
            }
            DP[parent][index_for_adjacent[node][parent_index]] = operate_node(accum, node);
        }

        for (int node: order) {
            T accum = identity;
            vector<T> accums_from_tail(adjacents[node].size());
            accums_from_tail.back() = identity;
            revrepr(j, 1, accums_from_tail.size())
                accums_from_tail[j - 1] = operate(DP[node][j], accums_from_tail[j]);
            rep(j, accums_from_tail.size()) {
                DP[adjacents[node][j]][index_for_adjacent[node][j]] =
                    operate_node(operate(accum, accums_from_tail[j]), node);
                accum = operate(accum, DP[node][j]);
            }
            res[node] = operate_node(accum, node);
        }
    }
};

int main() {
    int n, m;
    cin >> n >> m;
    vector<vector<int>> edges(n - 1, vector<int>(2));
    rep(i, n - 1) {
        int x, y;
        cin >> x >> y;
        x--; y--;
        edges[i][0] = x;
        edges[i][1] = y;
    }
    ModInt::mod = m;
    
    ReRooting<ModInt> res(n, edges, 1, 
                          [](ModInt a, ModInt b){ return a * b; }, 
                          [](ModInt a, int){ return a + 1; });
    rep(i, n) cout << res.query(i) - 1 << endl;
}

Measured memory_bytes: 31856