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: Runtime Error)

#include <bits/stdc++.h>
//#include <boost/multiprecision/cpp_int.hpp>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
#pragma GCC optimize("O3")
#define REP(i,n) for(int i=0;i<n;i++)
#define REPP(i,n) for(int i=1;i<=n;i++)
#define ALL(obj) (obj).begin(), (obj).end()
#define EPS (1e-9)
#define INF (1e17)
#define PI (acos(-1))
//const double PI = acos(-1);
//const double EPS = 1e-15;
//long long INF=(long long)1E17;
#define i_7 (long long)(1e9+7)
//#define i_7 998'244'353
long mod(long a){
    long long c=a%i_7;
    if(c>=0)return c;
    return c+i_7;
}
long long po(long a, long b){
    if(b==0){
        return 1;
    }
    
    long long z = po(a,b/2);
    z = mod(z*z);
    if(b%2!=0){
        z = mod(a*z);
    }
    return z;
}
 
bool prime_(int n){
  if(n==1){
    return false;
  }else if(n==2){
    return true;
  }else{
    for(int i=2;i<=std::sqrt(n);i++){
      if(n%i==0){
        return false;
      }
    }
    return true;
  }
}
 
long long gcd_(long long a, long long b){
  if(a<b){
    std::swap(a,b);
  }
  if(a%b==0){
    return b;
  }else{
    return gcd_(b,a%b);
  }
}
 
long long lcm_(long long x, long long y){
  return (x/gcd_(x,y))*y;
}
 
using namespace std;
//using namespace boost::multiprecision;
//using namespace __gnu_pbds;

vector<int> G[100'010];
vector<int> p(100'010, -1);
vector<int> pp(100'010, -1);
vector<int> ppp(100'010, -1);
vector<int> tier[100'010];
bool visited[100'010];
stack<int> s0, s1, s2;
vector<int> ans;

void dfs(int v, int par = -1, int level = 0){
  
  p[v] = par;
  if(par >= 0){
    pp[v] = p[par];
  }
  if(pp[v] >= 0){
    ppp[v] = p[pp[v]];
  }
  
  bool usable[3] = {};
  if(level < 3){
    for(int sv: tier[3-level]){
      if(ans[sv] < 0)continue;
      if(ans[sv] % 3 == 1){
        usable[1] = false;
      }
      if(ans[sv] % 3 == 2){
        usable[2] = false;
      }
    }
  }else{
    if(ppp[v] >= 0){
      int sv = ppp[v];
      if(ans[sv] >= 0){
        if(ans[sv] % 3 == 1){
          usable[1] = false;
        }
        if(ans[sv] % 3 == 2){
          usable[2] = false;
        }
      }
    }
  }
  
  if(usable[1] && s1.size() >= 1){
    int t = s1.top();
    s1.pop();
    ans[v] = t;
  }
  if(usable[2] && s2.size() >= 1 && ans[v] < 0){
    int t = s2.top();
    s2.pop();
    ans[v] = t;
  }
  if(usable[0] && s0.size() >= 0 && ans[v] < 0){
    int t = s0.top();
    s0.pop();
    ans[v] = t;
  }
  
  if(ans[v] < 0)return;
  
  tier[level].push_back(v);
  
  
  for(int nv: G[v]){
    if(nv == par)continue;
    dfs(nv, v, level + 1);
  }
  
  return;
}
  
  
int main(){
  int n;
  cin>>n;
  int a[n - 1], b[n - 1];
  REP(i, n - 1){
    cin>>a[i]>>b[i];
    a[i]--;b[i]--;
    G[a[i]].push_back(b[i]);
    G[b[i]].push_back(a[i]);
  }
  REPP(i, n){
    if(i % 3 == 0){
      s0.push(i);
    }else if(i % 3 == 1){
      s1.push(i);
    }else{
      s2.push(i);
    }
  }
  ans.resize(n);
  REP(i, n){
    ans[i] = -1;
  }
  
  dfs(0);
  
  REP(i, n){
    if(ans[i] < 0){
      cout<<-1<<endl;
      return 0;
    }
  }
  REP(i, n){
    cout<<ans[i]<<' ';
  }
  cout<<endl;
  
  return 0;
}