Problem:
Score : 600 points

Problem Statement

We have a tree with N vertices numbered 1 to N. The i-th edge in this tree connects Vertex a_i and b_i.
For each k=1, ..., N, solve the problem below:

Consider writing a number on each vertex in the tree in the following manner:

First, write 1 on Vertex k.

Then, for each of the numbers 2, ..., N in this order, write the number on the vertex chosen as follows:

Choose a vertex that still does not have a number written on it and is adjacent to a vertex with a number already written on it. If there are multiple such vertices, choose one of them at random.

Find the number of ways in which we can write the numbers on the vertices, modulo (10^9+7).

Constraints

2 \leq N \leq 2 \times 10^5

1 \leq a_i,b_i \leq N

The given graph is a tree.

Input

Input is given from Standard Input in the following format:

N
a_1 b_1
:
a_{N-1} b_{N-1}

Output

For each k=1, 2, ..., N in this order, print a line containing the answer to the problem.

Sample Input 1

3
1 2
1 3

Sample Output 1

2
1
1

The graph in this input is as follows:

For k=1, there are two ways in which we can write the numbers on the vertices, as follows:

Writing 1, 2, 3 on Vertex 1, 2, 3, respectively

Writing 1, 3, 2 on Vertex 1, 2, 3, respectively

Sample Input 2

2
1 2

Sample Output 2

1
1

The graph in this input is as follows:

Sample Input 3

5
1 2
2 3
3 4
3 5

Sample Output 3

2
8
12
3
3

The graph in this input is as follows:

Sample Input 4

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

Sample Output 4

40
280
840
120
120
504
72
72

The graph in this input is as follows:

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

