Problem:
Score : 600 points

Problem Statement

We have a tree with N vertices. The vertices are numbered 1 to N, and the i-th edge connects Vertex a_i and Vertex b_i.

Takahashi loves the number 3. He is seeking a permutation p_1, p_2, \ldots , p_N of integers from 1 to N satisfying the following condition:

For every pair of vertices (i, j), if the distance between Vertex i and Vertex j is 3, the sum or product of p_i and p_j is a multiple of 3.

Here the distance between Vertex i and Vertex j is the number of edges contained in the shortest path from Vertex i to Vertex j.

Help Takahashi by finding a permutation that satisfies the condition.

Constraints

2\leq N\leq 2\times 10^5

1\leq a_i, b_i \leq N

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

If no permutation satisfies the condition, print -1.

Otherwise, print a permutation satisfying the condition, with space in between.
If there are multiple solutions, you can print any of them.

Sample Input 1

5
1 2
1 3
3 4
3 5

Sample Output 1

1 2 5 4 3

The distance between two vertices is 3 for the two pairs (2, 4) and (2, 5).

p_2 + p_4 = 6

p_2\times p_5 = 6

Thus, this permutation satisfies the condition.

Solution in C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Collections.Generic;
class Program
{
	static void Main(string[] args)
	{
		int N = int.Parse(Console.ReadLine());
		int[,]A = new int[N-1,2];
		var list = new List<int>[N];
		int[]P = new int[N];
		var E = new List<int>[N];
		for(var i=0;i<N;i++){
			list[i] = new List<int>();
			E[i] = new List<int>();
		}
		for(var i=0;i<N-1;i++){
			string[] str = Console.ReadLine().Split();
			A[i,0] = int.Parse(str[0]);
			A[i,1] = int.Parse(str[1]);
			if(A[i,1] < A[i,0]){
				int t = A[i,1];
				A[i,1] = A[i,0];
				A[i,0] = t;
			}
			list[A[i,0]-1].Add(A[i,1]);
			P[A[i,1]-1]=A[i,0];
		}
		int[][]D = new int[N][];
		for(var i=0;i<N;i++){
			D[i] = new int[2]{0,i};
		}
		for(var i=0;i<N;i++){
			foreach(var j in list[i]){
				foreach(var k in list[j-1]){
					foreach(var l in list[k-1]){
						E[i].Add(l);
						D[i][0]++;
					}
				}
			}
			if(P[i]>0){
				foreach(var k in list[P[i]-1]){
					if(k-1==i){
						continue;
					}
					foreach(var l in list[k-1]){
						E[i].Add(l);
						D[i][0]++;
					}
				}
				if(P[P[i]-1]>0){
					foreach(var l in list[P[P[i]-1]-1]){
						if(l==P[i]){
							continue;
						}
						E[i].Add(l);
						D[i][0]++;
					}
					if(P[P[P[i]-1]-1]>0){
						E[i].Add(P[P[P[i]-1]-1]);
						D[i][0]++;
					}
				}
			}
		}
		int[]ans = new int[N];
		var pq = new PriorityQueue<int>((x,y)=>D[y][0]-D[x][0]);
		for(var i=0;i<N;i++){
			pq.Enqueue(i);
		}
		int c = 0;
		while(pq.Count > 0){
			int i = pq.Dequeue();
			if(ans[i]==0){
				if(c<=N-3){
					c += 3;
					ans[i] = c;
					for(var j=0;j<E[i].Count;j++){
						D[E[i][j]-1][0]--;
						pq.Enqueue(E[i][j]-1);
					}
				} else {
					break;
				}
			}
		}
		int c2 = -2;
		int c3 = -1;
		bool flag = true;
		while(pq.Count > 0){
			int i = pq.Dequeue();
			if(ans[i]==0){
				if(c2<c3){
					if(c2<=N-3){
						c2 += 3;
						ans[i] = c2;
					} else {
						flag = false;
						break;
					}
				} else {
					if(c3<=N-3){
						c3 += 3;
						ans[i] = c3;
					} else {
						flag = false;
						break;
					}
				}
			}
			for(var j=0;j<E[i].Count;j++){
				if(ans[E[i][j]-1]==0){
					if(ans[i]%3==1){
						if(c3<=N-3){
							c3 += 3;
							ans[E[i][j]-1] = c3;
						} else {
							flag = false;
							break;
						}
					} else if(ans[i]%3==2){
						if(c2<=N-3){
							c2 += 3;
							ans[E[i][j]-1] = c2;
						} else {
							flag = false;
							break;
						}
					}
				}
			}
		}
		if(flag){
			int[]CA = new int[N];
			for(var i=0;i<N;i++){
				if(ans[i]>0){
					CA[ans[i]-1]++;
				}
			}
			int cb = 0;
			for(var i=0;i<N;i++){
				if(ans[i]==0){
					while(CA[cb]>0){
						cb++;
					}
					ans[i] = cb+1;
				}
			}
			Console.Write(ans[0]);
			for(var i=1;i<N;i++){
				Console.Write(" "+ans[i]);
			}
		} else {
			Console.WriteLine("-1");
		}
	}
}

class PriorityQueue<T>
{
    private readonly List<T> heap;
    private readonly Comparison<T> compare;
    private int size;
    public PriorityQueue() : this(Comparer<T>.Default) {} 
    public PriorityQueue(IComparer<T> comparer) : this(16, comparer.Compare) { }
    public PriorityQueue(Comparison<T> comparison) : this(16, comparison) { }
    public PriorityQueue(int capacity, Comparison<T> comparison)
    {
        this.heap = new List<T>(capacity);
        this.compare = comparison;
    }
    public void Enqueue(T item)
    {
        this.heap.Add(item);
        var i = size++;
        while (i > 0)
        {
            var p = (i - 1) >> 1;
            if (compare(this.heap[p], item) <= 0)
                break;
            this.heap[i] = heap[p];
            i = p;
        }
        this.heap[i] = item;

    }
    public T Dequeue()
    {
        var ret = this.heap[0];
        var x = this.heap[--size];
        var i = 0;
        while ((i << 1) + 1 < size)
        {
            var a = (i << 1) + 1;
            var b = (i << 1) + 2;
            if (b < size && compare(heap[b], heap[a]) < 0) a = b;
            if (compare(heap[a], x) >= 0)
                break;
            heap[i] = heap[a];
            i = a;
        }
        heap[i] = x;
        heap.RemoveAt(size);
        return ret;
    }
    public T Peek() { return heap[0]; }
    public int Count { get { return size; } }
    public bool Any() { return size > 0; }
}