#include <stdio.h>
#include <cstdio>
#include <iostream>
#include <iomanip>
#include <queue>
#include <set>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>

int make_rooted_tree(std::vector<std::vector<long long int> > &G, long long int N, long long int root_index, std::vector<std::vector<long long int> > &G_rooted, std::vector<long long int> &par);
int sub_make_rooted_tree(std::vector<std::vector<long long int> > &G, long long int N, long long int root_index, std::vector<std::vector<long long int> > &G_rooted, std::vector<long long int> &par);

long long int fill_table1(std::vector<std::vector<long long int> > &G_rooted, std::vector<long long int> &table1, long long int index, long long int MOD);

long long int fill_table2(std::vector<std::vector<long long int> > &G_rooted, std::vector<long long int> &table1, std::vector<long long int> &par_info, std::vector<long long int> &table2, long long int index, long long int MOD);

int main(){

  // read problem
  long long int N, M, tmp1, tmp2;
  scanf("%lld%lld", &N, &M);

  std::vector<std::vector<long long int> > G(N);
  for(long long int i = 0; i < N-1; i++){
    scanf("%lld%lld", &tmp1, &tmp2);
    G[tmp1-1].push_back(tmp2-1);
    G[tmp2-1].push_back(tmp1-1);
  }

  // make rooted tree
  std::vector<std::vector<long long int> > G_rooted(N);
  std::vector<long long int> par(N);

  make_rooted_tree(G, N, 0, G_rooted, par);

  // make table1
  std::vector<long long int> table1(N);
  for(long long int i = 0; i < N; i++)table1[i] = -1;

  fill_table1(G_rooted, table1, 0, M);

  /*std::cerr << "table1: " << std::endl;
  for(long long int i = 0; i < N; i++){
    std::cout << table1[i] << std::endl;
  }*/

  // calculate answer
  std::vector<long long int> table2(N), par_info(N);

  par_info[0] = 0;
  table2[0] = table1[0];


  fill_table2(G_rooted, table1, par_info, table2, 0, M);

  std::cerr << "ans: " << std::endl;
  for(long long int i = 0; i < N; i++){
    std::cout << table2[i] << std::endl;
  }

  
}

int make_rooted_tree(std::vector<std::vector<long long int> > &G, long long int N, long long int root_index, std::vector<std::vector<long long int> > &G_rooted, std::vector<long long int> &par){
  // initialize par and call sub_make_rooted_tree
  par[root_index] = root_index;
  sub_make_rooted_tree(G, N, root_index, G_rooted, par);

  return 0;
}

int sub_make_rooted_tree(std::vector<std::vector<long long int> > &G, long long int N, long long int root_index, std::vector<std::vector<long long int> > &G_rooted, std::vector<long long int> &par){

  for(long long int i = 0; i < G[root_index].size(); i++){
    // for all connected nodes but parent node
    if(G[root_index][i] != par[root_index]){
      par[G[root_index][i]] = root_index;
      G_rooted[root_index].push_back(G[root_index][i]);
      sub_make_rooted_tree(G, N, G[root_index][i], G_rooted, par);
    }
  }

  return 0;
}

long long int fill_table1(std::vector<std::vector<long long int> > &G_rooted, std::vector<long long int> &table1, long long int index, long long int MOD){

  // if already calculated
  if(table1[index] >= 0){
    return table1[index];
  }
  // if the vertex has no child
  if(G_rooted[index].size() == 0){
    table1[index] = 1;
    return 1;
  }

  // calculate answer
  long long int ans = 1;
  for(long long int i = 0; i < G_rooted[index].size(); i++){
    ans *= (fill_table1(G_rooted, table1, G_rooted[index][i], MOD) +1);
    ans = (ans+MOD)%MOD;
  }

  table1[index] = ans;
  return ans;
}

long long int fill_table2(std::vector<std::vector<long long int> > &G_rooted, std::vector<long long int> &table1, std::vector<long long int> &par_info, std::vector<long long int> &table2, long long int index, long long int MOD){

  // make temporary table
  long long int n_child = G_rooted[index].size();

  if(n_child == 0){
    return 0;
  }

  std::vector<long long int> tmptable1(n_child+1), tmptable2(n_child+1);
  
  tmptable1[0] = 1;
  for(long long int i = 0; i < n_child; i++){
    tmptable1[i+1] = (tmptable1[i] * (table1[G_rooted[index][i]]+1) + MOD)%MOD;
  }
  tmptable2[n_child] = par_info[index]+1;
  for(long long int i = n_child-1; i >= 0; i--){
    tmptable2[i] = (tmptable2[i+1] * (table1[G_rooted[index][i]]+1) + MOD)%MOD;
  }

  // fill table2[G[index][i]]
  long long int tmp=0;
  for(long long int i = 0; i < n_child; i++){
    par_info[G_rooted[index][i]] = (tmptable1[i]*tmptable2[i+1]+MOD)%MOD;
    tmp = (1+ tmptable1[i]*tmptable2[i+1]);
    tmp = (tmp+MOD)%MOD;
    table2[G_rooted[index][i]] = (table1[G_rooted[index][i]] *tmp +MOD)%MOD;
    fill_table2(G_rooted, table1, par_info, table2, G_rooted[index][i], MOD);
  }

  return 0;
}

Measured memory_bytes: 27392