#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;
}


Measured memory_bytes: 36736