// Slower C++ solution:
#include <iostream>

#include <vector>



using namespace std;

using ll = long long;



ll MOD;



vector<int> path[100010];

ll dp[100010], ans[100010];



ll dfs(int v, int r) {

    dp[v] = 1;

    for (int sv : path[v]) {

        if (sv == r) continue;

        dp[v] *= dfs(sv, v) + 1;

        dp[v] %= MOD;

    }

    return dp[v];

}



void edfs(int v, int r, ll par) {

    ans[v] = dp[v] * (par + 1) % MOD;



    vector<int> chv = {-1};

    for (int sv : path[v]) {

        if (sv == r) continue;

        chv.push_back(sv);

    }

    int L = chv.size() - 1;



    ll fore[L + 2], back[L + 2];

    fore[0] = back[L + 1] = 1;

    for (int i = 1; i <= L; ++i) fore[i] = fore[i - 1] * (dp[chv[i]] + 1) % MOD;

    for (int i = L; i >= 1; --i) back[i] = back[i + 1] * (dp[chv[i]] + 1) % MOD;



    for (int i = 1; i <= L; ++i) {

        edfs(chv[i], v, fore[i - 1] * back[i + 1] % MOD * (par + 1) % MOD);

    }

}



int main() {

    int N;

    cin >> N >> MOD;

    for (int i = 0; i < N - 1; ++i) {

        int u, v;

        cin >> u >> v;

        --u, --v;

        path[u].push_back(v);

        path[v].push_back(u);

    }



    dfs(0, -1);

    for (int v = 0; v < N; ++v) cerr << dp[v] << endl;



    edfs(0, -1, 0);

    for (int v = 0; v < N; ++v) cout << ans[v] << endl;

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 3.50484428542092x):
#include <iostream>

#include <vector>

#include <functional>



template <class T>

struct Edge {

    int from, to;

    T cost;

    Edge(int from = -1, int to = -1, T cost = 1) : from(from), to(to), cost(cost){};



    bool operator<(const Edge<T>& e) const { return this->cost < e.cost; }

    bool operator>(const Edge<T>& e) const { return this->cost > e.cost; }

};



template <class T = int>

class Graph {

public:

    explicit Graph(int N = 0) : size(N) { path.resize(size); }

    void span(int u, int v, T cost = 1) { path[u].push_back(Edge<T>(u, v, cost)); }

    std::vector<Edge<T>> operator[](int v) const { return path[v]; }



    int size;

    std::vector<std::vector<Edge<T>>> path;

};



class ModInt {

    using ll = long long;



public:

    int value;

    static int MOD;



    ModInt(ll value = 0) {

        this->value = (-MOD < value && value < MOD ? value : value % MOD);

        if (this->value < 0) this->value += MOD;

    }



    operator int() const noexcept { return this->value; }

    operator ll() const noexcept { return this->value; }



    ModInt& operator=(const ModInt& x) {

        if (this != &x) { this->value = x.value; }

        return *this;

    }



    bool operator==(const ModInt& x) const { return this->value == x.value; }

    bool operator!=(const ModInt& x) const { return !(*this == x); }



    ModInt operator+() const { return value; }

    ModInt operator-() const { return MOD - value; }

    ModInt operator~() const { return (*this) ^ ModInt(MOD - 2); }



    ModInt operator++() { return *this += 1; }

    ModInt operator--() { return *this -= 1; }



    ModInt operator++(int) {

        ModInt before = *this;

        ++(*this);

        return before;

    }

    ModInt operator--(int) {

        ModInt before = *this;

        --(*this);

        return before;

    }



    ModInt& operator+=(const ModInt& x) {

        int sum = this->value + x.value;

        return *this = (sum < MOD ? sum : sum - MOD);

    }

    ModInt& operator-=(const ModInt& x) {

        int diff = this->value - x.value;

        return *this = (diff >= 0 ? diff : diff + MOD);

    }

    ModInt& operator+=(int x) { return *this += ModInt(x); }

    ModInt& operator-=(int x) { return *this -= ModInt(x); }



