// Generated by 1.1.6 https://github.com/kyuridenamida/atcoder-tools

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

const i64 MOD = 1e9 + 7;
const i64 INF = i64(1e18) + 7;


template <typename T>
bool chmin(T& x, T y){
    if(x > y){
        x = y;
        return true;
    }
    return false;
}

template <typename T>
bool chmax(T& x, T y){
    if(x < y){
        x = y;
        return true;
    }
    return false;
}


void solve(long long n, std::vector<long long> a, std::vector<long long> b){
    vector<vector<int>> edges(n);
    for(int i = 0; i < n - 1; ++i){
        edges[--a[i]].push_back(--b[i]);
        edges[b[i]].push_back(a[i]);
    }
    vector<int> col(n, -1);
    function<void(int)> f = [&](int x){
        for(auto& y : edges[x]){
            if(col[y] == -1){
                col[y] = col[x] ^ 1;
                f(y);
            }
        }
    };
    col[0] = 0;
    f(0);

    if(count(col.begin(), col.end(), 0) < count(col.begin(), col.end(), 1)){
        for(int i = 0; i < n; ++i)
            col[i] = col[i] ^ 1;
    }

    vector<queue<int>> que(3);
    for(int i = 0; i < n; ++i)
        que[(i + 1) % 3].push(i + 1);

    int fl = 0;
    vector<int> ans(n, -1);
    for(int i = 0; i < n; ++i){
        if(col[i]){
            if(que[2].empty()){
                if(que[0].empty()){
                    fl = 2;
                    break;
                }
                ans[i] = que[0].front();
                que[0].pop();
            }
            else{
                ans[i] = que[2].front();
                que[2].pop();
            }
        }
        else{
            if(que[1].empty()){
                if(que[0].empty()){
                    fl = 1;
                    break;
                }
                ans[i] = que[0].front();
                que[0].pop();
            }
            else{
                ans[i] = que[1].front();
                que[1].pop();
            }
        }
    }

    if(fl){
        ans.assign(n, -1);
        for(int i = 0; i < 3; ++i)
            while(!que[i].empty())
                que[i].pop();
        for(int i = 0; i < n; ++i)
            que[bool((i + 1) % 3)].push(i + 1);

        for(int i = 0; i < n; ++i){
            if(col[i]){
                if(fl == 2 && !que[1].empty()){
                    ans[i] = que[1].front();
                    que[1].pop();
                }
                else{
                    assert(!que[0].empty());
                    ans[i] = que[0].front();
                    que[0].pop();
                }
            }
            else{
                if(fl == 1 && !que[1].empty()){
                    assert(!que[1].empty());
                    ans[i] = que[1].front();
                    que[1].pop();
                }
                else{
                    assert(!que[0].empty());
                    ans[i] = que[0].front();
                    que[0].pop();
                }
            }
        }
    }
    for(int i = 0; i < n; ++i)
        cout << ans[i] << " \n"[i == n - 1];

}


signed main(){
    long long N;
    scanf("%lld",&N);
    std::vector<long long> a(N-1);
    std::vector<long long> b(N-1);
    for(int i = 0 ; i < N-1 ; i++){
        scanf("%lld",&a[i]);
        scanf("%lld",&b[i]);
    }
    solve(N, std::move(a), std::move(b));

    return 0;
}


Measured memory_bytes: 23296