Problem:
Score : 100 points

Problem Statement

There is a tree with N vertices, numbered 1, 2, \ldots, N.
For each i (1 \leq i \leq N - 1), the i-th edge connects Vertex x_i and y_i.

Taro has decided to paint each vertex in white or black, so that any black vertex can be reached from any other black vertex by passing through only black vertices.

You are given a positive integer M.
For each v (1 \leq v \leq N), answer the following question:

Assuming that Vertex v has to be black, find the number of ways in which the vertices can be painted, modulo M.

Constraints

All values in input are integers.

1 \leq N \leq 10^5

2 \leq M \leq 10^9

1 \leq x_i, y_i \leq N

The given graph is a tree.

Input

Input is given from Standard Input in the following format:

N M
x_1 y_1
x_2 y_2
:
x_{N - 1} y_{N - 1}

Output

Print N lines.
The v-th (1 \leq v \leq N) line should contain the answer to the following question:

Assuming that Vertex v has to be black, find the number of ways in which the vertices can be painted, modulo M.

Sample Input 1

3 100
1 2
2 3

Sample Output 1

3
4
3

There are seven ways to paint the vertices, as shown in the figure below.
Among them, there are three ways such that Vertex 1 is black, four ways such that Vertex 2 is black and three ways such that Vertex 3 is black.

Sample Input 2

4 100
1 2
1 3
1 4

Sample Output 2

8
5
5
5

Sample Input 3

1 100

Sample Output 3

1

Sample Input 4

10 2
8 5
10 8
6 5
1 5
4 8
2 10
3 6
9 2
1 7

Sample Output 4

0
0
1
1
1
0
1
0
1
1

Be sure to print the answers modulo M.

Solution in Rust (1.15.1) (judge verdict: Accepted)

