#include <bits/stdc++.h>
using namespace std;
const int inf = 1000000007;
const long long linf = 1ll * inf * inf;
const int N = 500000 + 7;
const int M = 31;
const int multipleTest = 0;
class SegmentTree {
 public:
  const static int MAXN = N;
  struct node {
    long long val;
    int lz;
    int leftChild;
    int rightChild;
    int leftIdx, rightIdx;
    int sz;
    node() {
      val = lz = 0;
      rightChild = leftChild = -1;
    }
    void reset(int u, int v, int _left, int _right) {
      val = lz = 0;
      leftChild = _left;
      rightChild = _right;
      leftIdx = u;
      rightIdx = v;
      sz = rightIdx - leftIdx + 1;
    }
  };
  node tree[MAXN * 2];
  int cnt = 0;
  void buildTree(node& root, int l, int r) {
    if (l == r) {
      root.reset(l, r, -1, -1);
      return;
    }
    int g = (l + r) >> 1;
    int leftChild = cnt++, rightChild = cnt++;
    buildTree(tree[leftChild], l, g);
    buildTree(tree[rightChild], g + 1, r);
    root.reset(l, r, leftChild, rightChild);
  }
  void init(int l, int r) {
    cnt = 1;
    buildTree(tree[0], l, r);
  }
  inline void pushDown(node& root, int val) {
    root.val += val * root.sz;
    root.lz += val;
  }
  inline void updateLz(node& root) {
    if (root.lz) {
      pushDown(tree[root.leftChild], root.lz);
      pushDown(tree[root.rightChild], root.lz);
      root.lz = 0;
    }
  }
  void update(node& root, int u, int v) {
    if (root.leftIdx == u && root.rightIdx == v) {
      pushDown(root, 1);
      return;
    }
    updateLz(root);
    int g = (root.leftIdx + root.rightIdx) >> 1;
    if (u <= g) update(tree[root.leftChild], u, min(g, v));
    if (g < v) update(tree[root.rightChild], max(u, g + 1), v);
    root.val = tree[root.leftChild].val + tree[root.rightChild].val;
    return;
  }
  void update(int u, int v) { update(tree[0], u, v); }
  long long get(node& root, int u, int v) {
    if (u <= root.leftIdx && root.rightIdx <= v) return root.val;
    if (u > root.rightIdx || v < root.leftIdx) return 0;
    updateLz(root);
    long long res =
        get(tree[root.leftChild], u, v) + get(tree[root.rightChild], u, v);
    return res;
  }
  long long get(int u, int v) { return get(tree[0], u, v); }
} segmentTree;
vector<int> adj[N];
int pa[N];
int pos[N];
int nxt[N], f[N];
int depth[N];
int root[N];
int k = 0;
int n;
vector<int> ver[N];
void dfs(int u, int r) {
  pa[u] = r;
  f[u] = 1;
  ver[depth[u]].push_back(u);
  for (int v : adj[u]) {
    if (v != r) {
      depth[v] = depth[u] + 1;
      dfs(v, u);
      f[u] += f[v];
      if (nxt[u] == 0 || f[nxt[u]] < f[v]) {
        nxt[u] = v;
      }
    }
  }
}
void buildHLD() {
  for (int i = 0; i < n; ++i) {
    for (int u : ver[i]) {
      if (pos[u] == 0) {
        root[u] = u;
        pos[u] = ++k;
        int v = u;
        while (nxt[v]) {
          v = nxt[v];
          pos[v] = ++k;
          root[v] = u;
        }
      }
    }
  }
}
long long res[N];
void update(int u) {
  while (u != -1) {
    int r = root[u];
    segmentTree.update(pos[r], pos[u]);
    u = pa[r];
  }
}
long long get(int u) {
  long long cur = 0;
  while (u != -1) {
    int r = root[u];
    cur += segmentTree.get(pos[r], pos[u]);
    u = pa[r];
  }
  return cur;
}
void solve() {
  cin >> n;
  for (int i = (1), _b = (n + 1); i < _b; ++i) {
    int u;
    scanf("%d", &u);
    adj[u].push_back(i);
  }
  dfs(adj[0].back(), -1);
  buildHLD();
  segmentTree.init(1, n);
  for (int d = 0; d < n; ++d) {
    for (int u : ver[d]) {
      update(u);
    }
    for (int u : ver[d]) {
      res[u] = get(u) - (d + 1);
    }
  }
  string rr = "";
  for (int i = (1), _b = (n); i <= _b; ++i) {
    if (res[i]) {
      string cur = "";
      while (res[i]) {
        int c = res[i] % 10;
        cur += char(c + '0');
        res[i] /= 10;
      }
      reverse(cur.begin(), cur.end());
      rr += cur;
    } else
      rr += '0';
    rr += ' ';
  }
  cout << rr;
}
int main() {
  int Test = 1;
  if (multipleTest) {
    cin >> Test;
  }
  for (int i = 0; i < Test; ++i) {
    solve();
  }
}
