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>,
    parents: &mut Vec<Option<usize>>,
) {
    for &to in graph[cur].iter() {
        if to == parent {
            continue;
        }
        color[to] = -1 * color[cur];
        parents[to] = Some(cur);
        dfs(to, cur, graph, color, parents);
    }
}

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;
    let mut parents = vec![vec![None; n]; 3];
    dfs(0, 0, &graph, &mut color, &mut parents[0]);

    for k in 1..3 {
        for v in 0..n {
            if let Some(parent_v) = parents[k - 1][v] {
                parents[k][v] = parents[0][parent_v];
            }
        }
    }

    let mut voted = vec![0; n];
    for i in 0..n {
        if let Some(oo) = parents[2][i] {
            voted[oo] += 1;
        }
    }
    debug!(voted);
    let max_vote1 = *voted.iter().max().unwrap();
    if max_vote1 == 0 {
        // allow everything
        for ans in 1..n + 1 {
            print!("{} ", ans);
        }
        println!("");
        return;
    }
    let mut max_voted1 = (0..n).max_by_key(|&x| voted[x]).unwrap();

    let mut voter = 0;
    for i in 0..n {
        if let Some(oo) = parents[2][i] {
            if oo == max_voted1 {
                voter = i;
                break;
            }
        }
    }

    let mut parents2 = vec![vec![None; n]; 3];

    let mut color2 = vec![0; n];
    dfs(voter, 0, &graph, &mut color2, &mut parents2[0]);

    for k in 1..3 {
        for v in 0..n {
            if let Some(parent_v) = parents2[k - 1][v] {
                parents2[k][v] = parents2[0][parent_v];
            }
        }
    }

    let mut voted = vec![0; n];
    for i in 0..n {
        if let Some(oo) = parents2[2][i] {
            voted[oo] += 1;
        }
    }
    let max_vote2 = *voted.iter().max().unwrap();

    let mut root;
    if max_vote1 >= max_vote2 {
        root = 0;
    } else {
        root = voter;
        parents = parents2;
        max_voted1 = (0..n).max_by_key(|&x| voted[x]).unwrap();
    }

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

    // assign 1
    for case in 0..2 {
        let mut pointers = vec![0; 3];
        let mut assigned = vec![0; n];

        assigned[max_voted1] = 3;
        // free assign
        for i in 0..n {
            if let Some(oo) = parents[2][i] {
                if oo == max_voted1 {
                    assigned[i] = std::usize::MAX;
                }
            }
        }

        let mut ok = true;
        for i in 0..n {
            let ci;
            if case % 2 == 0 {
                ci = if color[i] == 1 { 2 } else { 1 };
            } else {
                ci = if color[i] == -1 { 2 } else { 1 };
            }
            if assigned[i] == std::usize::MAX || assigned[i] == 3 {
                continue;
            }
            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;
            }
        }
        for i in 0..n {
            if assigned[i] == std::usize::MAX {
                if pointers[0] < residuals[0].len() {
                    assigned[i] = residuals[0][pointers[0]];
                    pointers[0] += 1;
                } else if pointers[1] < residuals[1].len() {
                    assigned[i] = residuals[1][pointers[1]];
                    pointers[1] += 1;
                } else {
                    assigned[i] = residuals[2][pointers[2]];
                    pointers[2] += 1;
                }
            }
        }

        // 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()
}