#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using PII = pair<ll, ll>;
#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()
template<typename T> void chmin(T &a, const T &b) { a = min(a, b); }
template<typename T> void chmax(T &a, const T &b) { a = max(a, b); }
struct FastIO {FastIO() { cin.tie(0); ios::sync_with_stdio(0); }}fastiofastio;
#ifdef DEBUG_ 
#include "../program_contest_library/memo/dump.hpp"
#else
#define dump(...)
#endif
const ll INF = 1LL<<60;

int main(void) {
    ll n;
    cin >> n;
    vector<vector<ll>> g(n);
    REP(i, n-1) {
        ll a, b;
        cin >> a >> b;
        a--, b--;
        g[a].push_back(b);
        g[b].push_back(a);
    }

    ll cnt0 = 0, cnt1 = 0;
    auto dfs0 = [&](auto &&self, ll v, ll p, ll d) -> void {
        if(d%2==0) cnt0++;
        else cnt1++;
        for(auto to: g[v]) if(to!=p) self(self, to, v, d+1);
    };
    dfs0(dfs0, 0, -1, 0);

    vector<ll> v0, v1, v2;
    FOR(i, 1, n+1) {
        if(i%3==0) v0.push_back(i);
        else if(i%3==1) v1.push_back(i);
        else v2.push_back(i);
    }
    ll idx0 = 0, idx1 = 0, idx2 = 0;

    // v1.size() <= max(cnt0, cnt1)
    // v2.size() <= min(cnt0, cnt1)



    vector<ll> ans(n, -1);
    auto dfs = [&](auto &&self, ll v, ll p, ll d) -> void {
        if(cnt0 <= cnt1) {
            if(cnt0 >= v2.size() && cnt1 >= v1.size()) {
                if(d%2 == 0) {
                    if(idx2 < v2.size()) ans[v] = v2[idx2++];
                    else ans[v] = v0[idx0++];
                } else {
                    if(idx1 < v1.size()) ans[v] = v1[idx1++];
                    else ans[v] = v0[idx0++];
                }
            } else if(cnt0 < v2.size()) {
                // cnt0 の位置全てに v0 を置く
                if(d%2 == 0) ans[v] = v0[idx0++];
            } else if(cnt1 < v1.size()) {
                // cnt1 の位置全てに v1 を置く
                if(d%2 == 1) ans[v] = v0[idx0++];
            } else {
                assert(false);
            }
        } else {
            if(cnt1 >= v2.size() && cnt0 >= v1.size()) {
                if(d%2 == 1) {
                    if(idx2 < v2.size()) ans[v] = v2[idx2++];
                    else ans[v] = v0[idx0++];
                } else {
                    if(idx1 < v1.size()) ans[v] = v1[idx1++];
                    else ans[v] = v0[idx0++];
                }
            } else if(cnt1 < v2.size()) {
                if(d%2 == 1) ans[v] = v0[idx0++];
            } else if(cnt0 < v1.size()) {
                if(d%2 == 0) ans[v] = v0[idx0++];
            } else {
                assert(false);
            }
        }
        for(auto to: g[v]) if(to != p) {
            self(self, to, v, d+1);
        }
    };
    dfs(dfs, 0, -1, 0);

    REP(i, n) {
        if(ans[i] == -1) {
            if(idx0 < v0.size()) {
                ans[i] = v0[idx0++];
            } else if(idx1 < v1.size()) {
                ans[i] = v1[idx1++];
            } else if(idx2 < v2.size()) {
                ans[i] = v2[idx2++];
            } else {
                assert(false);
            }
        }
    }
    REP(i, n) cout << ans[i] << (i==n-1 ? '\n' : ' ');

    return 0;
}

Measured memory_bytes: 21740