#include <bits/stdc++.h>   using namespace std;   const int N = 2e5 + 7, inf = 1e8;   int read() {     int s = 0, w = 1;     char c;     while (c = getchar(), c >  9  || c <  0 )       if (c ==  - ) w = -1;     while (c >=  0  && c <=  9 ) s = s * 10 + c -  0 , c = getchar();     return s * w;   }   void write(int x) {     if (x < 0) x = -x, putchar( - );     if (x >= 10) write(x / 10);     putchar(x % 10 |  0 );   }   void writeln(int x) {     write(x);     puts(  );   }   struct edge {     int t, nxt;   } e[N];   struct node {     int s, tag;   };   int n, cnt, rt;   int head[N], siz[N], Mx[N], Cx[N], Mn[N], Mson[N], Bigs[N], ans[N], vis[N];   void add(int u, int t) {     e[++cnt].t = t;     e[cnt].nxt = head[u];     head[u] = cnt;   }   struct tree {     node tr[N << 1];     void pushdown(int ts) {       if (!tr[ts].tag) return;       tr[ts << 1].s = 0;       tr[ts << 1 | 1].s = 0;       tr[ts << 1].tag = 1;       tr[ts << 1 | 1].tag = 1;       tr[ts].tag = 0;     }     inline void add(int ts, int l, int r, int pos, int x) {       pushdown(ts);       tr[ts].s += x;       if (l == r) return;       int mid = (l + r) >> 1;       if (pos <= mid)         add(ts << 1, l, mid, pos, x);       else         add(ts << 1 | 1, mid + 1, r, pos, x);     }     inline void clear() {       tr[1].s = 0;       tr[1].tag = 1;     }     inline int query1(int ts, int l, int r, int L, int R) {       if (L > R) return 0;       if (l == L && r == R) return tr[ts].s;       pushdown(ts);       int mid = (l + r) >> 1;       if (R <= mid)         return query1(ts << 1, l, mid, L, R);       else if (L > mid)         return query1(ts << 1 | 1, mid + 1, r, L, R);       else         return query1(ts << 1, l, mid, L, mid) +                query1(ts << 1 | 1, mid + 1, R, mid + 1, R);     }     inline int query2(int ts, int l, int r, int L, int R) {       if (L > R || !tr[ts].s) return 0;       if (l == r) return l;       pushdown(ts);       int mid = (l + r) >> 1;       if (R <= mid)         return query2(ts << 1, l, mid, L, R);       else if (L > mid)         return query2(ts << 1 | 1, mid + 1, r, L, R);       else {         int v = query2(ts << 1 | 1, mid + 1, r, mid + 1, R);         if (v)           return v;         else           return query2(ts << 1, l, mid, L, mid);       }     }     inline int query3(int ts, int l, int r, int L, int R) {       if (L > R || !tr[ts].s) return inf;       if (l == r) return l;       pushdown(ts);       int mid = (l + r) >> 1;       if (R <= mid)         return query3(ts << 1, l, mid, L, R);       else if (L > mid)         return query3(ts << 1 | 1, mid + 1, r, L, R);       else {         int v = query3(ts << 1, l, mid, L, mid);         if (v != inf)           return v;         else           return query3(ts << 1 | 1, mid + 1, r, mid + 1, R);       }     }   } T1, T2, T3;   void chu(int &mx, int &cx, int &mn, int v, int &id, int t) {     if (v > mx)       cx = mx, mx = v, id = t;     else if (v > cx)       cx = v;     if (v) mn = min(mn, v);   }   void dfs1(int u) {     siz[u] = 1;     Mson[u] = -1;     for (int i = head[u]; i; i = e[i].nxt) {       int t = e[i].t;       dfs1(t);       siz[u] += siz[t];       chu(Mx[u], Cx[u], Mn[u], siz[t], Mson[u], t);     }     Bigs[u] = Mson[u];     chu(Mx[u], Cx[u], Mn[u], n - siz[u], Mson[u], 0);     T1.add(1, 1, n, siz[u], 1);   }   void Add(int u) {     T3.add(1, 1, n, siz[u], 1);     for (int i = head[u]; i; i = e[i].nxt) {       int t = e[i].t;       if (vis[t]) continue;       Add(t);     }   }   int query2(int ts, int l, int r, int L, int R) {     if (L > R || T1.tr[ts].s - T3.tr[ts].s <= 0) return 0;     if (l == r) return l;     T3.pushdown(ts);     int mid = (l + r) >> 1;     if (R <= mid)       return query2(ts << 1, l, mid, L, R);     else if (L > mid)       return query2(ts << 1 | 1, mid + 1, r, L, R);     else {       int v = query2(ts << 1 | 1, mid + 1, r, mid + 1, R);       if (v)         return v;       else         return query2(ts << 1, l, mid, L, mid);     }   }   int query3(int ts, int l, int r, int L, int R) {     if (L > R || T1.tr[ts].s - T3.tr[ts].s <= 0) return inf;     if (l == r) return l;     T3.pushdown(ts);     int mid = (l + r) >> 1;     if (R <= mid)       return query3(ts << 1, l, mid, L, R);     else if (L > mid)       return query3(ts << 1 | 1, mid + 1, r, L, R);     else {       int v = query3(ts << 1, l, mid, L, mid);       if (v != inf)         return v;       else         return query3(ts << 1 | 1, mid + 1, r, mid + 1, R);     }   }   void dfs2(int u) {     T1.add(1, 1, n, siz[u], -1);     T2.add(1, 1, n, siz[u], 1);     for (int i = head[u]; i; i = e[i].nxt) {       int t = e[i].t;       if (t == Bigs[u]) continue;       dfs2(t);       T3.clear();     }     if (Bigs[u] != -1) dfs2(Bigs[u]), vis[Bigs[u]] = 1;     int v = 0;     if (Mson[u] == Bigs[u]) {       v = T3.query2(1, 1, n, 1, (Mx[u] - Mn[u]) / 2);       ans[u] = max(max(Mx[u] - v, Mn[u] + v), Cx[u]);       v = T3.query3(1, 1, n, (Mx[u] - Mn[u]) / 2, n);       ans[u] = min(ans[u], max(max(Mx[u] - v, Mn[u] + v), Cx[u]));     }     Add(u);     if (Bigs[u] != -1) vis[Bigs[u]] = 0;     T1.add(1, 1, n, siz[u], 1);     T2.add(1, 1, n, siz[u], -1);     if (Mson[u] != Bigs[u]) {       v = max(           query2(1, 1, n, 1, (Mx[u] - Mn[u]) / 2),           T2.query2(1, 1, n, 1 + siz[u], min((Mx[u] - Mn[u]) / 2 + siz[u], n)) -               siz[u]);       ans[u] = max(max(Mx[u] - v, Mn[u] + v), Cx[u]);       v = min(query3(1, 1, n, (Mx[u] - Mn[u]) / 2, n),               T2.query3(1, 1, n, (Mx[u] - Mn[u]) / 2 + siz[u], n) - siz[u]);       ans[u] = min(ans[u], max(max(Mx[u] - v, Mn[u] + v), Cx[u]));     }   }   int main() {     n = read();     if (n == 1) return puts( 0 ), 0;     memset(Mn, 60, sizeof Mn);     for (int i = 1, u, v; i <= n; i++) {       u = read(), v = read();       if (u == 0)         rt = v;       else         add(u, v);     }     dfs1(rt);     dfs2(rt);     for (int i = 1; i <= n; i++) writeln(ans[i]);   }