Problem:
Score : 1200 points

Problem Statement

Takahashi's office has N rooms. Each room has an ID from 1 to N.
There are also N-1 corridors, and the i-th corridor connects Room a_i and Room b_i.
It is known that we can travel between any two rooms using only these corridors.

Takahashi has got lost in one of the rooms. Let this room be r.
He decides to get back to his room, Room 1, by repeatedly traveling in the following manner:

Travel to the room with the smallest ID among the rooms that are adjacent to the rooms already visited, but not visited yet.

Let c_r be the number of travels required to get back to Room 1.
Find all of c_2,c_3,...,c_N.
Note that, no matter how many corridors he passes through in a travel, it still counts as one travel.

Constraints

2 \leq N \leq 2\times 10^5

1 \leq a_i,b_i \leq N

a_i \neq b_i

The graph given as input is a tree.

Input

Input is given from Standard Input in the following format:

N
a_1 b_1
:
a_{N-1} b_{N-1}

Output

Print c_r for each r, in the following format:

c_2 c_3 ... c_N

Sample Input 1

6
1 5
5 6
6 2
6 3
6 4

Sample Output 1

5 5 5 1 5

For example, if Takahashi was lost in Room 2, he will travel as follows:

Travel to Room 6.

Travel to Room 3.

Travel to Room 4.

Travel to Room 5.

Travel to Room 1.

Sample Input 2

6
1 2
2 3
3 4
4 5
5 6

Sample Output 2

1 2 3 4 5

Sample Input 3

10
1 5
5 6
6 10
6 4
10 3
10 8
8 2
4 7
4 9

Sample Output 3

7 5 3 1 3 4 7 4 5

Solution in Rust (1.15.1) (judge verdict: Wrong Answer)

#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
use std::collections::*;
use std::io::{Write, BufWriter};
// https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        let mut next = || { iter.next().unwrap() };
        input_inner!{next, $($r)*}
    };
    ($($r:tt)*) => {
        let stdin = std::io::stdin();
        let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock()));
        let mut next = move || -> String{
            bytes
                .by_ref()
                .map(|r|r.unwrap() as char)
                .skip_while(|c|c.is_whitespace())
                .take_while(|c|!c.is_whitespace())
                .collect()
        };
        input_inner!{next, $($r)*}
    };
}

macro_rules! input_inner {
    ($next:expr) => {};
    ($next:expr, ) => {};

    ($next:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($next, $t);
        input_inner!{$next $($r)*}
    };
}

macro_rules! read_value {
    ($next:expr, ( $($t:tt),* )) => {
        ( $(read_value!($next, $t)),* )
    };

    ($next:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
    };

    ($next:expr, chars) => {
        read_value!($next, String).chars().collect::<Vec<char>>()
    };

    ($next:expr, usize1) => {
        read_value!($next, usize) - 1
    };

    ($next:expr, [ $t:tt ]) => {{
        let len = read_value!($next, usize);
        (0..len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
    }};

    ($next:expr, $t:ty) => {
        $next().parse::<$t>().expect("Parse error")
    };
}

/**
 * Union-Find tree.
 * Verified by yukicoder No.94 (http://yukicoder.me/submissions/82111)
 */
struct UnionFind { disj: Vec<usize>, size: Vec<usize> }

impl UnionFind {
    fn new(n: usize) -> Self {
        let mut disj = vec![0; n];
        for i in 0 .. n {
            disj[i] = i;
        }
        UnionFind { disj: disj, size: vec![1; n] }
    }
    fn root(&mut self, x: usize) -> usize {
        if x != self.disj[x] {
            let par = self.disj[x];
            let r = self.root(par);
            self.disj[x] = r;
        }
        return self.disj[x];
    }
    fn unite(self: &mut Self, x: usize, y: usize) {
        let xr = self.root(x);
        let yr = self.root(y);
        if xr != yr {
            self.size[yr] += self.size[xr];
            self.size[xr] = 0;
            self.disj[xr] = yr;
        }
    }
    #[allow(unused)]
    fn is_same_set(&mut self, x: usize, y: usize) -> bool {
        self.root(x) == self.root(y)
    }
    #[allow(unused)]
    fn size(&mut self, x: usize) -> usize {
        let x = self.root(x);
        self.size[x]
    }
}


fn find_par(v: usize, g: &[Vec<usize>], par: &mut [usize]) {
    for &w in g[v].iter() {
        if par[v] == w { continue; }
        par[w] = v;
        find_par(w, g, par);
    }
}

// For each vertex v, find how many turns are required to move up to par.
fn go_to_par(g: &[Vec<usize>], par: &[usize], dp: &mut [usize]) {
    let n = g.len();
    let mut uf = UnionFind::new(n);
    for i in 0 .. n {
        // Find the size of the only connected component containing i
        // when vertices with id < i are available
        for &w in g[i].iter() {
            if w == par[i] { continue; }
            dp[w] = if w < i {
                uf.size(w)
            } else {
                let mut size = 1;
                for &x in g[w].iter() {
                    if x == i { continue; }
                    if x < i { size += uf.size(x); }
                }
                size
            };
        }
        // Vertex i is available now
        for &w in g[i].iter() {
            if w < i { uf.unite(i, w); }
        }
    }
}

// Propagate
fn dfs2(v: usize, par: usize, acc: usize, g: &[Vec<usize>], dp1: &[usize],
        dp2: &mut [usize]) {
    dp2[v] = acc;
    for &w in g[v].iter() {
        if par == w { continue; }
        if par == g.len() {
            dfs2(w, v, 1, g, dp1, dp2);
        } else if w < par {
            dfs2(w, v, acc, g, dp1, dp2);
        } else {
            dfs2(w, v, acc + dp1[w], g, dp1, dp2);
        }
    }
}

fn solve() {
    let out = std::io::stdout();
    let mut out = BufWriter::new(out.lock());
    macro_rules! puts {
        ($format:expr) => (write!(out,$format).unwrap());
        ($format:expr, $($args:expr),+) => (write!(out,$format,$($args),*).unwrap())
    }
    input! {
        n: usize,
        uv: [(usize1, usize1); n - 1],
    }
    let mut g = vec![Vec::new(); n];
    for (u, v) in uv {
        g[u].push(v);
        g[v].push(u);
    }
    let mut par = vec![0; n];
    par[0] = n;
    find_par(0, &g, &mut par);
    let mut dp1 = vec![0; n];
    let mut dp2 = vec![0; n];
    go_to_par(&g, &par, &mut dp1);
    dfs2(0, n, 0, &g, &dp1, &mut dp2);
    // eprintln!("dp1 = {:?}", dp1);
    for i in 1 .. n {
        puts!("{}{}", dp2[i], if i == n - 1 { "\n" } else { " " });
    }
}

fn main() {
    // In order to avoid potential stack overflow, spawn a new thread.
    let stack_size = 104_857_600; // 100 MB
    let thd = std::thread::Builder::new().stack_size(stack_size);
    thd.spawn(|| solve()).unwrap().join().unwrap();
}