import sys

from collections import deque



n = int(eval(input()))

G = [[] for _ in range(n + 1)]

G_order = []

# a<bが保証されている、aを親、bを子とする

for i in range(n - 1):

    a, b = [int(x) - 1 for x in input().split()]

    G[a].append(b)

    G_order.append(b)



# どこでも良いが、ここでは0をrootとする

que = deque([0])



# 各頂点と「親」を結ぶ辺の色

# 頂点0をrootとするのでC[0]=0で確定, 他を調べる

colors = [0] * n



while que:

    # prt = 親

    # 幅優先探索

    prt = que.popleft()

    color = 0



    # cld = 子

    for cld in G[prt]:

        color += 1

        # 「今考えている頂点とその親を結ぶ辺の色」と同じ色は使えない

        if color == colors[prt]:

            color += 1

        colors[cld] = color

        que.append(cld)



# それぞれの頂点とその親を結ぶ辺の色

# print(colors)



# 必要な最小の色数

print((max(colors)))



# 辺の番号順に色を出力

for i in G_order:

    print((colors[i]))

from collections import deque



N = int(eval(input()))

# 有向グラフと見る、G[親] = [子1, 子2, ...]

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

# 子ノードを記録、これで辺の番号を管理

G_order = []

# a<bが保証されている、aを親、bを子とする

for i in range(N - 1):

    a, b = [int(x) - 1 for x in input().split()]

    G[a].append(b)

    G_order.append(b)



# どこでも良いが、ここでは0をrootとする

que = deque([0])



# 各頂点と「親」を結ぶ辺の色

# 頂点0をrootとするのでC[0]=0で確定(「無色」), 他を調べる

colors = [0] * N

# BFS

while que:

    # prt = 親

    # 幅優先探索

    prt = que.popleft()

    color = 0



    # cld = 子

    for cld in G[prt]:

        color += 1

        # 「今考えている頂点とその親を結ぶ辺の色」と同じ色は使えないので次の色にする

        if color == colors[prt]:

            color += 1

        colors[cld] = color

        que.append(cld)



# それぞれの頂点とその親を結ぶ辺の色

# print(colors)



# 必要な最小の色数

print((max(colors)))



# 辺の番号順に色を出力

for i in G_order:

    print((colors[i]))

import sys
from collections import deque

n = int(eval(input()))
G = [[] for _ in range(n + 1)]
G_order = []
# a<bが保証されている、aを親、bを子とする
for i in range(n - 1):
    a, b = [int(x) - 1 for x in input().split()]
    G[a].append(b)
    G_order.append(b)
# どこでも良いが、ここでは0をrootとする
que = deque([0])
# 各頂点と「親」を結ぶ辺の色
# 頂点0をrootとするのでC[0]=0で確定, 他を調べる
colors = [0] * n
while que:
    # prt = 親
    # 幅優先探索
    prt = que.popleft()
    color = 0
    # cld = 子
    for cld in G[prt]:
        color += 1
        # 「今考えている頂点とその親を結ぶ辺の色」と同じ色は使えない
        if color == colors[prt]:
            color += 1
        colors[cld] = color
        que.append(cld)
# それぞれの頂点とその親を結ぶ辺の色
# print(colors)
# 必要な最小の色数
print((max(colors)))
# 辺の番号順に色を出力
for i in G_order:
    print((colors[i]))

from collections import deque

N = int(eval(input()))
# 有向グラフと見る、G[親] = [子1, 子2, ...]
G = [[] for _ in range(N + 1)]
# 子ノードを記録、これで辺の番号を管理
G_order = []
# a<bが保証されている、aを親、bを子とする
for i in range(N - 1):
    a, b = [int(x) - 1 for x in input().split()]
    G[a].append(b)
    G_order.append(b)
# どこでも良いが、ここでは0をrootとする
que = deque([0])
# 各頂点と「親」を結ぶ辺の色
# 頂点0をrootとするのでC[0]=0で確定(「無色」), 他を調べる
colors = [0] * N
# BFS
while que:
    # prt = 親
    # 幅優先探索
    prt = que.popleft()
    color = 0
    # cld = 子
    for cld in G[prt]:
        color += 1
        # 「今考えている頂点とその親を結ぶ辺の色」と同じ色は使えないので次の色にする
        if color == colors[prt]:
            color += 1
        colors[cld] = color
        que.append(cld)
# それぞれの頂点とその親を結ぶ辺の色
# print(colors)
# 必要な最小の色数
print((max(colors)))
# 辺の番号順に色を出力
for i in G_order:
    print((colors[i]))

-import sys -n = int(eval(input())) -G = [[] for _ in range(n + 1)] +N = int(eval(input())) +# 有向グラフと見る、G[親] = [子1, 子2, ...] +G = [[] for _ in range(N + 1)] +# 子ノードを記録、これで辺の番号を管理 -for i in range(n - 1): +for i in range(N - 1): -# 頂点0をrootとするのでC[0]=0で確定, 他を調べる -colors = [0] * n +# 頂点0をrootとするのでC[0]=0で確定(「無色」), 他を調べる +colors = [0] * N +# BFS -        # 「今考えている頂点とその親を結ぶ辺の色」と同じ色は使えない +        # 「今考えている頂点とその親を結ぶ辺の色」と同じ色は使えないので次の色にする