import sys

from collections import defaultdict



sr = lambda: sys.stdin.readline().rstrip()

ir = lambda: int(sr())

lr = lambda: list(map(int, sr().split()))



N = ir()

AB = [lr() for _ in range(N-1)]

graph = [[] for _ in range(N+1)] # 1-indexed

for i in range(N-1):

    a, b = AB[i]

    AB[i] = tuple(sorted([a, b]))

    graph[a].append(b)

    graph[b].append(a)



AB_to_C = defaultdict(int)

root = 1

parent = [0] * (N+1)

stack = [root]

while stack:

    cur = stack.pop()

    used = 0

    if parent[cur] != 0:

        used = AB_to_C[tuple(sorted([cur, parent[cur]]))]

    color = 1

    for next in graph[cur]:

        if next == parent[cur]:

            continue

        parent[next] = cur

        while True:

            if color == used:

                color += 1

            else:

                AB_to_C[tuple(sorted([cur, next]))] = color

                color += 1

                break

        stack.append(next)



answer = [0] * (N-1)

for i in range(N-1):

    answer[i] = AB_to_C[AB[i]]



print(max(answer))

print(*answer, sep='\n')

import sys



sr = lambda: sys.stdin.readline().rstrip()

ir = lambda: int(sr())

lr = lambda: list(map(int, sr().split()))



N = ir()

graph = [[] for _ in range(N+1)]

AB = [lr() for _ in range(N-1)]

for a, b in AB:

    graph[a].append(b)

    graph[b].append(a)



root = 1

parent = [0] * (N+1)

order = []

stack = [(root, 0)]

color = [0] * (N+1)

# 頂点と、親方向の辺を対応させる

while stack:

    cur, ng = stack.pop()

    c = 1

    for next in graph[cur]:

        if next == parent[cur]:

            continue

        if c == ng:

            c += 1

        parent[next] = cur

        color[next] = c

        stack.append((next, c))

        c += 1



answer = []

append = answer.append

for a, b in AB:

    if parent[a] == b:

        append(color[a])

    else:

        append(color[b])



print(max(answer))

print(*answer, sep='\n')

# 02

import sys
from collections import defaultdict

sr = lambda: sys.stdin.readline().rstrip()
ir = lambda: int(sr())
lr = lambda: list(map(int, sr().split()))
N = ir()
AB = [lr() for _ in range(N - 1)]
graph = [[] for _ in range(N + 1)]  # 1-indexed
for i in range(N - 1):
    a, b = AB[i]
    AB[i] = tuple(sorted([a, b]))
    graph[a].append(b)
    graph[b].append(a)
AB_to_C = defaultdict(int)
root = 1
parent = [0] * (N + 1)
stack = [root]
while stack:
    cur = stack.pop()
    used = 0
    if parent[cur] != 0:
        used = AB_to_C[tuple(sorted([cur, parent[cur]]))]
    color = 1
    for next in graph[cur]:
        if next == parent[cur]:
            continue
        parent[next] = cur
        while True:
            if color == used:
                color += 1
            else:
                AB_to_C[tuple(sorted([cur, next]))] = color
                color += 1
                break
        stack.append(next)
answer = [0] * (N - 1)
for i in range(N - 1):
    answer[i] = AB_to_C[AB[i]]
print(max(answer))
print(*answer, sep="\n")

import sys

sr = lambda: sys.stdin.readline().rstrip()
ir = lambda: int(sr())
lr = lambda: list(map(int, sr().split()))
N = ir()
graph = [[] for _ in range(N + 1)]
AB = [lr() for _ in range(N - 1)]
for a, b in AB:
    graph[a].append(b)
    graph[b].append(a)
root = 1
parent = [0] * (N + 1)
order = []
stack = [(root, 0)]
color = [0] * (N + 1)
# 頂点と、親方向の辺を対応させる
while stack:
    cur, ng = stack.pop()
    c = 1
    for next in graph[cur]:
        if next == parent[cur]:
            continue
        if c == ng:
            c += 1
        parent[next] = cur
        color[next] = c
        stack.append((next, c))
        c += 1
answer = []
append = answer.append
for a, b in AB:
    if parent[a] == b:
        append(color[a])
    else:
        append(color[b])
print(max(answer))
print(*answer, sep="\n")
# 02

-from collections import defaultdict +graph = [[] for _ in range(N + 1)] -graph = [[] for _ in range(N + 1)]  # 1-indexed -for i in range(N - 1): -    a, b = AB[i] -    AB[i] = tuple(sorted([a, b])) +for a, b in AB: -AB_to_C = defaultdict(int) -stack = [root] +order = [] +stack = [(root, 0)] +color = [0] * (N + 1) +# 頂点と、親方向の辺を対応させる -    cur = stack.pop() -    used = 0 -    if parent[cur] != 0: -        used = AB_to_C[tuple(sorted([cur, parent[cur]]))] -    color = 1 +    cur, ng = stack.pop() +    c = 1 +        if c == ng: +            c += 1 -        while True: -            if color == used: -                color += 1 -            else: -                AB_to_C[tuple(sorted([cur, next]))] = color -                color += 1 -                break -        stack.append(next) -answer = [0] * (N - 1) -for i in range(N - 1): -    answer[i] = AB_to_C[AB[i]] +        color[next] = c +        stack.append((next, c)) +        c += 1 +answer = [] +append = answer.append +for a, b in AB: +    if parent[a] == b: +        append(color[a]) +    else: +        append(color[b]) +# 02