#include <bits/stdc++.h>
using namespace std;
template <typename num_t>
inline void addmod(num_t& a, const long long& b, const int& m) {
  a = (a + b) % m;
  if (a < 0) a += m;
}
template <typename num_t>
inline void update_max(num_t& a, const num_t& b) {
  a = max(a, b);
}
template <typename num_t>
inline void update_min(num_t& a, const num_t& b) {
  a = min(a, b);
}
template <typename num_t>
num_t gcd(num_t lhs, num_t rhs) {
  return !lhs ? rhs : gcd(rhs % lhs, lhs);
}
template <typename num_t>
num_t pw(num_t n, num_t k, num_t mod) {
  long long res = 1;
  for (; k; k >>= 1) {
    if (k & 1) res = res * n % mod;
    n = 1ll * n * n % mod;
  }
  return (num_t)res;
}
const int inf = 1e9 + 7;
const long long ll_inf = 1ll * inf * inf;
const int MAX_N = 400000 + 7;
const int mod = inf;
template <typename num_t>
class SegmentTree {
 public:
  void init(int l, int r) {
    tree.resize((r - l + 1) << 1);
    queue.resize(tree.size());
    node_index = 0;
    build_tree(tree[node_index++], l, r);
    initial_value.clear();
  }
  void init(const vector<num_t>& arr) {
    initial_value = arr;
    init(0, (int)arr.size() - 1);
  }
  void update(int left_index, int right_index, const num_t& val) {
    update_(tree[0], left_index, right_index, val);
  }
  num_t get(int left_index, int right_index) {
    if (right_index < left_index) return 0;
    return tree[0].get(left_index, right_index);
  }

 private:
  struct node {
    static const num_t nil = 0;
    node *left_child, *right_child;
    int left_index, right_index;
    num_t value;
    void push_down(num_t v) { value = v; }
    void merge_node() {
      const node &lhs = *left_child, &rhs = *right_child;
      value = max(lhs.value, rhs.value);
    }
    void lazy_update() {}
    inline void init_value(num_t v = 0) { value = v; }
    num_t get(int u, int v) {
      if (u <= left_index && right_index <= v) return value;
      if (u > right_index || v < left_index) return node::nil;
      lazy_update();
      auto lhs = left_child->get(u, v);
      auto rhs = right_child->get(u, v);
      return max(lhs, rhs);
    }
    inline void init(int left, int right, node* left_child_,
                     node* right_child_) {
      left_index = left;
      right_index = right;
      left_child = left_child_;
      right_child = right_child_;
    }
    int size() const { return right_index - left_index + 1; }
  };
  vector<num_t> initial_value;
  vector<node> tree;
  vector<node*> queue;
  int node_index = 0;
  void build_tree(node& root, int left, int right) {
    if (left == right) {
      if (!initial_value.empty())
        root.init_value(initial_value[root.left_index]);
      else
        root.init_value(0);
      root.init(left, right, nullptr, nullptr);
      return;
    }
    int mid = (left + right) >> 1, lhs = node_index++, rhs = node_index++;
    build_tree(tree[lhs], left, mid);
    build_tree(tree[rhs], mid + 1, right);
    root.init(left, right, &tree[lhs], &tree[rhs]);
  }
  void update_(node& root, int u, int v, const num_t& value) {
    if (u > root.right_index || v < root.left_index) return;
    if (u <= root.left_index && root.right_index <= v) {
      root.push_down(value);
    } else {
      root.lazy_update();
      update_(*root.left_child, u, v, value);
      update_(*root.right_child, u, v, value);
      root.merge_node();
    }
  }
};
SegmentTree<int> tree;
int n;
int low[MAX_N], high[MAX_N];
int f[MAX_N];
vector<int> adj[MAX_N];
void dfs(int u, int r) {
  static int cnt = 0;
  low[u] = ++cnt;
  f[u] = 1;
  for (int v : adj[u])
    if (v != r) {
      dfs(v, u);
      f[u] += f[v];
    }
  high[u] = cnt;
}
bool check[MAX_N];
set<int> stack_trace;
void calc(int u, int r) {
  stack_trace.insert(f[u]);
  if (f[u] <= n / 2) tree.update(low[u], low[u], 0);
  int sub_tree = -1;
  for (int v : adj[u])
    if (v != r && f[v] > n / 2) {
      sub_tree = v;
    }
  if (sub_tree != -1) {
    int mx = tree.get(low[sub_tree], high[sub_tree]);
    if (f[sub_tree] - mx <= n / 2) check[u] = true;
  } else {
    if (n - f[u] <= n / 2)
      check[u] = true;
    else {
      auto it = stack_trace.upper_bound(f[u] + n / 2);
      if (it != stack_trace.begin()) {
        --it;
        if (n - *it <= n / 2) check[u] = true;
      }
      if (!check[u]) {
        int mx = tree.get(1, low[u] - 1);
        mx = max(mx, tree.get(high[u] + 1, n));
        if (n - mx - f[u] <= n / 2) check[u] = true;
      }
    }
  }
  for (int v : adj[u])
    if (v != r) calc(v, u);
  stack_trace.erase(f[u]);
  if (f[u] <= n / 2) tree.update(low[u], low[u], f[u]);
}
void solve() {
  cin >> n;
  for (int i = 1; i < n; ++i) {
    int u, v;
    cin >> u >> v;
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  dfs(1, -1);
  tree.init(1, n);
  for (int i = 1; i <= n; ++i)
    if (f[i] <= n / 2) tree.update(low[i], low[i], f[i]);
  calc(1, -1);
  for (int i = 1; i <= n; ++i) cout << check[i] << ' ';
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  const bool multiple_test = false;
  int test = 1;
  if (multiple_test) cin >> test;
  for (int i = 0; i < test; ++i) {
    solve();
  }
}
