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++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <set>
#include <queue>
#include <cstdio>
#include <algorithm>
using namespace std;
void read(int &a){
	a=0;
	char c=getchar();
	while(c<'0'||c>'9'){
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		a=(a<<1)+(a<<3)+(c^48);
		c=getchar();
	}
}
const int Maxn=200000;
int n;
int f[4][Maxn+5],fa[4][Maxn+5],g[Maxn+5];
int head[Maxn+5],arrive[Maxn<<1|5],nxt[Maxn<<1|5],tot;
int a[Maxn+5];
set<int> num[4][Maxn+5];
void add_edge(int from,int to){
	arrive[++tot]=to;
	nxt[tot]=head[from];
	head[from]=tot;
}
void init_dfs_1(int u,bool flag){
	fa[2][u]=fa[1][fa[1][u]];
	fa[3][u]=fa[2][fa[1][u]];
	if(a[u]==0||a[u]%3!=0){
		f[0][u]=1;
		if(flag){
			num[0][u].insert(u);
		}
	}
	for(int i=head[u];i;i=nxt[i]){
		int v=arrive[i];
		if(fa[1][u]==v){
			continue;
		}
		fa[1][v]=u;
		init_dfs_1(v,flag);
		if(flag&&(a[u]==0||a[u]%3!=0)){
			for(int k=0;k<3;k++){
				for(auto j:num[k][v]){
					num[k+1][u].insert(j);
				}
			}
		}
		f[1][u]+=f[0][v];
		f[2][u]+=f[1][v];
		f[3][u]+=f[2][v];
	}
}
void init_dfs_2(int u,bool flag){
	g[u]=f[3][u];
	if(fa[1][u]){
		g[u]+=f[2][fa[1][u]]-f[1][u];
	}
	if(fa[2][u]){
		g[u]+=f[1][fa[2][u]]-1;
	}
	if(fa[3][u]){
		g[u]+=f[0][fa[3][u]];
	}
	for(int i=head[u];i;i=nxt[i]){
		int v=arrive[i];
		if(fa[1][u]==v){
			continue;
		}
		init_dfs_2(v,flag);
	}
	if(flag&&(a[u]==0||a[u]%3!=0)){
		for(int k=0;k<3;k++){
			if(fa[3-k][u]){
				for(auto j:num[k][fa[3-k][u]]){
					if(3-k==1){
						if(num[1][u].count(j)==0){
							num[1][u].insert(j);
						}
					}
					else if(3-k==1){
						if(j==fa[1][u]){
							num[1][u].insert(j);
						}
					}
					else{
						num[1][u].insert(j);
					}
				}
			}
		}
	}
}
int id[Maxn+5];
int id_tot;
bool used[Maxn+5];
bool cmp(int p,int q){
	return g[p]>g[q];
}
queue<int> q;
int main(){
	read(n);
	int u,v;
	for(int i=1;i<n;i++){
		read(u),read(v);
		add_edge(u,v);
		add_edge(v,u);
	}
	init_dfs_1(1,0);
	init_dfs_2(1,0);
	for(int i=1;i<=n;i++){
		id[i]=i;
	}
	sort(id+1,id+1+n,cmp);
	for(int i=1;i<=n/3;i++){
		a[id[i]]=i*3;
		used[i*3]=1;
	}
	init_dfs_1(1,1);
	init_dfs_2(1,1);
	int last=0;
	int mod_3_1=-2,mod_3_2=-1;
	while(id_tot<n){
		for(int i=last+1;i<=n;i++){
			if(a[i]==0){
				q.push(i);
				last=i;
				id_tot++;
				while(used[id_tot]){
					id_tot++;
				}
				used[id_tot]=1;
				a[i]=id_tot;
				break;
			}
		}
		while(!q.empty()){
			int u=q.front();
			q.pop();
			for(auto v:num[3][u]){
				if(a[v]==0){
					if(a[u]%3==1){
						mod_3_2+=3;
						while(used[mod_3_2]){
							mod_3_2+=3;
						}
						a[v]=mod_3_2;
						used[mod_3_2]=1;
					}
					else{
						mod_3_1+=3;
						while(used[mod_3_1]){
							mod_3_1+=3;
						}
						a[v]=mod_3_1;
						used[mod_3_1]=1;
					}
					q.push(v);
				}
			}
		}
		while(used[id_tot+1]){
			id_tot++;
		}
	}
	for(int i=1;i<=n;i++){
		printf("%d ",a[i]);
	}
	puts("");
	return 0;
}