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 Java8 (OpenJDK 1.8.0) (judge verdict: Accepted)

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;

public class Main {
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] sa = br.readLine().split(" ");
		int n = Integer.parseInt(sa[0]);
		Node2[] arr = new Node2[n];
		for (int i = 0; i < n; i++) {
			Node2 o = new Node2();
			arr[i] = o;
		}
		for (int i = 0; i < n - 1; i++) {
			sa = br.readLine().split(" ");
			int a = Integer.parseInt(sa[0]) - 1;
			int b = Integer.parseInt(sa[1]) - 1;
			arr[a].nexts.add(b);
			arr[b].nexts.add(a);
		}
		br.close();

		Queue<Integer> que = new ArrayDeque<>();
		que.add(0);
		arr[0].grp = 1;
		while (!que.isEmpty()) {
			int cur = que.poll();
			for (int next : arr[cur].nexts) {
				if (arr[next].grp == 0) {
					que.add(next);
					arr[next].grp = 3 - arr[cur].grp;
				}
			}
		}

		int[] rem = new int[4];
		int n2 = n / 3;
		rem[1] = n2;
		rem[2] = n2;
		rem[3] = n2;
		int n3 = n % 3;
		if (n3 > 0) rem[1]++;
		if (n3 > 1) rem[2]++;

		int[] cnt = new int[3];
		for (int i = 0; i < n; i++) {
			cnt[arr[i].grp]++;
		}
		int mincnt = cnt[1];
		int mingrp = 1;
		if (cnt[1] > cnt[2]) {
			mincnt = cnt[2];
			mingrp = 2;
		}

		int[] ans = new int[n];
		if (mincnt <= rem[3]) {
			for (int i = 0; i < n; i++) {
				if (arr[i].grp == mingrp) {
					ans[i] = rem[3] * 3;
					rem[3]--;
				} else {
					for (int j = 1; j <= 3; j++) {
						if (rem[j] > 0) {
							rem[j]--;
							ans[i] = rem[j] * 3 + j;
							break;
						}
					}
				}
			}
		} else {
			for (int i = 0; i < n; i++) {
				for (int j = 1; j <= 3; j++) {
					if (arr[i].grp == j && rem[j] > 0 || j == 3) {
						rem[j]--;
						ans[i] = rem[j] * 3 + j;
						break;
					}
				}
			}
		}

		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < n; i++) {
			sb.append(ans[i]).append(' ');
		}
		sb.deleteCharAt(sb.length() - 1);
		System.out.println(sb.toString());
	}

	static class Node2 {
		int grp;
		Integer target;
		List<Integer> nexts = new ArrayList<>();
	}
}