### BUGGY CODE ###

# 入力、初期化
N = int(input())
tree = [[] for _ in range(N)]
input_list = []
for _ in range(N - 1):
    a, b = map(int, input().split())
    a, b = a - 1, b - 1
    input_list.append([a, b])
    tree[a].append(b)
    tree[b].append(a)

# print(tree)

# visitedにノードの色を格納する
visited_edge = [[0] * N for _ in range(N)]

# print(visited_edge)
# bfsによる色付けを行う
def bfs(now_node):
    queue = [[tree[now_node], 0, now_node]]
    while queue:
        next_nodes, before_color, now_node = queue.pop(0)
        now_color = 1
        for next_node in next_nodes:
            if visited_edge[now_node][next_node] == 0:
                if now_color != before_color:
                    visited_edge[now_node][next_node] = now_color
                    visited_edge[next_node][now_node] = now_color
                else:
                    now_color += 1
                    visited_edge[next_node][now_node] = now_color
                    visited_edge[now_node][next_node] = now_color
                # print("next_node : ",next_node)
                # print("before_color : ",before_color)
                queue.append([tree[next_node], now_color, next_node])
                now_color += 1


# for i in range(N - 1):
#     if len(tree[i]) == 1:
#         start = i
#         break

# for i in tree[0]:
#     visited_edge[0][i] = 1
bfs(0)
# print(visited_edge)
# print(max(visited_edge))
max_val = 0
for row in visited_edge:
    tmp_max = max(row)
    if max_val < tmp_max:
        max_val = tmp_max
print(max_val)
for a, b in input_list:
    print(visited_edge[a][b])

### FIXED CODE ###

from collections import deque
# 入力、初期化
N = int(input())
tree = [[] for _ in range(N)]
input_list = []
for _ in range(N - 1):
    a, b = map(int, input().split())
    a, b = a - 1, b - 1
    input_list.append([a, b])
    tree[a].append(b)
    tree[b].append(a)


# visitedにノードの色を格納する
# visited_edge = [[0] * N for _ in range(N)]
dict = {}
'''
# bfsによる色付けを行う
def bfs(now_node, max_val=0):
    queue = deque([[tree[now_node], -1, now_node]])
    while queue:
        next_nodes, before_color, now_node = queue.pop()
        now_color = 1
        for next_node in next_nodes:
            if visited_edge[now_node][next_node] != 0:
                continue
            if now_color == before_color:
                now_color += 1
            if max_val < now_color:
                max_val = now_color
            visited_edge[next_node][now_node] = now_color
            visited_edge[now_node][next_node] = now_color
            queue.appendleft([tree[next_node], now_color, next_node])
            now_color += 1
    return max_val
'''
def bfs(now_node, max_val=0):
    queue = deque([[tree[now_node], -1, now_node]])
    while queue:
        next_nodes, before_color, now_node = queue.pop()
        now_color = 1
        for next_node in next_nodes:
            key = tuple(sorted([now_node, next_node]))
            if not dict.get(key) is None:
                continue
            if now_color == before_color:
                now_color += 1
            if max_val < now_color:
                max_val = now_color
            dict[key] = now_color
            # visited_edge[now_node][next_node] = now_color
            queue.appendleft([tree[next_node], now_color, next_node])
            now_color += 1
    return max_val

ans = bfs(0)
print(ans)
for a, b in input_list:
    # print(visited_edge[a][b])
    print(dict[tuple(sorted([a,b]))])