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 C# (Mono 4.6.2.0) (judge verdict: Time Limit Exceeded)

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
        Console.SetOut(sw);
        Solve();
        Console.Out.Flush();
    }
    static void Solve()
    {
        var N = sc.ReadInt();
        var rerooting = new Rerooting(N);
        for (int i = 0; i < N - 1; i++)
        {
            var a = sc.ReadInt();
            var b = sc.ReadInt();
            a--; b--;
            rerooting.AddEdge(a, b);
            rerooting.AddEdge(b, a);
        }
        var res = rerooting.Build();
        for (int i = 0; i < N; i++)
        {
            var ans = res[i].Comb;
            Console.WriteLine(ans);
        }
    }
    class Rerooting
    {
        /*
         * 型Data: DPテーブルに記録するデータ型
         * Identity: DPテーブルの初期値(単位元)
         * Merge: 部分木の計算結果をマージする二項演算
         * AddRoot: 部分木のマージ結果から現在の頂点を根とする部分木の答えを計算する関数
         */
        // DPテーブルに記録する型
        public struct Data
        {
            public ModInt Comb;
            public int NodeCount;
            public Data(ModInt comb, int nodeCount)
            {
                this.Comb = comb;
                this.NodeCount = nodeCount;
            }
            public override string ToString()
            {
                return this.Comb.ToString() + " " + NodeCount;
            }
        }
        public readonly Data Identity = new Data(1, 0);
        private Data Merge(Data a, Data b)
        {
            var comb = a.Comb * b.Comb;
            comb /= ModInt.Fac(b.NodeCount);
            return new Data(comb, a.NodeCount + b.NodeCount);
        }
        private Data Merge2(Data a, Data b)
        {
            var comb = a.Comb * b.Comb;
            return new Data(comb, a.NodeCount + b.NodeCount);
        }
        private Data AddRoot(Data accum, Edge edge)
        {
            var fac = ModInt.Fac(accum.NodeCount);
            var comb = fac * accum.Comb;
            var nodeCount = accum.NodeCount + 1;
            return new Data(comb, nodeCount);
        }

        public class Edge
        {
            public int From;
            public int To;
            public long Cost;
            public Edge(int from, int to, long cost = 1)
            {
                this.From = from;
                this.To = to;
                this.Cost = cost;
            }
        }
        // --------------------

        public List<Edge>[] G;
        public Data[] Ans;
        public Data[][] DP;
        public int N;
        public Rerooting(int n)
        {
            N = n;
            G = new List<Edge>[N];
            Ans = Enumerable.Repeat(Identity, N).ToArray();
            for (int i = 0; i < N; i++)
            {
                G[i] = new List<Edge>();
            }
        }
        public void AddEdge(int a, int b, long cost = 1)
        {
            G[a].Add(new Edge(a, b, cost));
        }
        public Data[] Build()
        {
            // DPテーブルの初期化
            DP = new Data[N][];
            for (int i = 0; i < N; i++)
            {
                // 初期値 Identity
                DP[i] = Enumerable.Repeat(Identity, G[i].Count).ToArray();
            }

            // 頂点0を根とする部分木について計算
            DFS(0);
            BFS(0, Identity);
            return Ans;
        }
        //private Data DFS()
        private Data DFS(int now, int prev = -1, Edge edge = null)
        {
            Data accum = Identity;
            for (int i = 0; i < G[now].Count; i++)
            {
                var next = G[now][i].To;
                if (next == prev) continue;
                // 現在の頂点からi番目の有向辺に対応する部分木の計算結果
                // メモしてからマージ
                DP[now][i] = DFS(next, now, G[now][i]);
                accum = Merge(accum, DP[now][i]);
            }
            var res = AddRoot(accum, edge);
            return res;
        }
        // 頂点nowの計算されていない逆向きの辺について計算する
        private void BFS(int now, Data data, int prev = -1, Edge edge = null)
        {
            var deg = G[now].Count;
            if (now == 2) { }

            // 直前のDfs2で計算した有向辺に対応する部分木のDPを保存
            for (int i = 0; i < deg; i++)
            {
                // この時点で頂点DP[now]の表はすべて埋まる
                if (G[now][i].To == prev) DP[now][i] = data;
            }

            // 累積マージの計算結果を保持する配列
            var CumL = Enumerable.Repeat(Identity, deg + 1).ToArray();
            var CumR = Enumerable.Repeat(Identity, deg + 1).ToArray();
            for (int i = 0; i < deg; i++)
            {
                CumL[i + 1] = Merge(CumL[i], DP[now][i]);
            }
            for (int i = deg - 1; i >= 0; i--)
            {
                CumR[i] = Merge(CumR[i + 1], DP[now][i]);
            }

            // 現在の頂点を根とする木の計算結果を更新する
            Ans[now] = AddRoot(CumL[deg], edge);

            // i番目の辺を除いたマージ結果をもって隣接する頂点に移る
            for (int i = 0; i < deg; i++)
            {
                var e = G[now][i];
                var next = e.To;
                if (next == prev) continue;
                // i番目の辺以外のマージ結果を計算
                // マージ結果に頂点を追加して部分木のデータとする
                var nextData = AddRoot(Merge2(CumL[i], CumR[i + 1]), e);
                BFS(next, nextData, now, e);
            }
        }
    }

    public struct ModInt
    {
        public const long Mod = (int)1e9 + 7;
        public long num;
        public ModInt(long n) { num = n; }
        public override string ToString() { return num.ToString(); }
        public static ModInt operator +(ModInt l, ModInt r) { l.num += r.num; if (l.num >= Mod) l.num -= Mod; return l; }
        public static ModInt operator -(ModInt l, ModInt r) { l.num -= r.num; if (l.num < 0) l.num += Mod; return l; }
        public static ModInt operator *(ModInt l, ModInt r) { return new ModInt(l.num * r.num % Mod); }
        public static ModInt operator /(ModInt l, ModInt r) { return l * Inverse(r); }
        public static implicit operator ModInt(long n) { n %= Mod; if (n < 0) n += Mod; return new ModInt(n); }
        public static ModInt Pow(ModInt v, long k) { return Pow(v.num, k); }
        public static ModInt Pow(long v, long k)
        {
            long ret = 1;
            for (k %= Mod - 1; k > 0; k >>= 1, v = v * v % Mod)
                if ((k & 1) == 1) ret = ret * v % Mod;
            return new ModInt(ret);
        }
        public static ModInt Inverse(ModInt v) { return Pow(v, Mod - 2); }
        private static List<ModInt> Facs = new List<ModInt> { 1 };
        private static List<ModInt> iFacs = new List<ModInt> { 1 };
        public static ModInt Fac(int n)
        {
            for (int i = Facs.Count; i <= n; i++)
            {
                Facs.Add(i * Facs[i - 1]);
                iFacs.Add(Inverse(Facs[i]));
            }
            return Facs[n];
        }
        public static ModInt iFac(int n)
        {
            Fac(n);
            return iFacs[n];
        }
        public static ModInt nCr(int n, int r)
        {
            if (n < r) return 0;
            if (n == r) return 1;
            if (n > (int)1e6) return nCrLoop(n, r);
            return Fac(n) * iFac(r) * iFac(n - r);
        }
        static ModInt nCrLoop(long n, long r)
        {
            ModInt num = 1;
            for (long i = 1; i <= r; i++)
            {
                num = num * (n - i + 1) / i;
            }
            return num;
        }
        public static ModInt nHr(int n, int r)
        {
            return nCr(n + r - 1, r);
        }
    }
    static Scanner sc = new Scanner();
}
class Scanner
{
    string[] S = new string[0];
    int Index = 0;
    char[] Separators = new char[] { ' ' };

