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 Rust (1.15.1) (judge verdict: Wrong Answer)

#![allow(unused_imports)]
#![allow(non_snake_case)]
use std::cmp::*;
use std::collections::*;
use std::io::Write;

#[allow(unused_macros)]
macro_rules! debug {
    ($($e:expr),*) => {
        #[cfg(debug_assertions)]
        $({
            let (e, mut err) = (stringify!($e), std::io::stderr());
            writeln!(err, "{} = {:?}", e, $e).unwrap()
        })*
    };
}

fn dfs(cur: usize, parent: usize, graph: &Vec<Vec<usize>>, color: &mut Vec<i32>) {
    for &to in graph[cur].iter() {
        if to == parent {
            continue;
        }
        color[to] = -1 * color[cur];
        dfs(to, cur, graph, color);
    }
}

fn dfs3(cur: usize, parent: usize, graph: &Vec<Vec<usize>>, depth: usize) -> usize {
    let mut ret = 0;
    if depth == 4 {
        return ret;
    }
    for &to in graph[cur].iter() {
        if to == parent {
            continue;
        }
        if depth == 3 {
            ret += 1
        }
        ret += dfs3(to, cur, graph, depth + 1);
    }
    ret
}

fn main() {
    let n = read::<usize>();
    let mut graph = vec![vec![]; n];
    for i in 0..n - 1 {
        let v = read_vec::<usize>();
        let (a, b) = (v[0] - 1, v[1] - 1);
        graph[a].push(b);
        graph[b].push(a);
    }
    let mut color = vec![0; n];
    color[0] = 1;
    dfs(0, 0, &graph, &mut color);

    let mut residuals = vec![vec![]; 3];
    for i in 1..n + 1 {
        residuals[i % 3].push(i);
    }

    let mut holds = vec![0; n];
    for i in 0..n {
        holds[i] = dfs3(0, 0, &graph, 0);
    }
    // debug!(holds);

    // assign 1
    for case in 0..2 {
        let mut pointers = vec![0; 3];
        let mut assigned = vec![0; n];
        let mut ok = true;
        for i in 0..n {
            let ci;
            if case == 0 {
                ci = if color[i] == 1 { 2 } else { 1 };
            } else {
                ci = if color[i] == -1 { 2 } else { 1 };
            }
            if pointers[ci] < residuals[ci].len() {
                assigned[i] = residuals[ci][pointers[ci]];
                pointers[ci] += 1;
            } else if pointers[0] < residuals[0].len() {
                assigned[i] = residuals[0][pointers[0]];
                pointers[0] += 1;
            } else {
                ok = false;
                break;
            }
        }
        // debug!(assigned);
        if ok {
            for ans in assigned {
                print!("{} ", ans);
            }
            println!("");
            return;
        }
    }

    println!("-1");
    return;
}

fn read<T: std::str::FromStr>() -> T {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>()
        .split_whitespace()
        .map(|e| e.parse().ok().unwrap())
        .collect()
}