# 2019-11-24 20:59:47(JST)

import sys



def main():

    n = int(sys.stdin.readline().rstrip())

    m = list(map(int, sys.stdin.read().split()))

    ab = list(zip(m, m)) # 2回以上使えるようにlist化



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

    for a, b in ab:

        graph[a].append(b)

        graph[b].append(a)



    root = 1

    parent = [None] * (n + 1)

    # treeなのでループがないため、parentが定義できる

    checked = []

    to_check = [root]

    # dfs: depth first search では stack

    # bfs: breadth first search では queueを使う

    # 今回は stack



    while to_check:

        x = to_check.pop()

        # stackから要素を取り除き、xにset

        for y in graph[x]: # xから直接つながっているverticesについて

            if y == parent[x]: 

                continue

            # yがxの親でなければ

            parent[y] = x # xを親にして

            to_check.append(y) # 子であるyをto_checkにstackしていく

        checked.append(x) # 探索が終わったらvertexを記録



    color = [None] * (n + 1) # 初期状態ではなにも塗らないのがNG

    # vertexに色を、色1から始めて一つ塗ったら色2, 色3,...と変えて塗っていく

    # その際、色iがngだったらその色iを跳ばして色i+1,色i+2,...と塗っていく(ngは親の色)

    for x in checked: # checkされた順になっている

        ng = color[x]

        c = 1

        for y in graph[x]:

            if y == parent[x]:

                continue

            if c == ng:

                c += 1

            color[y] = c 

            c += 1



    res = []

    for a, b in ab:

        if a == parent[b]:

            res.append(color[b])

        else: # 木なので parent[a] == b

            res.append(color[a])



    print((max(res)))

    print(('\n'.join(map(str, res))))





if __name__ == '__main__':

    main()

import sys

from collections import deque



def main():

    n = int(sys.stdin.readline().rstrip())

    ab = list(map(int, sys.stdin.read().split()))

    ab = list(zip(ab, ab))



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

    for a, b in ab:

        G[a].append(b)

        G[b].append(a)

    

    root = 1

    q = deque()

    q.append(root)

    parent = [None] * (n + 1)

    color = [0] * (n + 1) # color[y]はx = parent[y]としてcolor[x] に依存する。



    while q:

        x = q.popleft()

        c = 1

        for y in G[x]:

            if y == parent[x]:

                continue

            parent[y] = x

            if color[x] == c:

                c += 1

            color[y] = c

            c += 1

            q.append(y)



    res = []

    for a, b in ab:

        if a == parent[b]:

            res.append(color[b])

        else:

            res.append(color[a])

    

    k = max(color)

    print(k)

    print(('\n'.join(map(str, res))))



if __name__ == '__main__':

    main()
# 2019-11-24 20:59:47(JST)
import sys


def main():
    n = int(sys.stdin.readline().rstrip())
    m = list(map(int, sys.stdin.read().split()))
    ab = list(zip(m, m))  # 2回以上使えるようにlist化
    graph = [[] for _ in range(n + 1)]
    for a, b in ab:
        graph[a].append(b)
        graph[b].append(a)
    root = 1
    parent = [None] * (n + 1)
    # treeなのでループがないため、parentが定義できる
    checked = []
    to_check = [root]
    # dfs: depth first search では stack
    # bfs: breadth first search では queueを使う
    # 今回は stack
    while to_check:
        x = to_check.pop()
        # stackから要素を取り除き、xにset
        for y in graph[x]:  # xから直接つながっているverticesについて
            if y == parent[x]:
                continue
            # yがxの親でなければ
            parent[y] = x  # xを親にして
            to_check.append(y)  # 子であるyをto_checkにstackしていく
        checked.append(x)  # 探索が終わったらvertexを記録
    color = [None] * (n + 1)  # 初期状態ではなにも塗らないのがNG
    # vertexに色を、色1から始めて一つ塗ったら色2, 色3,...と変えて塗っていく
    # その際、色iがngだったらその色iを跳ばして色i+1,色i+2,...と塗っていく(ngは親の色)
    for x in checked:  # checkされた順になっている
        ng = color[x]
        c = 1
        for y in graph[x]:
            if y == parent[x]:
                continue
            if c == ng:
                c += 1
            color[y] = c
            c += 1
    res = []
    for a, b in ab:
        if a == parent[b]:
            res.append(color[b])
        else:  # 木なので parent[a] == b
            res.append(color[a])
    print((max(res)))
    print(("\n".join(map(str, res))))


if __name__ == "__main__":
    main()

import sys
from collections import deque


def main():
    n = int(sys.stdin.readline().rstrip())
    ab = list(map(int, sys.stdin.read().split()))
    ab = list(zip(ab, ab))
    G = [[] for _ in range(n + 1)]
    for a, b in ab:
        G[a].append(b)
        G[b].append(a)
    root = 1
    q = deque()
    q.append(root)
    parent = [None] * (n + 1)
    color = [0] * (n + 1)  # color[y]はx = parent[y]としてcolor[x] に依存する。
    while q:
        x = q.popleft()
        c = 1
        for y in G[x]:
            if y == parent[x]:
                continue
            parent[y] = x
            if color[x] == c:
                c += 1
            color[y] = c
            c += 1
            q.append(y)
    res = []
    for a, b in ab:
        if a == parent[b]:
            res.append(color[b])
        else:
            res.append(color[a])
    k = max(color)
    print(k)
    print(("\n".join(map(str, res))))


if __name__ == "__main__":
    main()

-# 2019-11-24 20:59:47(JST) +from collections import deque -    m = list(map(int, sys.stdin.read().split())) -    ab = list(zip(m, m))  # 2回以上使えるようにlist化 -    graph = [[] for _ in range(n + 1)] +    ab = list(map(int, sys.stdin.read().split())) +    ab = list(zip(ab, ab)) +    G = [[] for _ in range(n + 1)] -        graph[a].append(b) -        graph[b].append(a) +        G[a].append(b) +        G[b].append(a) +    q = deque() +    q.append(root) -    # treeなのでループがないため、parentが定義できる -    checked = [] -    to_check = [root] -    # dfs: depth first search では stack -    # bfs: breadth first search では queueを使う -    # 今回は stack -    while to_check: -        x = to_check.pop() -        # stackから要素を取り除き、xにset -        for y in graph[x]:  # xから直接つながっているverticesについて +    color = [0] * (n + 1)  # color[y]はx = parent[y]としてcolor[x] に依存する。 +    while q: +        x = q.popleft() +        c = 1 +        for y in G[x]: -            # yがxの親でなければ -            parent[y] = x  # xを親にして -            to_check.append(y)  # 子であるyをto_checkにstackしていく -        checked.append(x)  # 探索が終わったらvertexを記録 -    color = [None] * (n + 1)  # 初期状態ではなにも塗らないのがNG -    # vertexに色を、色1から始めて一つ塗ったら色2, 色3,...と変えて塗っていく -    # その際、色iがngだったらその色iを跳ばして色i+1,色i+2,...と塗っていく(ngは親の色) -    for x in checked:  # checkされた順になっている -        ng = color[x] -        c = 1 -        for y in graph[x]: -            if y == parent[x]: -                continue -            if c == ng: +            parent[y] = x +            if color[x] == c: +            q.append(y) -        else:  # 木なので parent[a] == b +        else: -    print((max(res))) +    k = max(color) +    print(k)