#[doc = " https://github.com/akiradeveloper/rust-comp-snippets"]
#[allow(unused_imports)]
use std::cmp::{max, min, Ordering};
#[allow(unused_imports)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
#[allow(unused_imports)]
use std::iter::FromIterator;
#[macro_export]
macro_rules ! chmax { ( $ x : expr , $ ( $ v : expr ) ,+ ) => { $ ( $ x = std :: cmp :: max ( $ x ,$ v ) ; ) + } ; }
#[macro_export]
macro_rules ! chmin { ( $ x : expr , $ ( $ v : expr ) ,+ ) => { $ ( $ x = std :: cmp :: min ( $ x ,$ v ) ; ) + } ; }
#[macro_export]
macro_rules ! max { ( $ x : expr ) => ( $ x ) ; ( $ x : expr , $ ( $ xs : expr ) ,+ ) => { std :: cmp :: max ( $ x , max ! ( $ ( $ xs ) ,+ ) ) } ; }
#[macro_export]
macro_rules ! min { ( $ x : expr ) => ( $ x ) ; ( $ x : expr , $ ( $ xs : expr ) ,+ ) => { std :: cmp :: min ( $ x , min ! ( $ ( $ xs ) ,+ ) ) } ; }
#[macro_export]
macro_rules ! dvec { ( $ t : expr ; $ len : expr ) => { vec ! [ $ t ; $ len ] } ; ( $ t : expr ; $ len : expr , $ ( $ rest : expr ) ,* ) => { vec ! [ dvec ! ( $ t ; $ ( $ rest ) ,* ) ; $ len ] } ; }
#[macro_export]
macro_rules ! cfor { ( ; $ ( $ rest : tt ) * ) => { cfor ! ( ( ) ; $ ( $ rest ) * ) } ; ( $ ( $ init : stmt ) ,+; ; $ ( $ rest : tt ) * ) => { cfor ! ( $ ( $ init ) ,+; ! false ; $ ( $ rest ) * ) } ; ( $ ( $ init : stmt ) ,+; $ cond : expr ; ; $ body : block ) => { cfor ! { $ ( $ init ) ,+; $ cond ; ( ) ; $ body } } ; ( $ ( $ init : stmt ) ,+; $ cond : expr ; $ ( $ step : expr ) ,+; $ body : block ) => { { $ ( $ init ; ) + while $ cond { let mut _first = true ; let mut _continue = false ; loop { if ! _first { _continue = true ; break } _first = false ; $ body } if ! _continue { break } $ ( $ step ; ) + } } } ; }
#[doc = " main"]
#[allow(unused_imports)]
use std::io::{stdin, stdout, BufWriter, Write};
#[macro_export]
macro_rules ! input { ( source = $ s : expr , $ ( $ r : tt ) * ) => { let mut parser = Parser :: from_str ( $ s ) ; input_inner ! { parser , $ ( $ r ) * } } ; ( parser = $ parser : ident , $ ( $ r : tt ) * ) => { input_inner ! { $ parser , $ ( $ r ) * } } ; ( new_stdin_parser = $ parser : ident , $ ( $ r : tt ) * ) => { let stdin = std :: io :: stdin ( ) ; let reader = std :: io :: BufReader :: new ( stdin . lock ( ) ) ; let mut $ parser = Parser :: new ( reader ) ; input_inner ! { $ parser , $ ( $ r ) * } } ; ( $ ( $ r : tt ) * ) => { input ! { new_stdin_parser = parser , $ ( $ r ) * } } ; }
#[macro_export]
macro_rules ! input_inner { ( $ parser : ident ) => { } ; ( $ parser : ident , ) => { } ; ( $ parser : ident , $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let $ var = read_value ! ( $ parser , $ t ) ; input_inner ! { $ parser $ ( $ r ) * } } ; }
#[macro_export]
macro_rules ! read_value { ( $ parser : ident , ( $ ( $ t : tt ) ,* ) ) => { ( $ ( read_value ! ( $ parser , $ t ) ) ,* ) } ; ( $ parser : ident , [ $ t : tt ; $ len : expr ] ) => { ( 0 ..$ len ) . map ( | _ | read_value ! ( $ parser , $ t ) ) . collect ::< Vec < _ >> ( ) } ; ( $ parser : ident , chars ) => { read_value ! ( $ parser , String ) . chars ( ) . collect ::< Vec < char >> ( ) } ; ( $ parser : ident , usize1 ) => { read_value ! ( $ parser , usize ) - 1 } ; ( $ parser : ident , $ t : ty ) => { $ parser . next ::<$ t > ( ) . expect ( "Parse error" ) } ; }
use std::io;
use std::io::BufRead;
use std::str;
pub struct Parser<R> {
    reader: R,
    buf: Vec<u8>,
    pos: usize,
}
impl Parser<io::Empty> {
    pub fn from_str(s: &str) -> Parser<io::Empty> {
        Parser {
            reader: io::empty(),
            buf: s.as_bytes().to_vec(),
            pos: 0,
        }
    }
}
impl<R: BufRead> Parser<R> {
    pub fn new(reader: R) -> Parser<R> {
        Parser {
            reader: reader,
            buf: vec![],
            pos: 0,
        }
    }
    pub fn update_buf(&mut self) {
        self.buf.clear();
        self.pos = 0;
        loop {
            let (len, complete) = {
                let buf2 = self.reader.fill_buf().unwrap();
                self.buf.extend_from_slice(buf2);
                let len = buf2.len();
                if len == 0 {
                    break;
                }
                (len, buf2[len - 1] <= 0x20)
            };
            self.reader.consume(len);
            if complete {
                break;
            }
        }
    }
    pub fn next<T: str::FromStr>(&mut self) -> Result<T, T::Err> {
        loop {
            let mut begin = self.pos;
            while begin < self.buf.len() && (self.buf[begin] <= 0x20) {
                begin += 1;
            }
            let mut end = begin;
            while end < self.buf.len() && (self.buf[end] > 0x20) {
                end += 1;
            }
            if begin != self.buf.len() {
                self.pos = end;
                return str::from_utf8(&self.buf[begin..end]).unwrap().parse::<T>();
            } else {
                self.update_buf();
            }
        }
    }
}
#[allow(unused_macros)]
macro_rules ! debug { ( $ ( $ a : expr ) ,* ) => { eprintln ! ( concat ! ( $ ( stringify ! ( $ a ) , " = {:?}, " ) ,* ) , $ ( $ a ) ,* ) ; } }
#[doc = " https://github.com/hatoo/competitive-rust-snippets"]
const BIG_STACK_SIZE: bool = true;
#[allow(dead_code)]
fn main() {
    use std::thread;
    if BIG_STACK_SIZE {
        thread::Builder::new()
            .stack_size(32 * 1024 * 1024)
            .name("solve".into())
            .spawn(solve)
            .unwrap()
            .join()
            .unwrap();
    } else {
        solve();
    }
}
fn solve() {
    let out = stdout();
    let mut out = BufWriter::new(out.lock());
    let mc = ModComb::new(300000, 1000000007);
    #[derive(Clone)]
    struct Z {
        mc: ModComb,
    }
    #[derive(Clone, Debug)]
    struct DP {
        dp: Mod,
        szfact: Mod,
        szsum: usize,
    }
    impl Foldable for Z {
        type T = DP;
        fn id() -> DP {
            DP {
                dp: Mod::new(1),
                szfact: Mod::new(1),
                szsum: 0,
            }
        }
        fn fold(acc: DP, x: DP) -> DP {
            DP {
                dp: acc.dp * x.dp,
                szfact: acc.szfact * x.szfact,
                szsum: acc.szsum + x.szsum,
            }
        }
    }
    impl ZenHoable for Z {
        type NVal = i64;
        type EVal = i64;
        fn f(&self, _: i64, _: i64, dp: &CumRL<Self>, l: usize, r: usize) -> DP {
            let LCum = dp.lcum(l);
            let RCum = dp.rcum(r);
            let dpfact = LCum.dp * RCum.dp;
            let szfact = LCum.szfact * RCum.szfact;
            // 部分木のサイズ和
            let szsum = LCum.szsum + RCum.szsum;

            DP {
                dp: Mod::new(self.mc.fact(szsum)) * dpfact / szfact,
                szfact: Mod::new(self.mc.fact(szsum+1)),
                szsum: szsum+1,
            }
        }
    }
    input!{
        n:usize,
        e:[(usize,usize);n-1],
    }
    let z = Z {
        mc: mc.clone(),
    };
    let mut g = ZenHo::new(z, vec![0; n]);
    for (u,v) in e {
        let u=u-1;
        let v=v-1;
        g.add_edge(u,v,0);
        g.add_edge(v,u,0);
    }
    g.build(0);
    for u in 0..n {
        let m = g.g[u].len();
        let mut dpfact = Mod::new(1);
        let mut szfact = Mod::new(1);
        let mut szsum = 0;
        for j in 0..m {
            let v = g.g[u][j];
            let dp = g.calc(v, u);
            dpfact *= dp.dp;
            szfact *= dp.szfact;
            szsum += dp.szsum;
        }
        let dp = Mod::new(mc.fact(szsum)) * dpfact / szfact;
        writeln!(out,"{}",dp);
    }
}
trait Foldable {
    type T: Clone + std::fmt::Debug;
    fn id() -> Self::T;
    fn fold(acc: Self::T, x: Self::T) -> Self::T;
}
#[derive(Clone, Debug)]
struct CumRL<F: Foldable> {
    lcum: Vec<F::T>,
    rcum: Vec<F::T>,
}
impl <F: Foldable> CumRL<F> {
    pub fn new(elems: Vec<F::T>) -> CumRL<F> {
        let n = elems.len();
        let mut lcum = vec![F::id()];
        for i in 0..n {
            let x = F::fold(lcum[i].clone(), elems[i].clone());
            lcum.push(x);
        }
        let mut elems = elems;
        elems.reverse();
        let mut rcum = vec![F::id()];
        for i in 0..n {
            let x = F::fold(rcum[i].clone(), elems[i].clone());
            rcum.push(x);
        }
        CumRL {
            lcum: lcum,
            rcum: rcum,
        }
    }
    pub fn len(&self) -> usize {
        self.lcum.len() - 1
    }
    pub fn lcum(&self, len: usize) -> F::T {
        self.lcum[len].clone()
    }
    pub fn rcum(&self, len: usize) -> F::T {
        self.rcum[len].clone()
    }
}
trait ZenHoable: Foldable + Clone + Sized {
    type NVal: Clone;
    type EVal: Clone;
    fn f(&self, nvalue: Self::NVal, evalue: Self::EVal, dp: &CumRL<Self>, l: usize, r: usize) -> Self::T;
}
#[derive(Debug)]
struct ZenHo<Z: ZenHoable> {
    z: Z,
    g: Vec<Vec<usize>>,
    nvalues: Vec<Z::NVal>,
    evalues: HashMap<(usize,usize), Z::EVal>,
    dp: HashMap<(usize,usize), Z::T>,
}
impl <Z: ZenHoable> ZenHo<Z> {
    pub fn new(z: Z, nvalues: Vec<Z::NVal>) -> ZenHo<Z> {
        let n = nvalues.len();
        ZenHo {
            z: z,
            g: vec![vec![]; n],
            nvalues: nvalues, 
            evalues: HashMap::new(),
            dp: HashMap::new(),
        }
    }
    pub fn n(&self) -> usize {
        self.g.len()
    }
    pub fn add_edge(&mut self, u: usize, v: usize, eval: Z::EVal) {
        self.g[u].push(v);
        self.evalues.insert((u,v), eval);
    }
    fn init_dfs(&mut self, par: Option<usize>, u: usize) {
        for i in 0..self.g[u].len() {
            let v = self.g[u][i];
            if Some(v) == par { continue; }
            self.init_dfs(Some(u), v);
        }
        if let Some(p) = par {
            let mut dp = vec![];
            for i in 0..self.g[u].len() {
                let v = self.g[u][i];
                if Some(v) == par { continue; }
                let dpval = self.dp.get(&(v,u)).cloned().unwrap();
                dp.push(dpval);
            }
            let cumRL: CumRL<Z> = CumRL::new(dp);
            let newv = self.z.f(self.nvalues[u].clone(), self.evalues.get(&(u,p)).cloned().unwrap(), &cumRL, cumRL.len(), 0);
            self.dp.insert((u,p), newv);
        }
    }
    fn reroot_bfs(&mut self, par: Option<usize>, u: usize) {
        let mut dp = vec![];
        // we have dp v->u
        for i in 0..self.g[u].len() {
            let v = self.g[u][i];
            let x = self.dp.get(&(v,u)).cloned().unwrap();
            dp.push(x);
        }
        let cum: CumRL<Z> = CumRL::new(dp);
        let n = cum.len();
        // let's make value dp u->v
        for i in 0..self.g[u].len() {
            let v = self.g[u][i];
            let L = i;
            let R = n-1-L;
            let newv = self.z.f(self.nvalues[u].clone(), self.evalues.get(&(u,v)).cloned().unwrap(), &cum, L, R);
            self.dp.insert((u,v), newv);
        }
        for i in 0..self.g[u].len() {
            let v = self.g[u][i];
            if Some(v) == par { continue; }
            self.reroot_bfs(Some(u), v);
        }
    }
    #[doc = "O(n)"]
    pub fn build(&mut self, root: usize) {
        self.init_dfs(None, root);
        self.reroot_bfs(None, root);
    }
    pub fn calc(&self, u: usize, v: usize) -> Z::T {
        self.dp.get(&(u,v)).cloned().unwrap()
    }
}

