#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
const long long M = 1000000007;
struct SegmentTree {
  int n;
  long long *tree;
  SegmentTree(int n) : n(n) {
    if (n)
      tree = new long long[n << 1];
    else
      tree = NULL;
  }
  void update(int i, long long x) {
    for (tree[i += n] = x % M; i > 0; i >>= 1)
      tree[i >> 1] = tree[i] * tree[i ^ 1] % M;
  }
  long long query(int a, int b) {
    long long Q = 1;
    for (a += n, b += n + 1; a < b; a >>= 1, b >>= 1) {
      if (a & 1) Q = (Q * tree[a++]) % M;
      if (b & 1) Q = (Q * tree[--b]) % M;
    }
    return Q;
  }
  long long queryExcept(int x) {
    return query(0, x - 1) * query(x + 1, n - 1) % M;
  }
};
int n, par[N], pos[N];
long long up[N], down[N];
SegmentTree *tree[N];
vector<int> adj[N];
void dfsDown(int u) {
  int children = 0;
  for (int i = 0; i < adj[u].size(); ++i) {
    int v = adj[u][i];
    if (v != par[u]) {
      par[v] = u;
      pos[v] = children++;
      dfsDown(v);
    }
  }
  tree[u] = new SegmentTree(children);
  for (int i = 0; i < adj[u].size(); ++i) {
    int v = adj[u][i];
    if (v != par[u]) {
      tree[u]->update(pos[v], down[v] + 1);
    }
  }
  down[u] = tree[u]->query(0, children - 1);
}
void dfsUp(int u) {
  if (!par[u])
    up[u] = 1;
  else {
    int p = par[u];
    up[u] = (up[p] * tree[p]->queryExcept(pos[u]) % M + 1) % M;
  }
  for (int i = 0; i < adj[u].size(); ++i) {
    int v = adj[u][i];
    if (v != par[u]) dfsUp(v);
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> n;
  for (int i = 2; i <= n; ++i) {
    int pi;
    cin >> pi;
    adj[i].push_back(pi);
    adj[pi].push_back(i);
  }
  dfsDown(1);
  dfsUp(1);
  for (int i = 1; i <= n; ++i) {
    if (i > 1) cout << ' ';
    cout << down[i] * up[i] % M;
  }
  cout << endl;
}
