#include <bits/stdc++.h>
#define all(v) begin(v), end(v)
using namespace std;

const int MX = 1e5;
struct Tree{
	vector<int> adj[MX];
	int depth[MX];
	int parent[MX];
	vector<int> layers[MX];
	int maxDepth;
	
	void addEdge(int u, int v) {
		adj[u].push_back(v);
		adj[v].push_back(u);
	}
	
	void dfs(int u, int p = -1) {
		maxDepth = max(maxDepth, depth[u]);
		parent[u] = p;
		layers[depth[u]].push_back(u);
		for (int v : adj[u]) {
			if (v == p) continue;
			depth[v] = depth[u] + 1;
			dfs(v, u);
		}
	}
	
	vector<int> encode(int root, int n) { //O(n log n)
		//The code will have size exactly 2n - 1
		maxDepth = 0;
		depth[root] = 0;
		dfs(root);
		
		vector<int> label(n);
		vector<int> code;
		vector<vector<int>> childrenCode(n);
		auto cmpNode = [&](int &u, int &v) {
			return childrenCode[u] < childrenCode[v];
		};
		for (int d = maxDepth; d >= 0; d--) {
			sort(layers[d].begin(), layers[d].end(), cmpNode);
			for (int i = 0; i < layers[d].size(); i++) {
				//***************Label Assignment**********************
				int u = layers[d][i];
				if (i == 0) label[u] = 1;
				else {
					int prev = layers[d][i - 1];
					label[u] = label[prev];
					if (childrenCode[u] != childrenCode[prev]) {
						label[u]++;
					}
				}
				//Keep building childrenCode of the parent of u
				if (d != 0) childrenCode[parent[u]].push_back(label[u]);
				//***************Code generation**********************
				code.push_back(0); //group separator
				copy(all(childrenCode[u]), back_inserter(code));
			}
			layers[d].clear();
		}
		return code;
	}
} tree;

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	
	//USAGE
	int n;
	cin >> n;
	for (int i = 0; i < n - 1; i++) {
		int u, v;
		cin >> u >> v;
		u--;
		v--;
		tree.addEdge(u, v);
	}
	int root = 0;
	auto code = tree.encode(root, n);
	for (int x : code) cout << x << " ";
	cout << "\n";
	return 0;
}
