#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <cmath>
#include <numeric>
#include <set>
#include <list>
#include <map>
#include <unordered_map>
#include<queue>
#include <stack>
#include<iomanip>
#include <math.h>
#include <functional>

const int INF = 1 << 28;
const long long MOD = 1000000007;
using namespace std;
using Graph = vector<vector<int>>;

template<class T> bool chmin(T &a, T &b) { if (a > b) { a = b; return 1; }return 0; }
template<class T> bool chmax(T &a, T &b) { if (a < b) { a = b; return 1; }return 0; }
template<class T, class U> using P = pair<T, U>;

vector<int> seen(50,-1);
int counter_for_dfs = 0;
void dfs(Graph &G, int v) {
	seen[v] = counter_for_dfs;
	counter_for_dfs++;
	for (auto v_next : G[v]) {
		if (seen[v_next]>=0)continue;

		dfs(G, v_next);
	}
}

void bfs(Graph &G) {
	vector<int> dist(G.size(), -1);
	queue<int> que;
	
	dist[0] = 0;
	que.push(0);
	while (!que.empty()) {
		int v = que.front();
		que.pop();

		for (int g : G[v]) {
			if (dist[g] != -1)continue;
			dist[g] = dist[v] + 1;
			que.push(g);
		}
	}
	for (auto i : dist) {
		cout << i << " ";
	}
}

int counter[200005] = {};
void bfs2(Graph &G,int p,int x) {
	vector<int> dist(G.size() , -1);
	queue<int> que;
	
	dist[p] = 0;
	que.push(p);
	while (!que.empty()) {
		int v = que.front();
		que.pop();

		for (int g : G[v]) {
			if (dist[g] != -1)continue;
			dist[g] = dist[v] + 1;
			que.push(g);
			counter[g] += x;
		}
	}
}
long long int gcd(long long int a, long long int b) {
	long long int c = std::min(a, b);
	a = std::max(a, b);
	b = c;
	while (true) {
		c = a % b;
		a = b;
		b = c;
		if (c == 0)break;
	}
	return a;
}
long long int factorial(int start,int end = 1) {
	if (start == 0)return 1;
	return start == end ? end : start * factorial(start - 1,end);
}
long long int npr(int n, int r) {
	return factorial(n) / factorial(n - r);
}

long long int ncr(int n, int r) {
	return npr(n, r) / factorial(r);
}

static unsigned long _XorShift_x = 123456789;
static unsigned long _XorShift_y = 362436069;
static unsigned long _XorShift_z = 521288629;
static unsigned long _XorShift_w = 88675123;
double XorShift() {
	unsigned long t = (_XorShift_x ^ (_XorShift_x << 11));
	_XorShift_x = _XorShift_y; _XorShift_y = _XorShift_z; _XorShift_z = _XorShift_w;
	_XorShift_w = (_XorShift_w ^ (_XorShift_w >> 19)) ^ (t ^ (t >> 8));
	double res = ((_XorShift_x + 0.5) / 4294967296.0 + _XorShift_w) / 4294967296.0;
	return res;
}

double SAniealing() {
	double x;
	double T;
	double f, fd;
	srand((unsigned int)time(NULL));
	x = (rand() + 0.5) / RAND_MAX;
	T = 100;
	f = x * x * x * x  + x * (x-2) -1;
	double p = 0;
	while (T > 0.01) {
		int i = XorShift() > 0.5 ? 1 : -1;
		double tempx;
		if (T > 0.03) {
			tempx = x + i * XorShift();
		}
		else {
			tempx = x + i * XorShift() * 0.001;
		}
		fd = tempx * tempx * tempx * tempx + tempx * (tempx-2) - 1 ;
		if (fd < f) {
			f = fd;
			x = tempx;
		}
		else {
			p = exp(-(fd - f) / T);
			if (p > 0.5) {
				f = fd;
				x = tempx;
			}
		}
		T *= 0.9999;
		
		//cout << "T=" << T << ":p=" << p <<":f - fd ="<<f - fd<<":x=" << x << endl;
	}

	return x;
}
int main()
{
	int n;
	std::cin >> n;
	int max = 0;
	vector<vector<pair<int, int>>> G(n);
	for (int i = 1; i < n; i++) {
		int a, b;
		std::cin >> a >> b;
		G[a].push_back(make_pair(b,i));
	}
	vector<int> edges(G.size(), 0);
	queue<pair<int, int>> q;
	q.push(make_pair(1, 0));
	while (!q.empty()) {
		pair<int, int> tmppair = q.front();
		int node = tmppair.first;
		int edgefrom = tmppair.second;
		q.pop();
		int num = 1;
		if (node >= n)continue;
		for (auto g : G[node]) {
			edges[g.second] = num == edges[edgefrom] ? ++num : num;
			q.push(g);
			max = max > num ? max : num;
			num++;
		}
	}
	std::cout << max << endl;
	for (int i = 1; i < n; i++) {
		std::cout << edges[i] << endl;
	}
	return 0;
}

Measured memory_bytes: 5120