// includes {{{
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<tuple>
#include<cmath>
#include<random>
#include<cassert>
// #include<deque>
// #include<multiset>
// #include<bitset>
// #include<cstring>
// #include<bits/stdc++.h>
// }}}
using namespace std;
using ll = long long;

const int N = 2e5;
vector<vector<int>> g;
int n;

int par[N];
int ma[N]; // おやの中でmax
int ans[N];

// DoublingTree ( <graph> , initial? )
// set (i, val) or assign ( <data> )
// WARN : build(root = 0) !!!
//     or dfs(roots) & init() !!
// lca (a, b)
// query(hi, a, hi_inclusive?)
/// --- Doubilng Tree Library {{{ ///

template < class Monoid >
struct DoublingTree {
  using T = typename Monoid::T;
  int n, logn;
  vector< vector< int > > tree;
  vector< int > depth; // 0-indexed
  // [logn][n]
  vector< vector< int > > par;
  vector< vector< T > > dat;
  int log(int n) {
    int h = 1;
    while((1 << h) < n) h++;
    return h;
  }
  DoublingTree() {}
  DoublingTree(int n, const T &initial = Monoid::identity())
    : n(n),
    logn(log(n)),
    tree(n),
    depth(n),
    par(logn, vector< int >(n)),
    dat(logn, vector< T >(n, initial)) {}
  template < class InputIter, class = typename iterator_traits< InputIter >::value_type >
    DoublingTree(InputIter first, InputIter last, const T &initial = Monoid::identity())
    : DoublingTree(distance(first, last), initial) {
      copy(first, last, begin(tree));
    }
  DoublingTree(const vector< vector< int > > &tree, const T &initial = Monoid::identity())
    : DoublingTree(begin(tree), end(tree), initial) {}
  void set(int i, const T &val) { dat[0][i] = val; }
  template < class InputIter, class = typename iterator_traits< InputIter >::value_type >
    void assign(InputIter first, InputIter last) {
      assert(distance(first, last) <= n);
      copy(first, last, begin(dat[0]));
    }
  void build(const vector< int > &roots) {
    for(int root : roots) dfs(root);
    init();
  }
  void build(int root = 0) {
    dfs(root);
    init();
  }
  void init() {
    for(int k = 1; k < logn; k++) {
      for(int i = 0; i < n; i++) {
        int p = par[k - 1][i];
        if(p == -1) {
          par[k][i] = -1;
          continue;
        }
        dat[k][i] = Monoid::op(dat[k - 1][p], dat[k - 1][i]);
        par[k][i] = par[k - 1][p];
      }
    }
  }
  void dfs(int i, int p = -1, int d = 0) {
    depth[i] = d;
    par[0][i] = p;
    for(int j : tree[i])
      if(j != p) {
        dfs(j, i, d + 1);
      }
  }
  int climb(int a, ll k) {
    for(int i = logn - 1; i >= 0 && a != -1; i--)
      if(k >= (1 << i)) a = par[i][a], k -= 1 << i;
    assert(a == -1 || k == 0);
    return a;
  }

public:
  int lca(int a, int b) {
    if(depth[a] < depth[b]) swap(a, b);
    for(int k = logn - 1; k >= 0; k--) {
      int na = par[k][a];
      if(na == -1 || depth[na] < depth[b]) continue;
      a = na;
    }
    if(a == b) return a;
    for(int k = logn - 1; k >= 0; k--) {
      int na = par[k][a];
      int nb = par[k][b];
      if(na == nb) continue;
      a = na, b = nb;
    }
    return par[0][a];
  }
  T query(int hi, int a, bool inclusive = true) {
    T res = Monoid::identity();
    for(int k = logn - 1; k >= 0; k--) {
      int na = par[k][a];
      if(na == -1 || depth[na] < depth[hi]) continue;
      res = Monoid::op(dat[k][a], res);
      a = na;
    }
    if(inclusive) res = Monoid::op(dat[0][hi], res);
    return res;
  }
};

/// }}}--- ///

/// --- Monoid examples {{{ ///

#include <algorithm>

constexpr long long inf = 1e18 + 100;

struct Nothing {
  using T = char;
  using M = T;
  static constexpr T op(const T &, const T &) { return T(); }
  static constexpr T identity() { return T(); }
  template < class X >
    static constexpr X actInto(const M &, ll, ll, const X &x) {
      return x;
    }
};

struct RangeMin {
  using T = ll;
  static T op(const T &a, const T &b) { return min(a, b); }
  static constexpr T identity() { return inf; }
};

struct RangeMax {
  using T = ll;
  static T op(const T &a, const T &b) { return max(a, b); }
  static constexpr T identity() { return -inf; }
};

struct RangeSum {
  using T = ll;
  static T op(const T &a, const T &b) { return a + b; }
  static constexpr T identity() { return 0; }
};

/// }}}--- ///

using D = DoublingTree< RangeMax >;

D eca;

void dfs0(int i, int p) {
  par[i] = p;
  if(i != 0) {
    ma[i] = max(p, ma[p]);
  }
  for(int j : g[i]) if(p != j) {
    dfs0(j, i);
  }
}

vector<int> v(N);

void dfs1(int i, int p = -1, int carry = 0) {
  carry += v[i];
  ans[i] = carry;
  for(int j : g[i]) if(j != p) {
    dfs1(j, i, carry);
  }
}

int main() {
  ios::sync_with_stdio(false), cin.tie(0);
  cin >> n;
  g.resize(n);

  for(int i = 0; i < n - 1; i++) {
    int a, b; cin >> a >> b;
    a--; b--;
    g[a].emplace_back(b);
    g[b].emplace_back(a);
  }
  eca = D(g);
  for(int i = 0; i < n; i++) eca.set(i, i);
  eca.build();

  dfs0(0, -1);

  for(int i = 1; i < n; i++) {
    int j = ma[i];
    int k = eca.climb(i, eca.depth[i] - eca.depth[j] - 1);
    if(eca.query(j, i, 0) <= ma[j]) v[j]++;
    else if(j > i) v[k]++;
    else v[i]++;
  }

  dfs1(0, -1);

  v.resize(n);

  for(int i = 1; i < n; i++) {
    cout << ans[i] << (i == n - 1 ? "" : " ");
  }
  return 0;
}


Measured memory_bytes: 79060