#[derive(Clone)]
struct ModComb {
    fact: Vec<i64>,
    fact_inv: Vec<i64>,
    n: usize,
    p: i64,
}
impl ModComb {
    fn initialize(ft: &mut Self) {
        let n = ft.n;
        ft.fact[0] = 1;
        for i in 1..n {
            ft.fact[i] = (ft.fact[i - 1] * i as i64) % ft.p;
        }
        ft.fact_inv[n - 1] = modpow(ft.fact[n - 1], ft.p - 2, ft.p);
        for i in (0..n - 1).rev() {
            ft.fact_inv[i] = (ft.fact_inv[i + 1] * (i + 1) as i64) % ft.p;
        }
    }
    #[doc = "O(N)"]
    fn new(max_n: usize, p: i64) -> ModComb {
        let mut ft = ModComb {
            fact: vec![0; max_n + 1],
            fact_inv: vec![0; max_n + 1],
            n: max_n + 1,
            p: p,
        };
        Self::initialize(&mut ft);
        ft
    }
    fn fact(&self, n: usize) -> i64 {
        self.fact[n]
    }
    #[doc = "choose k numbers from 1..n"]
    fn nCk(&self, n: i64, k: i64) -> i64 {
        if n < k {
            return 0;
        }
        (self.nPk(n, k) * self.fact_inv[k as usize]) % self.p
    }
    fn nPk(&self, n: i64, k: i64) -> i64 {
        if n < k {
            return 0;
        }
        self.fact[n as usize] * self.fact_inv[(n - k) as usize] % self.p
    }
    #[doc = "split k into n number as x1+x2+...xn=k"]
    fn nHk(&self, n: i64, k: i64) -> i64 {
        if n == 0 && k == 0 {
            return 1;
        }
        self.nCk(n + k - 1, k)
    }
    #[doc = "put n balls into k different boxes. In case of n=3,k+2 [[1,2],[3]]==[[3],[1,2]]"]
    fn nSk(&self, n: i64, k: i64) -> i64 {
        if n < k {
            return 0;
        }
        let mut res = 0;
        for i in 0..k + 1 {
            let v = self.nCk(k, i) * modpow(i, n, self.p) % self.p;
            if (k - i) % 2 == 1 {
                res = (res + self.p - v) % self.p;
            } else {
                res = (res + v) % self.p;
            }
        }
        return res * self.fact_inv[k as usize] % self.p;
    }
    fn nBk(&self, n: i64, k: i64) -> i64 {
        0
    }
}
#[allow(dead_code)]
#[doc = " x ^ n % m"]
pub fn modpow(x: i64, n: i64, m: i64) -> i64 {
    let mut res = 1;
    let mut x = x % m;
    let mut n = n;
    while n > 0 {
        if n & 1 == 1 {
            res = (res * x) % m;
        }
        x = (x * x) % m;
        n >>= 1;
    }
    res
}
pub mod modular {
    const M: i64 = 1_000_000_007;
    #[derive(Debug, Clone, Copy, Default, PartialOrd, Ord, PartialEq, Eq)]
    pub struct Mod(pub i64);
    impl ::std::fmt::Display for Mod {
        fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
            write!(f, "{}", self.0)
        }
    }
    impl Mod {
        pub fn new(v: i64) -> Mod {
            Mod((v + M) % M)
        }
        pub fn pow(self, mut r: i64) -> Mod {
            let mut k = self;
            let mut ret = 1.into();
            while r > 0 {
                if r % 2 != 0 {
                    ret = ret * k;
                }
                r /= 2;
                k = k * k;
            }
            ret
        }
        pub fn recip(self) -> Mod {
            self.pow(M - 2)
        }
    }
    use std::ops::*;
    impl<T: Into<Mod>> Add<T> for Mod {
        type Output = Mod;
        fn add(self, rhs: T) -> Self::Output {
            Mod::new(self.0 + rhs.into().0)
        }
    }
    impl<T: Into<Mod>> AddAssign<T> for Mod {
        fn add_assign(&mut self, rhs: T) {
            *self = *self + rhs;
        }
    }
    impl<T: Into<Mod>> Sub<T> for Mod {
        type Output = Mod;
        fn sub(self, rhs: T) -> Self::Output {
            Mod::new(self.0 - rhs.into().0 + M)
        }
    }
    impl<T: Into<Mod>> SubAssign<T> for Mod {
        fn sub_assign(&mut self, rhs: T) {
            *self = *self - rhs;
        }
    }
    impl<T: Into<Mod>> Mul<T> for Mod {
        type Output = Mod;
        fn mul(self, rhs: T) -> Self::Output {
            Mod::new(self.0 * rhs.into().0)
        }
    }
    impl<T: Into<Mod>> MulAssign<T> for Mod {
        fn mul_assign(&mut self, rhs: T) {
            *self = *self * rhs;
        }
    }
    impl<T: Into<Mod>> Div<T> for Mod {
        type Output = Mod;
        fn div(self, rhs: T) -> Self::Output {
            self * rhs.into().recip()
        }
    }
    impl<T: Into<Mod>> DivAssign<T> for Mod {
        fn div_assign(&mut self, rhs: T) {
            *self = *self / rhs;
        }
    }
    impl Neg for Mod {
        type Output = Mod;
        fn neg(self) -> Self::Output {
            Mod(0) - self
        }
    }
    impl<T: ::std::convert::Into<i64>> ::std::convert::From<T> for Mod {
        fn from(v: T) -> Self {
            Mod::new(v.into())
        }
    }
}
pub type Mod = modular::Mod;