#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;

// NOTE:
// コレクションを参照でもポインタでもなくうっかりそのまま受け取ってしまうと、
// 大量のデータのコピーコンストラクタが走って大変なことになるので気を付けよう！


// リンクのスコア（計算済パラメータ）
// - 複数のリンクが一つのスコアを参照できる
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;
    }
  }

  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>
  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 = "";

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

    //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: 121288