#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <functional>
#include <bitset>

using namespace std;
using lint = long long int;
long long int INF = 1001001001001001LL;
int inf = 1000000007;
long long int MOD = 1000000007LL;
double PI = 3.1415926535897932;

template<typename T1,typename T2>inline void chmin(T1 &a,const T2 &b){if(a>b) a=b;}
template<typename T1,typename T2>inline void chmax(T1 &a,const T2 &b){if(a<b) a=b;}

#define ALL(a) a.begin(),a.end()
#define RALL(a) a.rbegin(),a.rend()

/* do your best */

void dfs(int cur, int c, vector<vector<int>> &g, vector<int> &color) {
  color[cur] = c;
  c ^= 1;
  for (auto nxt : g[cur]) {
    if (color[nxt] != -1) continue;
    dfs(nxt, c, g, color);
  }
}

int main() {

  int n; cin >> n;
  vector<vector<int>> g(n);
  for (int i = 0; i < n - 1; i++) {
    int a, b; cin >> a >> b;
    a--;
    b--;
    g[a].push_back(b);
    g[b].push_back(a);
  }

  vector<int> color(n, -1); // 0 | 1, -1 := 未訪問
  dfs(0, 0, g, color);
  vector<vector<int>> nums(3);
  for (int i = 1; i <= n; i++) {
    nums[i % 3].push_back(i);
  }

  int red = 0;
  int blue = 0;
  for (int i = 0; i < n; i++) {
    if (color[i] == 0) {
      red++;
    } else {
      blue++;
    }
  }

  for (int i = 0; i < n; i++) {
    //cerr << "color[" << i + 1 << "] = " << color[i] << endl;
  }

  for(int i = 0; i < 3; i++) {
    //cerr << "nums[" << i << "].size() = " << nums[i].size() << endl;
  }

  //cerr << "red == " << red << endl;
  //cerr << "blue == " << blue << endl;

  vector<int> ans(n, -1);
  // red に全て 0 を押し付けることができるなら終わり
  if (red <= nums[0].size()) {
    //cerr << "piyo" << endl;
    for (int i = 0; i < n; i++) {
      if (color[i] == 0) {
        ans[i] = nums[0].back();
        nums[0].pop_back();
      } else {
        for (int j = 2; j >= 0; j--) {
          if (nums[j].size()) {
            ans[i] = nums[j].back();
            nums[j].pop_back();
            break;
          }
        }
      }
    }
  } else if (blue <= nums[0].size()) {
    // //cerr << "huga" << endl;
    // blue も同様
    for (int i = 0; i < n; i++) {
      if (color[i] == 1) {
        ans[i] = nums[0].back();
        nums[0].pop_back();
      } else {
        for (int j = 2; j >= 0; j--) {
          if (nums[j].size()) {
            ans[i] = nums[j].back();
            nums[j].pop_back();
            break;
          }
        }
      }
    }
  } else {
    //cerr << "hoge" << endl;
    // red に 1 を，blue に 2 を押し付けて，残りを 0 にする
    for (int i = 0; i < n; i++) {
      if (color[i] == 0) {
        if (nums[1].size()) {
          ans[i] = nums[1].back();
          nums[1].pop_back();
        } else {
          ans[i] = nums[0].back();
          nums[0].pop_back();
        }
      } else {
        if (nums[2].size()) {
          ans[i] = nums[2].back();
          nums[2].pop_back();
        } else {
          ans[i] = nums[0].back();
          nums[0].pop_back();
        }
      }
    }
  }

  for (int i = 0; i < n; i++) {
    cout << ans[i] << " ";
  }
  cout << endl;

  return 0;
}


Measured memory_bytes: 18808