#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <functional>
#include <utility>
#include <tuple>
#include <cctype>
#include <bitset>
#include <complex>
#include <cmath>
#include <array>
#include <numeric>
using namespace std;
#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3fLL
//#define MOD 998244353
#define MOD 1000000007
#define mp make_pair
#define mt make_tuple
#define pb push_back
#define eb emplace_back
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pint;
typedef pair<ll,ll> pll;
typedef tuple<int,int,int> tint;
typedef vector<int> vint;
typedef vector<ll> vll;
typedef vector<ull> vull;
typedef vector<pint> vpint;
typedef vector<tint> vtint;
typedef vector<vint> vvint;
int dx[8]={0,0,-1,1,1,1,-1,-1};
int dy[8]={-1,1,0,0,1,-1,1,-1};
const int SIZE=200050;
//↑templete
int N;
vint node[SIZE];
int ans[SIZE]={};
int color[SIZE]={};
void DFS(int now, int col){
    if(color[now]!=-1)
        return;
    color[now]=col;
    for(int next:node[now]){
        if(color[next]!=-1)
            continue;
        DFS(next, 1-col);
    }
    return;
}
void DFS_2(vint& v, int now, int d){
    if(v[now]!=-1)
        return;
    v[now]=d;
    for(int next:node[now]){
        if(v[next]!=-1)
            continue;
        DFS_2(v, next, d+1);
    }
    return;
}
signed main(){

    int N;
    cin>>N;
    for(int i=0;i<N-1;i++){
        int a, b;
        cin>>a>>b;
        a--, b--;
        node[a].pb(b);
        node[b].pb(a);
    }
    for(int i=0;i<SIZE;i++)
        color[i]=-1;
    
    //直径を調べる
    vint alpha(N, -1), beta(N, -1);
    DFS_2(alpha, 0, 0);
    int x=-1;
    int ax=0;
    for(int i=0;i<N;i++){
        if(ax<alpha[i]){
            ax=alpha[i];
            x=i;
        }
    }
    DFS_2(beta, x, 0);
    bool flag=0;
    for(int i=0;i<N;i++){
        if(beta[i]>=3){
            flag=1;
        }
    }
    if(!flag){
        for(int i=0;i<N;i++){
            cout<<i+1<<(i==N-1?'\n':' ');
        }
        return 0;
    }


    DFS(0, 0);
    //色を数える
    int cnt[2]={};
    for(int i=0;i<N;i++){
        cnt[color[i]]++;
    }
    if(cnt[0]<cnt[1]){  //0のほうが少ないとき、入れ替える
        swap(cnt[1], cnt[0]);
        for(int i=0;i<N;i++)
            color[i]=1-color[i];
    }

    //以降、必ず0のほうが多くなる

    queue<int> que[3];
    for(int i=1;i<=N;i++){
        que[i%3].push(i);
    }

    //0が1の2倍以上多いとき、1をすべて3の倍数にすればあとはどうでも良くなる
    if(cnt[1]<=que[0].size()){
        for(int i=0;i<N;i++){
            if(color[i]==1){
                ans[i]=que[0].front();
                que[0].pop();
            }
            else{
                if(que[1].size()){
                    ans[i]=que[1].front();
                    que[1].pop();
                }
                else if(que[2].size()){
                    ans[i]=que[2].front();
                    que[2].pop();
                }
                else{
                    ans[i]=que[0].front();
                    que[0].pop();
                }
            }
        }
        for(int i=0;i<N;i++){
            cout<<ans[i]<<(i==N-1?'\n':' ');
        }
        return 0;
    }

    // cout<<"color : "<<endl;
    // for(int i=0;i<N;i++)
    //     cout<<color[i]<<" ";
    // cout<<endl;

    for(int i=0;i<N;i++){
        if(que[color[i]+1].size()){
            ans[i]=que[color[i]+1].front();
            que[color[i]+1].pop();
        }
        else if(que[0].size()){
            ans[i]=que[0].front();
            que[0].pop();
        }
        else{
            cout<<-1<<endl;
            return 0;
        }
    }

    for(int i=0;i<N;i++){
        cout<<ans[i]<<(i==N-1?'\n':' ');
    }
	
    return 0;
}


Measured memory_bytes: 20992