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 <bits/stdc++.h>


#define rep2(x,fr,to) for(int (x)=(fr);(x)<(to);(x)++)
#define rep(x,to) for(int (x)=0;(x)<(to);(x)++)
#define repr(x,fr,to) for(int (x)=(fr);(x)>=(to);(x)--)
#define all(c) (c).begin(),(c).end()
#define sz(v) (int)(v).size()

using namespace std;
typedef long long ll; typedef vector<int> VI; typedef pair<int,int> pii;
const int MD = (int)1e9 + 7; typedef vector<ll> VL;
void dbg(){ cerr << "\n"; }  template <class T, class ...T2>
void dbg(const T& fst, const T2&...rst){ cerr << fst << ": "; dbg(rst...); }
template <class T, class T2> void amax(T& a,T2 b){ if(a < b) a = b;}


class LCA{
private:
	vector<vector<int> > to;
	vector<int> depth;
	void dfs(const vector<vector<int> >& edges, int curr, int prev, int cnt){
		depth[curr] = cnt;
		if(prev != -1){
			to[curr].push_back(prev);
			int j = prev;
			rep(k, sz(to[j])){
				j = to[j][k];
				to[curr].push_back(j);
			}
		}
		rep(i,sz(edges[curr])){
			int next = edges[curr][i];
			if(next != prev)
				dfs(edges, next, curr, cnt + 1);
		}
	}
	int climb(int curr, int dist){
		for(int i=0;dist > 0; ++i){
			if(dist % 2 == 1)
				curr = to[curr][i];
			dist /= 2;
		}
		return curr;
	}
public:
	LCA(const vector<vector<int>>& edges, int root){
		int n = sz(edges);
		to.assign(n, vector<int>());
		depth.assign(n,0);
		dfs(edges, root, -1, 0);
	}
	int query(int a, int b){
		pair<int, int> dist(0, 0);
		int diff = depth[a] - depth[b];
		if(diff < 0){
			b = climb(b, -diff);
			dist.second += -diff;
		}else{
			a = climb(a, diff);
			dist.first += diff;
		}
 
		if(a == b) return dist.first + dist.second;
		for(int x = sz(to[a]) -1; x >= 0; --x){
			if(x < sz(to[a]) && to[a][x] != to[b][x]){
				a = to[a][x];
				b = to[b][x];
				dist.first += 1 << x;
				dist.second += 1 << x;
			}
		}
 
		return dist.first + dist.second + 2;
	}
};

int main()
{
	//cin.tie(0); ios_base::sync_with_stdio(false);
	int n;
	cin >>n;
	vector<VI> r(n);
	rep(i, n-1){
		int a, b; cin >>a >>b;
		r[a-1].push_back(b-1);
		r[b-1].push_back(a-1);
	}
	//LCA mlca(r, 0);
	//mlca.query(a-1, b-1);
	//cout <<cnd <<"\n";
	vector<VI> shp(n);
	set<pii> st;
	VI dst(n, -1);
	auto f=[&](auto f,int c, int qq)->void{
		for(auto v: r[c]) if(dst[v] ==-1){
			dst[v] = dst[c] + 1;
			if(dst[v] == 3){
				shp[qq].push_back(v);
				st.insert(pii(min(qq, v), max(qq,v)));
			}
			if(dst[v] <= 2) f(f, v, qq);
		}
	};
	rep(i, n){
		fill(all(dst), -1); dst[i] =0;
		f(f, i, i);
	}
	//rep(i,n){cerr<<i<<":: "; for(auto x :shp[i]) cerr<<x<<" ";dbg();}
	//for(auto x :st) cerr<<x.first<<":"<<x.second<<" "; dbg();
	VI ans(n, -1);
	VI used(n+1, -1); int sml=1;
	for(auto x :st){
		int fs=x.first, sc=x.second;
		//dbg(fs, sc, sml);
		if(ans[fs]==-1){
			rep2(j, sml,n+1 ) if(used[j]==-1){
				ans[fs] = j; sml=j+1; used[j]=1;break;
			}
		}
		
		bool ok=false;
		rep2(i, 1, n){
			if(i*3 -ans[fs] >=n) break;
			if(i*3- ans[fs] >= 1 && used[i*3- ans[fs]]==-1){
				ans[sc] = i*3- ans[fs]; used[i*3- ans[fs]] =1; ok=true;
				break;
			}
		}
		if(!ok) rep2(i, 1, n){
			if(i*3 % ans[fs] ) continue;
			if((i*3)  /ans[fs] >= n) break;
			if((i*3)  /ans[fs] >= 1 && used[(i*3)  /ans[fs]]==-1){
				ans[sc] = (i*3)  /ans[fs]; used[(i*3)  /ans[fs]] =1;
				ok=true; break;
			}
		}
		//for(auto x :ans) cerr<<x<<" "; dbg();
		if(!ok){ puts("-1"); return 0;}
	}
	
	int sj=1;
	rep(i, n){
		if(ans[i]==-1){
			rep2(j, sj, n+1) if(used[j]==-1){
				used[j]=1; ans[i]=j; sj=j; break;
				
			}
		}
	}
	for(auto x :ans) cout<<x<<" ";
	cout <<"\n";
	return 0;
}