macro_rules ! input { ( source = $ s : expr , $ ( $ r : tt ) * ) => { let mut iter = $ s . split_whitespace ( ) ; input_inner ! { iter , $ ( $ r ) * } } ; ( iter = $ iter : ident , $ ( $ r : tt ) * ) => { let s = { use std :: io :: Read ; let mut s = String :: new ( ) ; std :: io :: stdin ( ) . read_to_string ( & mut s ) . unwrap ( ) ; s } ; let mut $ iter = s . split_whitespace ( ) ; input_inner ! { $ iter , $ ( $ r ) * } } ; ( $ ( $ r : tt ) * ) => { let s = { use std :: io :: Read ; let mut s = String :: new ( ) ; std :: io :: stdin ( ) . read_to_string ( & mut s ) . unwrap ( ) ; s } ; let mut iter = s . split_whitespace ( ) ; input_inner ! { iter , $ ( $ r ) * } } ; }
macro_rules ! input_inner { ( $ iter : expr ) => { } ; ( $ iter : expr , ) => { } ; ( $ iter : expr , mut $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let mut $ var = read_value ! ( $ iter , $ t ) ; input_inner ! { $ iter $ ( $ r ) * } } ; ( $ iter : expr , mut $ var : ident $ ( $ r : tt ) * ) => { input_inner ! { $ iter , mut $ var : usize $ ( $ r ) * } } ; ( $ iter : expr , $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let $ var = read_value ! ( $ iter , $ t ) ; input_inner ! { $ iter $ ( $ r ) * } } ; ( $ iter : expr , $ var : ident $ ( $ r : tt ) * ) => { input_inner ! { $ iter , $ var : usize $ ( $ r ) * } } ; }
macro_rules ! read_value { ( $ iter : expr , ( $ ( $ t : tt ) ,* ) ) => { ( $ ( read_value ! ( $ iter , $ t ) ) ,* ) } ; ( $ iter : expr , [ $ t : tt ; $ len : expr ] ) => { ( 0 ..$ len ) . map ( | _ | read_value ! ( $ iter , $ t ) ) . collect ::< Vec < _ >> ( ) } ; ( $ iter : expr , { chars : $ base : expr } ) => { read_value ! ( $ iter , String ) . chars ( ) . map ( | c | ( c as u8 - $ base as u8 ) as usize ) . collect ::< Vec < usize >> ( ) } ; ( $ iter : expr , { char : $ base : expr } ) => { read_value ! ( $ iter , { chars : $ base } ) [ 0 ] } ; ( $ iter : expr , chars ) => { read_value ! ( $ iter , String ) . chars ( ) . collect ::< Vec < char >> ( ) } ; ( $ iter : expr , char ) => { read_value ! ( $ iter , chars ) [ 0 ] } ; ( $ iter : expr , usize1 ) => { read_value ! ( $ iter , usize ) - 1 } ; ( $ iter : expr , $ t : ty ) => { $ iter . next ( ) . unwrap ( ) . parse ::<$ t > ( ) . unwrap ( ) } ; }
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct AnyMod {
    x: i64,
    m: i64,
}
impl AnyMod {
    #[inline]
    pub fn new(x: i64, m: i64) -> Self {
        AnyMod {
            x: Self::modulo(x, m),
            m: m,
        }
    }
    #[inline]
    pub fn modulo(x: i64, m: i64) -> i64 {
        let mut x = x % m;
        if x < 0 {
            x += m;
        }
        x
    }
    pub fn pow(self, y: usize) -> Self {
        let mut x = 1i64;
        let mut y = y;
        let mut base = self.x;
        while y > 0 {
            if y & 1 == 1 {
                x = x * base % self.m;
            }
            base = base * base % self.m;
            y = y >> 1;
        }
        AnyMod { x: x, m: self.m }
    }
    #[inline]
    pub fn inv(self) -> Self {
        let (mut x, mut s, mut t, mut u) = (1, self.x, self.m, 0);
        while t != 0 {
            let k = s / t;
            s -= k * t;
            std::mem::swap(&mut s, &mut t);
            x -= k * u;
            std::mem::swap(&mut x, &mut u);
        }
        AnyMod::new(x, self.m)
    }
}
impl std::ops::Add for AnyMod {
    type Output = Self;
    #[inline]
    fn add(self, rhs: Self) -> Self::Output {
        AnyMod {
            x: (self.x + rhs.x) % self.m,
            m: self.m,
        }
    }
}
impl<'a> std::ops::Add<AnyMod> for &'a AnyMod {
    type Output = AnyMod;
    #[inline]
    fn add(self, rhs: AnyMod) -> Self::Output {
        *self + rhs
    }
}
impl<'a> std::ops::Add<&'a AnyMod> for AnyMod {
    type Output = AnyMod;
    #[inline]
    fn add(self, rhs: &'a AnyMod) -> Self::Output {
        self + *rhs
    }
}
impl<'a> std::ops::Add for &'a AnyMod {
    type Output = AnyMod;
    #[inline]
    fn add(self, rhs: Self) -> Self::Output {
        *self + *rhs
    }
}
impl std::ops::AddAssign for AnyMod {
    #[inline]
    fn add_assign(&mut self, rhs: Self) {
        *self = *self + rhs;
    }
}
impl<'a> std::ops::AddAssign<&'a AnyMod> for AnyMod {
    #[inline]
    fn add_assign(&mut self, rhs: &'a AnyMod) {
        *self += *rhs;
    }
}
impl std::ops::Sub for AnyMod {
    type Output = Self;
    #[inline]
    fn sub(self, rhs: Self) -> Self::Output {
        Self::new(self.x - rhs.x, self.m)
    }
}
impl<'a> std::ops::Sub<AnyMod> for &'a AnyMod {
    type Output = AnyMod;
    #[inline]
    fn sub(self, rhs: AnyMod) -> Self::Output {
        *self - rhs
    }
}
impl<'a> std::ops::Sub<&'a AnyMod> for AnyMod {
    type Output = AnyMod;
    #[inline]
    fn sub(self, rhs: &'a AnyMod) -> Self::Output {
        self - *rhs
    }
}
impl<'a> std::ops::Sub for &'a AnyMod {
    type Output = AnyMod;
    #[inline]
    fn sub(self, rhs: Self) -> Self::Output {
        *self - *rhs
    }
}
impl std::ops::SubAssign for AnyMod {
    #[inline]
    fn sub_assign(&mut self, rhs: Self) {
        *self = *self - rhs;
    }
}
impl<'a> std::ops::SubAssign<&'a AnyMod> for AnyMod {
    #[inline]
    fn sub_assign(&mut self, rhs: &'a AnyMod) {
        *self -= *rhs;
    }
}
impl std::ops::Mul for AnyMod {
    type Output = Self;
    #[inline]
    fn mul(self, rhs: Self) -> Self::Output {
        AnyMod {
            x: (self.x * rhs.x) % self.m,
            m: self.m,
        }
    }
}
impl<'a> std::ops::Mul<AnyMod> for &'a AnyMod {
    type Output = AnyMod;
    #[inline]
    fn mul(self, rhs: AnyMod) -> Self::Output {
        *self * rhs
    }
}
impl<'a> std::ops::Mul<&'a AnyMod> for AnyMod {
    type Output = AnyMod;
    #[inline]
    fn mul(self, rhs: &'a AnyMod) -> Self::Output {
        self * *rhs
    }
}
impl<'a> std::ops::Mul for &'a AnyMod {
    type Output = AnyMod;
    #[inline]
    fn mul(self, rhs: Self) -> Self::Output {
        *self * *rhs
    }
}
impl std::ops::MulAssign for AnyMod {
    #[inline]
    fn mul_assign(&mut self, rhs: Self) {
        *self = *self * rhs;
    }
}
impl<'a> std::ops::MulAssign<&'a AnyMod> for AnyMod {
    #[inline]
    fn mul_assign(&mut self, rhs: &'a AnyMod) {
        *self *= *rhs;
    }
}
impl std::ops::Div for AnyMod {
    type Output = Self;
    #[inline]
    fn div(self, rhs: Self) -> Self::Output {
        self * rhs.inv()
    }
}
impl<'a> std::ops::Div<AnyMod> for &'a AnyMod {
    type Output = AnyMod;
    #[inline]
    fn div(self, rhs: AnyMod) -> Self::Output {
        *self / rhs
    }
}
impl<'a> std::ops::Div<&'a AnyMod> for AnyMod {
    type Output = AnyMod;
    #[inline]
    fn div(self, rhs: &'a AnyMod) -> Self::Output {
        self / *rhs
    }
}
impl<'a> std::ops::Div for &'a AnyMod {
    type Output = AnyMod;
    #[inline]
    fn div(self, rhs: Self) -> Self::Output {
        *self / *rhs
    }
}
impl std::ops::DivAssign for AnyMod {
    #[inline]
    fn div_assign(&mut self, rhs: Self) {
        *self = *self / rhs;
    }
}
impl<'a> std::ops::DivAssign<&'a AnyMod> for AnyMod {
    #[inline]
    fn div_assign(&mut self, rhs: &'a AnyMod) {
        *self /= *rhs;
    }
}
impl std::ops::Neg for AnyMod {
    type Output = Self;
    #[inline]
    fn neg(self) -> Self::Output {
        Self::new(-self.x, self.m)
    }
}
impl<'a> std::ops::Neg for &'a AnyMod {
    type Output = AnyMod;
    #[inline]
    fn neg(self) -> Self::Output {
        -*self
    }
}
impl std::fmt::Display for AnyMod {
    fn fmt<'a>(&self, f: &mut std::fmt::Formatter<'a>) -> Result<(), std::fmt::Error> {
        write!(f, "{}", self.x)
    }
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct Adjacent {
    pub to: usize,
    pub id: usize,
}
impl Adjacent {
    pub fn new(to: usize, id: usize) -> Adjacent {
        Adjacent { to: to, id: id }
    }
}
#[derive(Clone, Debug, Default)]
pub struct Graph {
    pub vsize: usize,
    pub esize: usize,
    pub graph: Vec<Vec<Adjacent>>,
}
impl Graph {
    pub fn new(vsize: usize) -> Graph {
        Graph {
            vsize: vsize,
            esize: 0,
            graph: vec![vec![]; vsize],
        }
    }
    pub fn add_edge(&mut self, from: usize, to: usize) {
        self.graph[from].push(Adjacent::new(to, self.esize));
        self.esize += 1;
    }
    pub fn add_undirected_edge(&mut self, u: usize, v: usize) {
        self.graph[u].push(Adjacent::new(v, self.esize));
        self.graph[v].push(Adjacent::new(u, self.esize));
        self.esize += 1;
    }
    pub fn vertexes(&self) -> std::ops::Range<usize> {
        0..self.vsize
    }
    pub fn adjacency(&self, from: usize) -> &Vec<Adjacent> {
        &self.graph[from]
    }
}
pub trait Monoid {
    type T: Clone + PartialEq;
    fn mempty(&self) -> Self::T;
    fn mappend(&self, x: &Self::T, y: &Self::T) -> Self::T;
}
#[derive(Clone, Debug)]
pub struct AnyMonoid<T: Clone, F: Fn(&T, &T) -> T> {
    id: T,
    op: F,
}
impl<T: Clone, F: Fn(&T, &T) -> T> AnyMonoid<T, F> {
    pub fn new(id: T, op: F) -> AnyMonoid<T, F> {
        AnyMonoid { id: id, op: op }
    }
}
impl<T: Clone + PartialEq, F: Fn(&T, &T) -> T> Monoid for AnyMonoid<T, F> {
    type T = T;
    #[inline]
    fn mempty(&self) -> T {
        self.id.clone()
    }
    #[inline]
    fn mappend(&self, x: &T, y: &T) -> T {
        (self.op)(x, y)
    }
}
#[derive(Clone, Debug)]
pub struct ReRooting<M: Monoid, V: Clone + Default, F: Fn(&M::T, &V) -> M::T> {
    n: usize,
    monoid: M,
    dp: Vec<M::T>,
    ep: Vec<M::T>,
    vertexes: Vec<V>,
    rooting: F,
}
impl<M: Monoid, F: Fn(&M::T, &()) -> M::T> ReRooting<M, (), F> {
    pub fn new(n: usize, monoid: M, rooting: F) -> Self {
        let dp = vec![monoid.mempty(); n];
        let ep = vec![monoid.mempty(); n * 2];
        let vertexes = vec![(); n];
        ReRooting {
            n: n,
            monoid: monoid,
            dp: dp,
            ep: ep,
            vertexes: vertexes,
            rooting: rooting,
        }
    }
}
impl<M: Monoid, V: Clone + Default, F: Fn(&M::T, &V) -> M::T> ReRooting<M, V, F> {
    pub fn from_vertexes(vertexes: Vec<V>, monoid: M, rooting: F) -> Self {
        let n = vertexes.len();
        let dp = vec![monoid.mempty(); n];
        let ep = vec![monoid.mempty(); n * 2 - 2];
        ReRooting {
            n: n,
            monoid: monoid,
            dp: dp,
            ep: ep,
            vertexes: vertexes,
            rooting: rooting,
        }
    }
    #[inline]
    pub fn eidx(&self, u: usize, a: &Adjacent) -> usize {
        a.id + (self.n - 1) * (u > a.to) as usize
    }
    #[inline]
    pub fn reidx(&self, u: usize, a: &Adjacent) -> usize {
        a.id + (self.n - 1) * (u < a.to) as usize
    }
    #[inline]
    pub fn merge(&self, x: &M::T, y: &M::T) -> M::T {
        self.monoid.mappend(x, y)
    }
    #[inline]
    pub fn add_root(&self, x: &M::T, u: usize) -> M::T {
        (self.rooting)(x, &self.vertexes[u])
    }
    pub fn dfs(&mut self, u: usize, p: usize, pi: usize, graph: &Graph) {
        for a in graph.adjacency(u) {
            let i = self.eidx(u, a);
            if a.to != p {
                self.dfs(a.to, u, i, graph);
                self.ep[pi] = self.merge(&self.ep[pi], &self.ep[i]);
            }
        }
        self.ep[pi] = self.add_root(&self.ep[pi], u);
    }
    pub fn efs(&mut self, u: usize, p: usize, graph: &Graph) {
        let adjacency = graph.adjacency(u);
        let m = adjacency.len();
        let mut left = vec![self.monoid.mempty(); m + 1];
        let mut right = vec![self.monoid.mempty(); m + 1];
        for (k, a) in adjacency.iter().enumerate() {
            let i = self.eidx(u, a);
            left[k + 1] = self.merge(&left[k], &self.ep[i]);
        }
        for (k, a) in adjacency.iter().enumerate().rev() {
            let i = self.eidx(u, a);
            right[k] = self.merge(&right[k + 1], &self.ep[i]);
        }
        self.dp[u] = self.add_root(&left[m], u);
        for (k, a) in adjacency.iter().enumerate() {
            if a.to != p {
                let i = self.reidx(u, a);
                self.ep[i] = self.merge(&left[k], &right[k + 1]);
                self.ep[i] = self.add_root(&self.ep[i], u);
                self.efs(a.to, u, graph);
            }
        }
    }
    pub fn rerooting(&mut self, graph: &Graph) {
        let n = self.n;
        for a in graph.adjacency(0) {
            let i = self.eidx(0, a);
            self.dfs(a.to, 0, i, graph);
        }
        self.efs(0, n, graph);
    }
}
#[allow(unused_imports)]
use std::io::{stdout, BufWriter, StdoutLock, Write};
fn with_bufwriter<F: FnOnce(&mut BufWriter<StdoutLock>) -> std::io::Result<()>>(
    f: F,
) -> std::io::Result<()> {
    let stdout = stdout();
    let mut writer = BufWriter::new(stdout.lock());
    f(&mut writer)
}
fn main() {
    input! { n, m: i64, xy: [(usize1, usize1); n-1] };
    let mut graph = Graph::new(n);
    let one = AnyMod::new(1, m);
    let mut re = ReRooting::new(n, AnyMonoid::new(one, |&d0, &d1| d0 * d1), |&x, _| x + one);
    for &(a, b) in &xy {
        graph.add_undirected_edge(a, b);
    }
    re.rerooting(&graph);
    with_bufwriter(|out| {
        for i in 0..n {
            writeln!(out, "{}", re.dp[i] - one)?;
        }
        Ok(())
    })
    .unwrap();
}