    template <class T>

    ModInt& operator*=(const T& x) { return *this = ll(this->value) * ll(x) % MOD; }

    template <class T>

    ModInt& operator/=(const T& x) { return *this = (this->value % int(x) == 0 ? ModInt(this->value / int(x)) : *this * ~ModInt(x)); }

    template <class T>

    ModInt& operator^=(const T& x) {

        int n = int(x);

        ModInt b = *this;

        *this = 1;

        while (n > 0) {

            if (n & 1) *this *= b;

            n >>= 1;

            b *= b;

        }

        return *this;

    }



    template <class T>

    ModInt operator+(const T& b) const { return ModInt(*this) += b; }

    template <class T>

    ModInt operator-(const T& b) const { return ModInt(*this) -= b; }

    template <class T>

    ModInt operator*(const T& b) const { return ModInt(*this) *= b; }

    template <class T>

    ModInt operator/(const T& b) const { return ModInt(*this) /= b; }

    template <class T>

    ModInt operator^(const T& b) const { return ModInt(*this) ^= b; }

};



std::ostream& operator<<(std::ostream& os, const ModInt& x) { return os << x.value; }

std::istream& operator>>(std::istream& is, ModInt& x) { return is >> x.value; }



int ModInt::MOD = 1000000007;



template <class Weight, class Data>

class ReRooting {

    using DataMerger = std::function<Data(Data, Data)>;

    using Promoter = std::function<Data(Data, Edge<Weight>)>;



public:

    Graph<Weight> tree;

    std::vector<Data> data;

    Data id;

    DataMerger merge;

    Promoter promote;



    ReRooting(const Graph<Weight>& tree, Data id, DataMerger merge, Promoter promote)

        : tree(tree), data(tree.size), id(id), merge(merge), promote(promote) {

        dfs(0, -1);

        edfs(0, -1, id);

    }



    // vを根とする部分木の解でdataを埋める

    Data dfs(int v, int r) {

        data[v] = id;

        for (const auto& e : tree[v]) {

            if (e.to == r) continue;

            data[v] = merge(data[v], promote(dfs(e.to, v), e));

        }

        return data[v];

    }



    // vを根とする木の解を求める

    void edfs(int v, int r, Data par_data) {

        int cnum = tree[v].size();  // vから伸びる辺の数



        std::vector<std::pair<Data, int>> child;

        child.emplace_back(id, 0);  // index合わせ

        for (const auto& e : tree[v]) {

            auto d = (e.to == r ? par_data : data[e.to]);

            child.emplace_back(promote(d, e), e.to);

        }



        std::vector<Data> lacc(cnum + 2), racc(cnum + 2);

        // 左から、右からの累積和

        lacc[0] = id;

        for (int i = 1; i <= cnum; ++i) {

            lacc[i] = merge(lacc[i - 1], child[i].first);

        }

        racc[cnum + 1] = id;

        for (int i = cnum; i >= 1; --i) {

            racc[i] = merge(racc[i + 1], child[i].first);

        }



        data[v] = lacc[cnum];  // 全体の累積和が答え



        for (int i = 1; i <= cnum; ++i) {

            if (child[i].second == r) continue;

            edfs(child[i].second, v, merge(lacc[i - 1], racc[i + 1]));

        }

    }

};



int main() {

    int N, M;

    std::cin >> N >> M;

    ModInt::MOD = M;



    Graph<> tree(N);

    for (int i = 0; i < N - 1; ++i) {

        int u, v;

        std::cin >> u >> v;

        --u, --v;

        tree.span(u, v);

        tree.span(v, u);

    }



    // Data    : パターン数

    // Merger  : 積 (id = 1)

    // Promoter: +1 (全部白のパターン)

    ReRooting<int, ModInt> dp(tree, ModInt(1),

                              [](ModInt a, ModInt b) { return a * b; },

                              [](ModInt a, Edge<int> e) { return a + 1; });



    for (auto a : dp.data) std::cout << a << std::endl;

    return 0;

}