#define NDEBUG
NDEBUG


#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cstring>
#include <cmath>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <memory>
#include <queue>
#include <random>


using namespace std;

template<class T>
using vec = std::vector<T>;

template<class T>
using vec2d = std::vector<std::vector<T>>;


#define FOR(i, n) for (int i = 0; i < (n); ++i)


#define all(c) c.begin(), c.end()


// TC_REMOVE_BEGIN
/// caide keep
bool __hack = std::ios::sync_with_stdio(false);
/// caide keep
auto __hack1 = cin.tie(nullptr);
// TC_REMOVE_END


// Section with adoption of array and vector algorithms.


//#include <ext/pb_ds/tree_policy.hpp>
//#include <ext/pb_ds/assoc_container.hpp>
//
//template <class T> using StdTree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;


namespace template_util {
    

    constexpr int bytecount(uint64_t x) {
        return x ? 1 + bytecount(x >> 8) : 0;
    }

    template<int N>
    struct bytetype {
        
    };

    
    /// caide keep
    template<uint64_t N>
    struct minimal_uint : bytetype<bytecount(N)> {
    };
}


template<class T>
T next(istream& in) {
    T ret;
    in >> ret;
    return ret;
}


#define dbg(...) ;


void solve(istream& in, ostream& out) {
  auto n = next<int>(in);
  auto mod = next<int64_t>(in);
  vec2d<int> g(n);
  FOR(i, n - 1) {
    auto x = next<int>(in) - 1;
    auto y = next<int>(in) - 1;
    g[x].push_back(y);
    g[y].push_back(x);
  }
  vec<int64_t> fBlack(n, 0), fUp(n, 0);

  function<void(int, int)> dfs1 = [&](int v, int p) {
    fBlack[v] = 1;
    for (auto to : g[v]) {
      if (to == p) continue;
      dfs1(to, v);
      fBlack[v] *= (fBlack[to] + 1) % mod;
      fBlack[v] %= mod;
    }
    if (p != -1) {
      g[v].erase(find(all(g[v]), p));
    }
  };
  dfs1(0, -1);
  dbg(fBlack);

  function<void(int, int, int64_t)> dfs = [&](int v, int p, int64_t upMul) {
    if (p != -1) {
      fUp[v] = (1 + upMul) % mod;
    } else {
      fUp[v] = 1 % mod;
    }

    if (g[v].empty()) return;
    vec<int64_t> suffix(g[v].size());
    suffix[g[v].size() - 1] = (fBlack[ g[v].back() ] + 1) % mod;
    for (int i = (int) g[v].size() - 2; i >= 0; --i) {
      int64_t c = (fBlack[g[v][i]] + 1) % mod;
      suffix[i] = (suffix[i + 1] * c) % mod;
    }

    int64_t u = 1;
    if (p != -1) u = (upMul + 1) % mod;
    int64_t pr = 1, su;
    FOR(i, g[v].size()) {
      int to = g[v][i];

      if (i + 1 >= g[v].size()) {
        su = 1;
      } else {
        su = suffix[i + 1];
      }

      int64_t d = (pr * su) % mod;
      d *= u;
      d %= mod;
//      ++d;
//      d %= mod;

      dfs(to, v, d);
      pr = (pr * (fBlack[to] + 1) % mod) % mod;
    }
  };
  dfs(0, -1, 1);
  dbg(fUp);
  FOR(i, n) {
    out << (fBlack[i] * fUp[i]) % mod << "\n";
  }
}

//#include <fstream>


int main() {
//  ifstream fin("bridges.in");
//  ofstream fout("bridges.out");
    solve(cin, cout);
//  solve(fin, fout);
    return 0;
}



Measured memory_bytes: 17280