You are given a rooted undirected tree consisting of n vertices. Vertex 1 is the root.

Let's denote a depth array of vertex x as an infinite sequence [d_{x, 0}, d_{x, 1}, d_{x, 2}, ...], where d_{x, i} is the number of vertices y such that both conditions hold:

  * x is an ancestor of y; 
  * the simple path from x to y traverses exactly i edges. 



The dominant index of a depth array of vertex x (or, shortly, the dominant index of vertex x) is an index j such that:

  * for every k < j, d_{x, k} < d_{x, j}; 
  * for every k > j, d_{x, k} ≤ d_{x, j}. 



For every vertex in the tree calculate its dominant index.

Input

The first line contains one integer n (1 ≤ n ≤ 10^6) — the number of vertices in a tree.

Then n - 1 lines follow, each containing two integers x and y (1 ≤ x, y ≤ n, x ≠ y). This line denotes an edge of the tree.

It is guaranteed that these edges form a tree.

Output

Output n numbers. i-th number should be equal to the dominant index of vertex i.

Examples

Input

4
1 2
2 3
3 4


Output

0
0
0
0


Input

4
1 2
1 3
1 4


Output

1
0
0
0


Input

4
1 2
2 3
2 4


Output

2
1
0
0
import java.lang.*;
import java.math.*;
import java.util.*;
import java.io.*;

public class Main{
    void solve() {
        int n=ni();
        g=new int[n+1][];
        int from[]=new int[n-1];
        int to[]=new int[n-1];
        for(int i=1;i<n;i++){
            int x=ni(),y=ni();
            from[i-1]=x; to[i-1]=y;

        }
        g=packU(n,from,to);
        sz=new int[n+1];
        size=new int[n+1];
        ans=new int[n+1];
        cnt=new int[n+1];

        h=new int[n+1];
        st=new int[n+1];
        ed=new int[n+1];
        ver=new int[n+1];
        dfs(1,-1,0);
        dfs2(1,-1,0,true);
        for(int i=1;i<=n;i++) pw.println(ans[i]-h[i]);
    }
    int g[][];

    int h[];
    int sz[];
    int ans[];
    int cnt[];

    int size[];
    int st[];
    int ed[];
    int ver[];
    int tme=0;

    void add(int v,int pr,int l,int x,int curr){
        cnt[l]+=x;
        if(cnt[l]>size[curr]){
            size[curr]=cnt[l];
            ans[curr]=l;
        }else if(cnt[l]==size[curr]){
            ans[curr]=Math.min(ans[curr],l);
        }

    }
    void dfs2(int v,int pr,int l,boolean keep){
        int mx=-1,bigChild=-1;
        for(int u : g[v]){
            if(u!=pr && sz[u]>mx){
                mx=sz[u];
                bigChild=u;

            }
        }
        for(int u : g[v]){
            if(u!=pr && u!=bigChild) dfs2(u,v,l+1,false);
        }
        ans[v]=h[v];
        size[v]=1;
        if(bigChild!=-1){
            dfs2(bigChild,v,l+1,true);
            if(size[bigChild]>size[v]) {
                ans[v] = ans[bigChild];
                size[v] = size[bigChild];
            }
        }

      //  add(v,pr,l,1,v);

        cnt[h[v]]=1;
        for(int u : g[v]){
            if(u!=pr && u!=bigChild){

                for(int p=st[u];p<ed[u];p++){
                    cnt[h[ver[p]]]++;

                    if(cnt[h[ver[p]]]>size[v]){
                        size[v]=cnt[h[ver[p]]];
                        ans[v]=h[ver[p]];
                    }else if(cnt[h[ver[p]]]==size[v]){
                        ans[v]=Math.min(ans[v],h[ver[p]]);
                    }
                }
            }
        }




        if(!keep){
            //add(v,pr,l,-1,v);
           for(int p=st[v];p<ed[v];p++) cnt[h[ver[p]]]--;
        }


    }


    void dfs(int v,int pr,int l){
        sz[v]=1;
        h[v]=l;
        st[v]=tme;
        ver[tme]=v;
        tme++;
        for(int u : g[v]){
            if(u!=pr){
                dfs(u,v,l+1);
                sz[v]+=sz[u];
            }
        }
        ed[v]=tme;

    }
    static int[][] packU(int n, int[] from, int[] to) {
        int[][] g = new int[n+1][];
        int[] p = new int[n+1];
        for (int f : from)
            p[f]++;
        for (int t : to)
            p[t]++;
        for (int i = 1; i <= n; i++)
            g[i] = new int[p[i]];
        for (int i = 0; i < from.length; i++) {
            g[from[i]][--p[from[i]]] = to[i];
            g[to[i]][--p[to[i]]] = from[i];
        }
        return g;
    }

    long M=(long)1e9+7;
    InputStream is;
    PrintWriter pw;
    String INPUT = "";
    void run() throws Exception {
        is = is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        pw = new PrintWriter(System.out);

        Thread t = new Thread(null, null, "~", Runtime.getRuntime().maxMemory()){
            @Override
            public void run() {
                long s = System.currentTimeMillis();
                solve();

                pw.flush();
                if(!INPUT.isEmpty())tr(System.currentTimeMillis()-s+"ms");
            }
        };
        t.start();
        t.join();

    }

    public static void main(String[] args) throws Exception { new Main().run(); }

    private byte[] inbuf = new byte[1024];
    public int lenbuf = 0, ptrbuf = 0;

    private int readByte() {
        if(lenbuf == -1)throw new InputMismatchException();
        if(ptrbuf >= lenbuf){
            ptrbuf = 0;
            try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
            if(lenbuf <= 0)return -1;
        }
        return inbuf[ptrbuf++];
    }

    private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
    private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

    private double nd() { return Double.parseDouble(ns()); }
    private char nc() { return (char)skip(); }

    private String ns() {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private char[] ns(int n) {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while(p < n && !(isSpaceChar(b))){
            buf[p++] = (char)b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private char[][] nm(int n, int m) {
        char[][] map = new char[n][];
        for(int i = 0;i < n;i++)map[i] = ns(m);
        return map;
    }

    private int[] na(int n) {
        int[] a = new int[n];
        for(int i = 0;i < n;i++)a[i] = ni();
        return a;
    }

    private int ni() {
        int num = 0, b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }

        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private long nl() {
        long num = 0;
        int b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }

        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }
    private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
    private void tr(Object... o) { if(INPUT.length() > 0)System.out.println(Arrays.deepToString(o)); }
}