    public string Next()
    {
        if (this.Index < this.S.Length) return this.S[this.Index++];
        var line = "";
        while (line == "") line = Console.ReadLine();
        this.S = line.Split(this.Separators, StringSplitOptions.RemoveEmptyEntries);
        if (this.S.Length == 0) return this.Next();
        this.Index = 0;
        return this.S[this.Index++];
    }
    public string ReadStr()
    {
        return this.Next();
    }
    public char ReadChar()
    {
        return this.Next()[0];
    }
    public int ReadInt()
    {
        return int.Parse(this.Next());
    }
    public uint ReadUInt()
    {
        return uint.Parse(this.Next());
    }
    public long ReadLong()
    {
        return long.Parse(this.Next());
    }
    public double ReadDouble()
    {
        return double.Parse(this.Next());
    }
    public Tuple<int, int> ReadTup(int add = 0)
    {
        return Tuple.Create(this.ReadInt() + add, this.ReadInt() + add);
    }
    public Tuple<long, long> ReadTupLong(int add = 0)
    {
        return Tuple.Create(this.ReadLong() + add, this.ReadLong() + add);
    }
    public Tuple<int, int, int> ReadTup3(int add = 0)
    {
        return Tuple.Create(this.ReadInt() + add, this.ReadInt() + add, this.ReadInt() + add);
    }
    public Tuple<int, int, int, int> ReadTup4(int add = 0)
    {
        return Tuple.Create(this.ReadInt() + add, this.ReadInt() + add, this.ReadInt() + add, this.ReadInt() + add);
    }
    public int[] ReadIntArray(int n)
    {
        var array = new int[n];
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = this.ReadInt();
        }
        return array;
    }
    public long[] ReadLongArray(int n)
    {
        var array = new long[n];
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = this.ReadLong();
        }
        return array;
    }
    public double[] ReadDoubleArray(int n)
    {
        var array = new double[n];
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = this.ReadDouble();
        }
        return array;
    }
    public char[] ReadCharArray(int n)
    {
        var array = new char[n];
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = this.ReadChar();
        }
        return array;
    }
    public string[] ReadStrArray(int n)
    {
        var array = new string[n];
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = this.ReadStr();
        }
        return array;
    }
    public Tuple<long, long>[] ReadTupLongArray(int n, int add = 0)
    {
        var array = new Tuple<long, long>[n];
        for (int i = 0; i < n; i++)
        {
            array[i] = this.ReadTupLong(add);
        }
        return array;
    }
    public Tuple<int, int>[] ReadTupArray(int n, int add = 0)
    {
        var array = new Tuple<int, int>[n];
        for (int i = 0; i < n; i++)
        {
            array[i] = this.ReadTup(add);
        }
        return array;
    }
    public Tuple<int, int, int>[] ReadTup3Array(int n, int add = 0)
    {
        var array = new Tuple<int, int, int>[n];
        for (int i = 0; i < n; i++)
        {
            array[i] = this.ReadTup3(add);
        }
        return array;
    }
    public Tuple<int, int, int, int>[] ReadTup4Array(int n, int add = 0)
    {
        var array = new Tuple<int, int, int, int>[n];
        for (int i = 0; i < n; i++)
        {
            array[i] = this.ReadTup4(add);
        }
        return array;
    }
}