Problem:
Score : 400 points

Problem Statement

Given is a tree G with N vertices.
The vertices are numbered 1 through N, and the i-th edge connects Vertex a_i and Vertex b_i.

Consider painting the edges in G with some number of colors.
We want to paint them so that, for each vertex, the colors of the edges incident to that vertex are all different.

Among the colorings satisfying the condition above, construct one that uses the minimum number of colors.

Constraints

2 \le N \le 10^5

1 \le a_i \lt b_i \le N

All values in input are integers.

The given graph is a tree.

Input

Input is given from Standard Input in the following format:

N
a_1 b_1
a_2 b_2
\vdots
a_{N-1} b_{N-1}

Output

Print N lines.

The first line should contain K, the number of colors used.

The (i+1)-th line (1 \le i \le N-1) should contain c_i, the integer representing the color of the i-th edge, where 1 \le c_i \le K must hold.

If there are multiple colorings with the minimum number of colors that satisfy the condition, printing any of them will be accepted.

Sample Input 1

3
1 2
2 3

Sample Output 1

2
1
2

Sample Input 2

8
1 2
2 3
2 4
2 5
4 7
5 6
6 8

Sample Output 2

4
1
2
3
4
1
1
2

Sample Input 3

6
1 2
1 3
1 4
1 5
1 6

Sample Output 3

5
1
2
3
4
5

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using AtCoderBeginnerContest146.Questions;
using AtCoderBeginnerContest146.Extensions;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace AtCoderBeginnerContest146.Questions
{
    public class QuestionD : AtCoderQuestionBase
    {
        Edge[] edges;
        List<int>[] nodes;
        Dictionary<Edge, int> edgeColors;
        int[] parentColors; // 各ノードの親と接続されている辺の色


        public override IEnumerable<object> Solve(TextReader inputStream)
        {
            var n = inputStream.ReadInt();
            edges = new Edge[n - 1];
            nodes = Enumerable.Range(0, n).Select(_ => new List<int>()).ToArray();
            edgeColors = new Dictionary<Edge, int>();
            parentColors = new int[n];

            for (int i = 0; i < n - 1; i++)
            {
                var ab = inputStream.ReadIntArray().Select(x => x - 1).ToArray();
                var a = ab[0];
                var b = ab[1];
                edges[i] = new Edge(a, b);
                edgeColors.Add(edges[i], 0);
                nodes[a].Add(b);
                nodes[b].Add(a);
            }

            Paint();

            yield return edgeColors.Max(p => p.Value);

            foreach (var edge in edges)
            {
                if (edgeColors.ContainsKey(edge))
                {
                    yield return edgeColors[edge];
                }
                else
                {
                    yield return edgeColors[new Edge(edge.NodeB, edge.NodeA)];
                }
            }
        }

        private void Paint()
        {
            var toDo = new Queue<int>();
            toDo.Enqueue(0);
            var seen = new bool[nodes.Length];
            seen[0] = true;

            while (toDo.Any())
            {
                var currentNode = toDo.Dequeue();
                var parentColor = parentColors[currentNode];
                var color = 1;
                foreach (var nextNode in nodes[currentNode].Where(n => !seen[n]))
                {
                    if (color == parentColor)
                    {
                        color++;
                    }

                    seen[nextNode] = true;
                    edgeColors[new Edge(currentNode, nextNode)] = color;
                    parentColors[nextNode] = color;
                    toDo.Enqueue(nextNode);
                    color++;
                }
            }
        }
    }

    public class Node
    {
        private List<Node> _connectedNodes = new List<Node>();

        public IReadOnlyList<Node> ConnectedNodes => _connectedNodes;

        public void Connect(Node node) => _connectedNodes.Add(node);

        public void Disconnect(Node node) => _connectedNodes.Remove(node);
    }

    public class Edge : IEquatable<Edge>
    {
        public int NodeA { get; }
        public int NodeB { get; }

        public Edge(int nodeA, int nodeB)
        {
            NodeA = nodeA;
            NodeB = nodeB;
        }

        public bool Equals(Edge other) => NodeA == other?.NodeA && NodeB == other?.NodeB;

        public override bool Equals(object obj) => Equals(obj as Edge);

        public override string ToString() => $"NodeA:{NodeA}, NodeB:{NodeB}";

        public override int GetHashCode()
        {
            unchecked
            {
                int hashCode = 105289569;
                hashCode = hashCode * -1521134295 + NodeA.GetHashCode();
                hashCode = hashCode * -1521134295 + NodeB.GetHashCode();
                return hashCode;
            }
        }
    }
}


namespace AtCoderBeginnerContest146
{
    class Program
    {
        static void Main(string[] args)
        {
            IAtCoderQuestion question = new QuestionD();    // 問題に合わせて書き換え
            var answers = question.Solve(Console.In);
            foreach (var answer in answers)
            {
                Console.WriteLine(answer);
            }
        }
    }
}

#region Base Classes

namespace AtCoderBeginnerContest146.Questions
{

    public interface IAtCoderQuestion
    {
        IEnumerable<object> Solve(string input);
        IEnumerable<object> Solve(TextReader inputStream);
    }

    public abstract class AtCoderQuestionBase : IAtCoderQuestion
    {
        public IEnumerable<object> Solve(string input)
        {
            var stream = new MemoryStream(Encoding.Unicode.GetBytes(input));
            var reader = new StreamReader(stream, Encoding.Unicode);

            return Solve(reader);
        }

        public abstract IEnumerable<object> Solve(TextReader inputStream);
    }

}

#endregion

#region Extensions

namespace AtCoderBeginnerContest146.Extensions
{
    internal static class TextReaderExtensions
    {
        internal static int ReadInt(this TextReader reader) => int.Parse(ReadString(reader));
        internal static long ReadLong(this TextReader reader) => long.Parse(ReadString(reader));
        internal static double ReadDouble(this TextReader reader) => double.Parse(ReadString(reader));
        internal static string ReadString(this TextReader reader) => reader.ReadLine();

        internal static int[] ReadIntArray(this TextReader reader, char separator = ' ') => ReadStringArray(reader, separator).Select(int.Parse).ToArray();
        internal static long[] ReadLongArray(this TextReader reader, char separator = ' ') => ReadStringArray(reader, separator).Select(long.Parse).ToArray();
        internal static double[] ReadDoubleArray(this TextReader reader, char separator = ' ') => ReadStringArray(reader, separator).Select(double.Parse).ToArray();
        internal static string[] ReadStringArray(this TextReader reader, char separator = ' ') => reader.ReadLine().Split(separator);
    }
}

#endregion