// Original C++ solution (slower):
#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);

    edfs(0, -1, 0);

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

    return 0;

}


// Optimized solution to the same problem (faster):
#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;

};



#include <iostream>



class ModInt {

    using lint = long long;



private:

    int val;



    int extgcd(int a, int b, int& x, int& y) const {

        if (a < b) return extgcd(b, a, y, x);

        if (b > 0) {

            ModInt g = extgcd(b, a % b, y, x);

            y -= (a / b) * x;

            return g;

        } else {

            x = 1, y = 0;

            return a;

        }

    }



public:

    static int MOD;



    // constructor

    ModInt() : val(0){};

    ModInt(lint v) {

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

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

    }

    ModInt(const ModInt& n) : val(n.val){};



    // cast

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

    operator lint() const { return this->val; }

    operator bool() const { return this->val != 0; }



    // assignment

    ModInt& operator=(const ModInt& x) {

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

        return *this;

    }



    // unary operator

    ModInt operator+() const { return val; }

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

    ModInt operator~() const {

        int x, y;

        extgcd(this->val, MOD, x, y);

        return ModInt(x);

    }



    // increment / decrement

    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;

    }



    // compound assignment

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

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

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

    }

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

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

        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 = lint(this->val) * lint(x) % MOD; }

    template <class T>

    ModInt& operator%=(const T& x) { return *this = this->val % int(x); }

    template <class T>

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

        if (this->val % int(x) == 0) {

            this->val /= int(x);

        } else {

            *this *= ~ModInt(x);

        }

        return *this;

    }

    template <class T>

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

        int n = int(x);

        ModInt b = *this;

        if (n < 0) n = -n, b = ~b;



        *this = 1;

        while (n > 0) {

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

            n >>= 1;

            b *= b;

        }

        return *this;

    }



    // compare

    template <class T>

    friend bool operator==(const ModInt& a, const T& b) { return a.val == int(b); }

    template <class T>

    friend bool operator!=(const ModInt& a, const T& b) { return a.val != int(b); }

    template <class T>

    friend bool operator<(const ModInt& a, const T& b) { return a.val < int(b); }

    template <class T>

    friend bool operator<=(const ModInt& a, const T& b) { return a.val <= int(b); }

    template <class T>

    friend bool operator>(const ModInt& a, const T& b) { return a.val > int(b); }

    template <class T>

    friend bool operator>=(const ModInt& a, const T& b) { return a.val >= int(b); }



    // I/O

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

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

};



// arithmetic

template <class T>

ModInt operator+(const ModInt& a, const T& b) { return ModInt(a) += b; }

template <class T>

ModInt operator-(const ModInt& a, const T& b) { return ModInt(a) -= b; }

template <class T>

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

template <class T>

ModInt operator%(const ModInt& a, const T& b) { return ModInt(a) %= b; }

template <class T>

ModInt operator/(const ModInt& a, const T& b) { return ModInt(a) /= b; }

template <class T>

ModInt operator^(const ModInt& a, const T& b) { return ModInt(a) ^= b; }



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;

}


// Fastest known solution for this problem: