#include <stdint.h>

using u64 = uint64_t;
using u32 = uint32_t;

// https://atcoder.jp/contests/abc160/submissions/11270339
// イニシャルKさんのコードにあった謎のクラスModuloを移植
class Modulo {
public:
  Modulo(u32 n) {
    facs = new u32[n + 1];
    facs[0] = 1;
    for (u32 i = 1; i <= n; i++) {
      facs[i] = Mul(facs[i - 1], i);
    }
  }
  u32 Mul(u32 a, u32 b) {
    return (u32)(((u64)a) * b % DivineDivisor);
  }
  u32 Fac(u32 n) {
    return facs[n];
  }
  u32 Pow(u32 a, u32 m) {
    switch (m) {
    case 0:
      return 1;
    case 1:
      return a;
    default:
      u32 p1 = Pow(a, m / 2);
      u32 p2 = Mul(p1, p1);
      return ((m % 2 == 0) ? p2 : Mul(p2, a));
    }
  }
  u32 Div(u32 a, u32 b) {
    return Mul(a, Pow(b, DivineDivisor - 2));
  }
  u32 Ncr(u32 n, u32 r) {
    if (n < r) { return 0; }
    if (n == r) { return 1; }
    auto res = facs[n];
    res = Div(res, facs[r]);
    res = Div(res, facs[n - r]);
    return res;
  }

private:
  constexpr static u32 DivineDivisor = 1000000007;
  u32* facs;
};

#include "bits/stdc++.h"

using namespace std;

//#define DEBUG

using u64 = uint64_t;
using u32 = uint32_t;
using i64 = int64_t;

struct Link;


// リンクのスコア（計算済パラメータ）
// - 複数のリンクが一つのスコアを参照できる
struct LinkScore {
  LinkScore(u32 nodeCount = 0, u32 patternCount = 0)
    : NodeCount(nodeCount), PatternCount(patternCount) {
    Id = nextId++;
  }
  u32 NodeCount;
  u32 PatternCount;
  u32 Id;

#ifdef DEBUG
  void Print() {
    cout << "[Score n" << NodeCount << " p" << PatternCount << "]";
  }
#endif

private:
  static u32 nextId;
};
u32 LinkScore::nextId = 1;


// ノード: 木のそれぞれの頂点を表す
struct Node {

  int IncompleteLinkCount = 0;

  void Connect(Node* To);

  void AddScore(LinkScore* score) {
    auto it = scores.find(score);
    if (it != scores.end()) {
      it->second++;
    }
    else {
      scores[score] = 1;
    }
  }

  unordered_map<LinkScore*, u32> GetScores() const {
    return scores;
  }

  const list<Link*>* GetCLinks() const {
    return &links;
  }

  list<Link*>* GetLinks() {
    return &links;
  }

  const list<Link*>* GetCReceiveLinks() const {
    return &receiveLinks;
  }

  list<Link*>* GetReceiveLinks() {
    return &receiveLinks;
  }

  // 末端か
  bool IsTip() const {
    return links.size() < 2;
  }

#ifdef DEBUG
  int Id;
  static int NextId;

  Node() {
    Id = NextId++;
  }

  void Print();
#endif

private:
  list<Link*> links, receiveLinks;

  // <LinkScore*, nCount>
  unordered_map<LinkScore*, u32> scores;
};


// リンク: ノード間の繋がりを表す。指向性
struct Link {
  using KeyType = string;

  Link(Node* From, Node* To) : From(From), To(To) {
  }

  Node* From, * To;
  LinkScore* Score = nullptr;
  Link* Reverse = nullptr;

  Node* GetOtherSideOf(const Node* node) const {
    return node == From ? To : From;
  }

  bool Contains(const Node* node) const {
    return node == From || node == To;
  }

  // ロングキーを生成
  KeyType GetLongKey(const Node* startNode) const {
    string result = "";

    // 接続先ノードを始点とするリンクのうち、このリンクの逆向きを
    // 除く全てのリンクのショートキーにより決定する

    // Radial (放射状) テストデータにおいて、
    // ↓に & を一文字書き忘れていたせいでものすごく重くなっていた。。。
    // こういうことが起こらないように class (struct) 側でしたいのだが…
    // ポインタで返すしかないのか？

    //sort(To->Scores.begin(), To->Scores.end());

    const Node* endNode = GetOtherSideOf(startNode);

    auto ignoreScore = this->Reverse->Score;

    for (auto scoreAndCount : endNode->GetScores()) {
      auto count = scoreAndCount.second;
      if (ignoreScore == scoreAndCount.first) {
        count--;
      }
      if (count > 0) {
        result += to_string(scoreAndCount.first->Id) + 'x' + to_string(count) + '+';
      }
    }

    if (result == "") {
      // 末端
      result = "T";
    }

    return result;
  }

#ifdef DEBUG
  void Print() const;
#endif

private:
};


#ifdef DEBUG
int Node::NextId = 0;

// ノード情報を出力
void Node::Print() {
  cout << "Node#" << Id << ":\n";
  for (auto link : links) {
    cout << " ";
    link->Print();
    cout << '\n';
  }
  //cout << '\n';
};

// リンク情報を出力
void Link::Print() const {
  cout << "[Link ";
  cout << From->Id << "->" << To->Id << ' ';
  cout << "key = " << GetLongKey(From);
  if (Score != nullptr) {
    cout << ", ";
    Score->Print();
  }
  cout << "]";
};
#endif

#ifdef DEBUG
// 全ノードを出力
void PrintAllNodes(Node* nodes, int count) {
  for (int i = 0; i < count; i++) {
    nodes[i].Print();
  }
}
#endif

// 相互リンクを張る
void Node::Connect(Node* To) {
  auto link = new Link(this, To);

  links.push_back(link);
  To->receiveLinks.push_back(link);
  IncompleteLinkCount++;

  auto rlink = new Link(To, this);

  To->links.push_back(rlink);
  receiveLinks.push_back(rlink);
  To->IncompleteLinkCount++;

  link->Reverse = rlink;
  rlink->Reverse = link;
}

void Start() {
  int nodeCount;
  cin >> nodeCount;

  Node* nodes = new Node[nodeCount + 1];

  for (int i = 1; i <= nodeCount - 1; i++) {
    int a, b;
    cin >> a >> b;
    nodes[a].Connect(&nodes[b]);
  }

#if defined(DEBUG) && 0
  cout << "*Initial State*\n";
  PrintAllNodes(nodes, nodeCount + 1);
  cout << '\n';
#endif

  // Linkの Key/LinkScore 対応表
  unordered_map<Link::KeyType, unique_ptr<LinkScore>> linkKey2Score;

#ifdef DEBUG
  // 処理必要なリンク残り
  int remaining = (nodeCount - 1) * 2;
#endif

  // 計算予定のリンク
  queue<Link*> linkQueue;

  // Modulo
  Modulo modulo(200000);

  // リンクを結合する:
  // 複数のリンクのノード数、パターン数を合わせた
  // ノード数（ただ足せばいい）、パターン数（これが大変）を計算する
  auto combineLink = [&](Node* node, const Link* ignoreLink = nullptr) {

    // 一つのノードから見たパターン数の計算は、以下の2つの問題に分けられる。
    // A.どのリンク先（の集合）から選ぶか
    // B.それぞれのリンク先（の集合）について、どれから選ぶか
    // AとBそれぞれのパターン数を乗算すればいいはず。

    // A.
    // リンク先集合のノード数がたとえば2, 2, 1 なら
    // 積み木が2, 2, 1個積みあがって3つの塔になっていて、毎回一つ上の積み木を取り出す。
    // どの塔から順に取り出すか、という選び方のパターンを計算すればいい。
    //
    // 左から順にA, B, Cの塔とすると
    // たとえばBAACBのような取り出し順がある。
    // 
    // *計算法
    // 左から順に処理する。上の例で行く
    // まずAが2つ並んでいるとする。AA
    // これにBを2つ、順に差し込んでいく。AABB, BAABなど
    // 既に並んでいる数をp, 差し込む数をqとすると
    // 差し込める箇所はp + 1個。p + 1個から q 個選びだす組み合わせの公式でいける
    // そうして次はCを差し込み、また公式を使う
    // これを、塔がなくなるまで繰り返す
    // ...
    // と思ったが上の方法ではだめだった。やり直す。
    // A B CCC この例を考える。
    // B を A に入れる方法は |A| の2パターン ...[1]
    // CをABに順に入れていく。1つ目を入れる位置は|A|B|の3か所
    // しかし2個目はCが追加されているので、|A|B|C|の4か所になる
    // つまり3個追加するには、3*4*5。Cは区別しないので、Cの順番のパターンである3*2*1で割る
    // よって答えは10。 [1]をかけると20。
    // これはA B CCC の並び順のパターン数に等しい。よってこちらの計算法を使う。
    // ...
    // 既に並んでいる数を p 個、これから差し込む数を q 個とすると
    // p + q 個 から q 個選び出す組み合わせの公式でいける。きっといける

    /*
|C|C|C|

ABCCC

CCCAB
CCACB
CACCB
ACCCB

CCABC
CACBC
ACCBC

CABCC
ACBCC

ABCCC
    */

    // B.
    // こちらはAと違い、一つの塔の中で入れ替えが何パターンきくかというもの
    // 例えばABCが直列につながっているなら、ABCの1パターンしかないから1だけど、
    // AがB,Cそれぞれにつながっているなら、ABCとACBで2ということになり、
    // 塔ごとにこの数値を出してAの結果に乗算していく。
    //
    // しかしそもそもパターン数を計算するために、A, Bと問題を分けたことを思い出す
    // Bを計算するためには、その塔の中でA, Bの計算をしなければいけない。
    // ↓つまり
    // N個のノードに対しN-1個の辺ということは、
    // 1. どの方向に行っても必ず終端に行きつき、
    // 2. 循環は決してしない
    // という特徴がある。よって、それぞれの終端からA, Bの処理を順にかけていき、
    // つながっていて計算できるノードを順に計算していけば、いいということ。
    // （Bの処理を行うためには、そのリンク先の計算が完了している必要があるが、
    // 　終端については難しい処理がなく、A = 1, B = 1となるため完了と見ることができるので）

    int nodeCount = 0;	// 既に処理したNode数
    u32 a = 1;	// Aの計算結果
    u32 b = 1;	// Bの計算結果
    auto ignoreScore = ignoreLink != nullptr ? ignoreLink->Score : nullptr;
    for (auto scoreAndCount : node->GetScores()) {
      auto count = scoreAndCount.second;
      auto score = scoreAndCount.first;
      if (ignoreScore == score) {
        count--;
      }
      for (; count > 0; count--) {

        // Aの処理
        // 差込処理をしていく。nCr
      //if (nodeCount > 0) {
        a = modulo.Mul(a, modulo.Ncr(nodeCount + score->NodeCount, score->NodeCount));

        nodeCount += score->NodeCount;

        b = modulo.Mul(b, score->PatternCount);
      }
    }

    // <NodeCount, PatternCount>
    return new LinkScore(nodeCount + 1, modulo.Mul(a, b));
  };

  // リンクを評価する
  auto evaluateLink = [&](Link* link) {
    //#define DEBUG_COMPLETE_ONE_LINK

    auto startNode = link->From;

#ifdef DEBUG
    cout << "evaluating ";
    link->Print();
    cout << "\n";
#endif

    LinkScore* score;

    // ロングキーを生成
    auto&& longKey = link->GetLongKey(startNode);

    // このロングキーが既に登録されているか？
    auto it = linkKey2Score.find(longKey);
    if (it != linkKey2Score.end()) {
      // 既に登録されている
      // - リンクスコアの計算は必要ない。

#ifdef DEBUG
     //cout << "Existing link key: " << longKey << "\n";
#endif

      score = it->second.get();
    }
    else {
      // まだ登録されていない
      // - リンクスコアを計算する

#ifdef DEBUG
      //cout << "Added new link key: " << longKey << "\n";
#endif

      if (link->To->IsTip()) {
        // リンク先は末端
        linkKey2Score[longKey].reset(score = new LinkScore(1, 1));
      }
      else {
        // リンク先は末端ではない
        linkKey2Score[longKey].reset(score = combineLink(link->GetOtherSideOf(startNode), link->Reverse));
      }
    }

#ifdef DEBUG
    cout << " result: ";
    score->Print();
    cout << '\n';
#endif

    startNode->AddScore(link->Score = score);
    return score;
  };

  // リンクの評価完了により、新しく評価できるようになった
  // リンクを探して全て評価予定キューに追加する
  auto addNextQueue = [&](Link* link) {

    auto startNode = link->From;

    //auto receiverLink = find(to->GetLinks().begin(), to->GetLinks().end(), *link);

    // 完成したリンクをリストから除去
    //startNode->GetLinks()->erase(link);
    //to->GetLinks().erase(receiverLink);

    --startNode->IncompleteLinkCount;

#ifdef DEBUG
    remaining--;
#endif

    if (startNode->IncompleteLinkCount == 1) {
      // 未完成リンク = 1:
      // 未完成リンクの逆向きを、キューに追加
      //assert(startNode->GetLinks()->size() == 1);

      for (auto slink = startNode->GetLinks()->begin(); slink != startNode->GetLinks()->end(); slink++) {
        if ((*slink)->Score == nullptr) {

#ifdef DEBUG
          cout << "Adding to queue: ";
          (*slink)->Reverse->Print();
          cout << '\n';
#endif
          //auto& receiverLinks = (*slink)->GetOtherSideOf(startNode)->GetLinks();
          //linkQueue.emplace((*slink)->GetOtherSideOf(startNode), find(receiverLinks.begin(), receiverLinks.end(), *slink));
          linkQueue.push((*slink)->Reverse);
          break;
        }
      }
    }
    else if (startNode->IncompleteLinkCount == 0) {
      // 未完成リンク = 0:
      // 今回完成したリンク以外全てのリンクの逆向きをキューに追加
      for (auto rlink = startNode->GetReceiveLinks()->begin();
        rlink != startNode->GetReceiveLinks()->end(); rlink++) {

        if (*rlink == link->Reverse) {
          continue;
        }

#ifdef DEBUG
        cout << "Adding to queue: ";
        (*rlink)->Print();
        cout << '\n';
#endif
        linkQueue.push(*rlink);
      }
    }

    //delete* link, * receiverLink;

    return;
  };

#ifdef DEBUG
  cout << "* Evaluating all links connected to end point ... *\n";
#endif

  // 全ての末端に対するリンクを評価
  for (int i = 1; i <= nodeCount; i++) {
    auto& node = nodes[i];

    if (node.IsTip()) {
      assert(node.GetLinks()->size() == 1);
      auto it = node.GetReceiveLinks()->begin();

      evaluateLink(*it);
      addNextQueue(*it);
    }
  }

#ifdef DEBUG
#if 1
  PrintAllNodes(nodes, nodeCount + 1);
  cout << '\n';
#endif
#if 1
  cout << "* Evaluating remaining nodes in queue ... *\n";
  cout << "queue.size = " << linkQueue.size() << '\n';
#endif
#endif

  // リンク先ノードの持つ（このリンクの逆以外の）他の全てのリンクの
  // 評価が終わっていれば、リンクの評価をする
  // 残り処理数がなくなるまで行う
  while (linkQueue.size() > 0) {

    auto link = linkQueue.front();
    evaluateLink(link);
    addNextQueue(link);

    linkQueue.pop();
  }

#ifdef DEBUG
  assert(remaining == 0);

  cout << "*Pre-calculation completed*\n";
#if 0
  PrintAllNodes(nodes, nodeCount + 1);
#endif
#endif

  // 事前計算終了

  // ノードそれぞれにつき、そのノードを始点とした選び方のパターン数を出す
  // ＝そのノードの全リンクを結合する
  for (int i = 1; i <= nodeCount; i++) {

    unique_ptr<LinkScore> score(combineLink(&nodes[i], nullptr));
    cout << score->PatternCount << '\n';
  }

  delete[] nodes;
}

#if 1
int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  Start();
}
#endif


Measured memory_bytes: 119496