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.



Sample input:
5
1 2
1 3
3 4
3 5


Sample output:
1 2 5 4 3

Submission status: Runtime Error

Solution code:
import queue

N = int(input())

# Adjacency matrix
e = [[] for i in range(N+1)]
for i in range(N-1):
    a, b = map(int, input().split())
    e[a].append(b)
    e[b].append(a)

even_v = []
odd_v = []

is_reached = [False] * (N+1)
q = queue.Queue()
# [start vertex, total distance]
q.put([1, 0])

# BFS
while not q.empty():
    v, d = q.get()
    if is_reached[v]:
        continue
    is_reached[v] = True
    
    if d%2 == 0:
        even_v.append(v)
    else:
        odd_v.append(v)

    for tv in e[v]:
        q.put([tv, d+1])

# Remainder lists [1..N] mod 3
r1 = list(range(1, N+1, 3))
r2 = list(range(2, N+1, 3))
r3 = list(range(3, N+1, 3))

p = [0] * N
if len(even_v) <= len(r3):
    # Embed r3 in even_v
    for v in even_v:
        p[v-1] = r3.pop()
elif len(odd_v) <= len(r3):
    # Embed r3 in odd_v
    for v in odd_v:
        p[v-1] = r3.pop()
else:
    # Embed r1 in even_v
    for v in even_v:
        if not r1:
            break
        p[v-1] = r1.pop()
    # Embed r2 in odd_v
    for v in odd_v:
        if not r2:
            break
        p[v-1] = r2.pop()

# Collect unused vertexes
rv = []
rv.extend(r1)
rv.extend(r2)
rv.extend(r3)
for i in enumerate(p):
    if p[i] == 0:
        p[i] = rv.pop()

ans = ' '.join(list(map(str, p)))
print(ans)

Submission status: Runtime Error

Solution code:
import sys

N = int(input())
ab = [list(map(int,input().split())) for _ in range(N-1)]

#%%
# 1-indexed
adj_list = [[] for _ in range(N+1)]

for a,b in ab:
    adj_list[a].append(b)
    adj_list[b].append(a)

# DFSで各頂点を1，2に割り当てる．

group = [1]*(N+1)
group[0] = -1

def dfs(v,par,grp):
    # 頂点vからpar以外の子へ遷移
    # grpで頂点vのグループを持つ
    
    nxt_grp = grp^3
    for child in adj_list[v]:
        if child==par:
            continue
        group[child] = nxt_grp
        dfs(child,v,nxt_grp)
    
    return 

dfs(1,-1,1)

ans = [0]*(N+1)
used = [False]*(N+1)


group_num = [0]*2
for g in group[1:]:
    group_num[g-1] += 1
    
print(*ans[1:])
sys.exit()

if min(group_num) <= N//3:
    if min(group_num) == group_num[0]:
        minidx = 1
    else:
        minidx = 2
    
    idx = 3
    idx_n = 1
    for i,g in enumerate(group):
        if i==0:continue
        if g==minidx:
            ans[i] = idx            
            used[idx] = True
            idx += 3

    for i,g in enumerate(group):
        if i==0:continue
        if ans[i]!=0:continue
        while used[idx_n]:
            idx_n += 1
        ans[i] = idx_n
        used[idx_n] = True
        idx_n += 1
    
    print(*ans[1:])

else:
    idx_1 = 1
    idx_2 = 2
    for i,g in enumerate(group):
        if i==0:continue
        if g==1:
            if idx_1>N:continue
            ans[i] = idx_1
            used[idx_1] = True
            idx_1 += 3
        else:
            if idx_2>N:continue
            ans[i] = idx_2
            used[idx_2] = True
            idx_2 += 3

    idx = 3
    for i in range(1,N+1):
        if ans[i]==0:
            while used[idx]:
                idx += 3
            ans[i] = idx
            used[idx] = True

    print(*ans[1:])

Submission status: Runtime Error

Solution code:
N = int(input())
ab = [list(map(int,input().split())) for _ in range(N-1)]

#%%
# 1-indexed
adj_list = [[] for _ in range(N+1)]

for a,b in ab:
    adj_list[a].append(b)
    adj_list[b].append(a)

# DFSで各頂点を1，2に割り当てる．

group = [1]*(N+1)
group[0] = -1

def dfs(v,par,grp):
    # 頂点vからpar以外の子へ遷移
    # grpで頂点vのグループを持つ
    
    nxt_grp = grp^3
    for child in adj_list[v]:
        if child==par:
            continue
        group[child] = nxt_grp
        dfs(child,v,nxt_grp)
    
    return 

dfs(1,-1,1)

ans = [0]*(N+1)
used = [False]*(N+1)


group_num = [0]*2
for g in group[1:]:
    group_num[g-1] += 1
    



if min(group_num) <= N//3:
    if min(group_num) == group_num[0]:
        minidx = 1
    else:
        minidx = 2
    
    idx = 3
    idx_n = 1
    for i,g in enumerate(group):
        if i==0:continue
        if g==minidx:
            ans[i] = idx            
            used[idx] = True
            idx += 3

    for i,g in enumerate(group):
        if i==0:continue
        if ans[i]!=0:continue
        while used[idx_n]:
            idx_n += 1
        ans[i] = idx_n
        used[idx_n] = True
        idx_n += 1
    
    print(*ans[1:])

else:
    idx_1 = 1
    idx_2 = 2
    for i,g in enumerate(group):
        if i==0:continue
        if g==1:
            if idx_1>N:continue
            ans[i] = idx_1
            used[idx_1] = True
            idx_1 += 3
        else:
            if idx_2>N:continue
            ans[i] = idx_2
            used[idx_2] = True
            idx_2 += 3

    idx = 3
    for i in range(1,N+1):
        if ans[i]==0:
            while used[idx]:
                idx += 3
            ans[i] = idx
            used[idx] = True

    print(*ans[1:])

Submission status: Runtime Error

Solution code:
N = int(input())
ab = [list(map(int,input().split())) for _ in range(N-1)]

#%%
# 1-indexed
adj_list = [[] for _ in range(N+1)]

for a,b in ab:
    adj_list[a].append(b)
    adj_list[b].append(a)

# DFSで各頂点を1，2に割り当てる．

group = [1]*(N+1)
group[0] = -1

def dfs(v,par,grp):
    # 頂点vからpar以外の子へ遷移
    # grpで頂点vのグループを持つ
    
    nxt_grp = grp^3
    for child in adj_list[v]:
        if child==par:
            continue
        group[child] = nxt_grp
        dfs(child,v,nxt_grp)
    
    return 

dfs(1,-1,1)

ans = [0]*(N+1)
used = [False]*(N+1)


group_num = [0]*2
for g in group[1:]:
    group_num[g-1] += 1
    



if min(group_num) <= N//3:
    if min(group_num) == group_num[0]:
        minidx = 1
    else:
        minidx = 2
    
    idx = 3
    idx_n = 1
    for i,g in enumerate(group):
        if i==0:continue
        if g==minidx:
            ans[i] = idx            
            used[idx] = True
            idx += 3

    for i,g in enumerate(group):
        if i==0:continue
        if ans[i]!=0:continue
        while used[idx_n]:
            idx_n += 1
        ans[i] = idx_n
        used[idx_n] = True
        idx_n += 1
    
    print(*ans[1:])

else:
    idx_1 = 1
    idx_2 = 2
    for i,g in enumerate(group):
        if i==0:continue
        if g==1:
            if idx_1>N:continue
            ans[i] = idx_1
            used[idx_1] = True
            idx_1 += 3
        else:
            if idx_2>N:continue
            ans[i] = idx_2
            used[idx_2] = True
            idx_2 += 3

    idx = 3
    for i in range(1,N+1):
        if ans[i]==0:
            while used[idx]:
                idx += 3
            ans[i] = idx

    print(*ans[1:])

Submission status: Runtime Error

Solution code:
import sys
sys.setrecursionlimit(1000000000000)
N = int(input())
AB = [list(map(int, input().split())) for _ in range(N - 1)]


class Tree:
    def __init__(self, v):
        self.v = v
        self.neighbors = []

    def set_rank(self, rank, parent):
        self.rank = rank
        for neighbor in self.neighbors:
            if neighbor is parent:
                continue
            neighbor.set_rank(rank=rank + 1, parent=self)


trees = {i: Tree(i) for i in range(1, N + 1)}

for a, b in AB:
    trees[a].neighbors.append(trees[b])
    trees[b].neighbors.append(trees[a])
try:
    trees[1].set_rank(1, None)
except:
    print(-1)
    exit()

group0 = [node.v for node in trees.values() if node.rank % 2 == 0]
group1 = [node.v for node in trees.values() if node.rank % 2]
x = [set(), set(), set()]
for i in range(1, N + 1):
    x[i % 3].add(i)
if len(group1) < len(group0):
    group1, group0 = group0, group1
result = {}
if len(group0) <= len(x[0]):
    while group0 and x[0]:
        result[group0.pop()] = x[0].pop()
    y = x[0] | x[1] | x[2]
    while group1 and y:
        result[group1.pop()] = y.pop()
else:
    while x[2] and group0:
        result[group0.pop()] = x[2].pop()
    while x[1] and group1:
        result[group1.pop()] = x[1].pop()
    while group0 and x[0]:
        result[group0.pop()] = x[0].pop()
    while group1 and x[0]:
        result[group1.pop()] = x[0].pop()
    if group0 or group1:
        print(-1)
        exit()

print(' '.join(str(result[i]) for i in range(1, N + 1)))

Submission status: Runtime Error

Solution code:
N = int(input())
ab = [list(map(int,input().split())) for _ in range(N-1)]

#%%
# 1-indexed
adj_list = [[] for _ in range(N+1)]

for a,b in ab:
    adj_list[a].append(b)
    adj_list[b].append(a)

# DFSで各頂点を1，2に割り当てる．

group = [1]*(N+1)
group[0] = -1

def dfs(v,par,grp):
    # 頂点vからpar以外の子へ遷移
    # grpで頂点vのグループを持つ
    
    nxt_grp = grp^3
    for child in adj_list[v]:
        if child==par:
            continue
        group[child] = nxt_grp
        dfs(child,v,nxt_grp)
    
    return 

dfs(1,-1,1)

ans = [0]*(N+1)
used = [False]*(N+1)


group_num = [0]*2
for g in group[1:]:
    group_num[g-1] += 1
    



if min(group_num) <= N//3:
    if min(group_num) == group_num[0]:
        minidx = 1
    else:
        minidx = 2
    
    idx = 3
    idx_n = 1
    for i,g in enumerate(group):
        if i==0:continue
        if g==minidx:
            ans[i] = idx            
            used[idx] = True
            idx += 3

    for i,g in enumerate(group):
        if i==0:continue
        if ans[i]!=0:continue
        while used[idx_n]:
            idx_n += 1
        ans[i] = idx_n
        used[idx_n] = True
        idx_n += 1
    
    print(*ans[1:])

else:
    idx_1 = 1
    idx_2 = 2
    for i,g in enumerate(group):
        if i==0:continue
        if g==1:
            while used[idx_1]:
                idx_1 += 3                
                if idx_1>N:
                    idx_1 = 3
                
            ans[i] = idx_1
            used[idx_1] = True
        else:
            while used[idx_2]:
                idx_2 += 3
                if idx_2>N:
                    idx_2 = 3
            ans[i] = idx_2
            used[idx_2] = True
            
    print(*ans[1:])

Submission status: Runtime Error

Solution code:
N = int(input())
ab = [list(map(int,input().split())) for _ in range(N-1)]

#%%
# 1-indexed
adj_list = [[] for _ in range(N+1)]

for a,b in ab:
    adj_list[a].append(b)
    adj_list[b].append(a)

# DFSで各頂点を1，2に割り当てる．

group = [1]*(N+1)
group[0] = -1

def dfs(v,par,grp):
    # 頂点vからpar以外の子へ遷移
    # grpで頂点vのグループを持つ
    
    nxt_grp = grp^3
    for child in adj_list[v]:
        if child==par:
            continue
        group[child] = nxt_grp
        dfs(child,v,nxt_grp)
    
    return 

dfs(1,-1,1)

ans = [0]*(N+1)
used = [False]*(N+1)


group_num = [0]*2
for g in group[1:]:
    group_num[g-1] += 1
    



if min(group_num) <= N//3:
    # if min(group_num) == group_num[0]:
    #     minidx = 1
    # else:
    #     minidx = 2
    
    # idx = 3
    # idx_n = 1
    # for i,g in group:
    #     if i==0:continue
    #     if g==minidx:
    #         ans[i] = idx            
    #         used[idx] = True
    #         idx += 3

    # for i,g in group:
    #     if i==0:continue
    #     if ans[i]!=0:continue
    #     while used[idx_n]:
    #         idx_n += 1
    #     ans[i] = idx_n
    #     used[idx_n] = True
    #     idx_n += 1
    
    print(*ans[1:])

else:
    idx_1 = 1
    idx_2 = 2
    for i,g in enumerate(group):
        if i==0:continue
        if g==1:
            while used[idx_1]:
                idx_1 += 3                
                if idx_1>N:
                    idx_1 = 3
                
            ans[i] = idx_1
            used[idx_1] = True
        else:
            while used[idx_2]:
                idx_2 += 3
                if idx_2>N:
                    idx_2 = 3
            ans[i] = idx_2
            used[idx_2] = True
            
    print(*ans[1:])

Submission status: Runtime Error

Solution code:
N = int(input())
ab = [list(map(int,input().split())) for _ in range(N-1)]

#%%
# 1-indexed
adj_list = [[] for _ in range(N+1)]

for a,b in ab:
    adj_list[a].append(b)
    adj_list[b].append(a)

# DFSで各頂点を1，2に割り当てる．

group = [1]*(N+1)
group[0] = -1

def dfs(v,par,grp):
    # 頂点vからpar以外の子へ遷移
    # grpで頂点vの子のグループを持つ
    
    nxt_grp = grp^3
    for child in adj_list[v]:
        if child==par:
            continue
        group[child] = nxt_grp
        dfs(child,v,nxt_grp)
    
    return 

dfs(1,-1,1)

ans = [0]*(N+1)
used = [False]*(N+1)


group_num = [0]*2
for g in group[1:]:
    group_num[g-1] += 1
    



if min(group_num) <= N//3:
    if min(group_num) == group_num[0]:
        minidx = 1
    else:
        minidx = 2
    
    idx = 3
    idx_n = 1
    for i,g in group:
        if i==0:continue
        if g==minidx:
            ans[i] = idx            
            used[idx] = True
            idx += 3

    for i,g in group:
        if i==0:continue
        if ans[i]!=0:continue
        while used[idx_n]:
            idx_n += 1
        ans[i] = idx_n
        used[idx_n] = True
        idx_n += 1
    
    print(*ans[1:])

else:
    # idx_1 = 1
    # idx_2 = 2
    # for i,g in enumerate(group):
    #     if i==0:continue
    #     if g==1:
    #         while used[idx_1]:
    #             idx_1 += 3                
    #             if idx_1>N:
    #                 idx_1 = 3
                
    #         ans[i] = idx_1
    #         used[idx_1] = True
    #     else:
    #         while used[idx_2]:
    #             idx_2 += 3
    #             if idx_2>N:
    #                 idx_2 = 3
    #         ans[i] = idx_2
    #         used[idx_2] = True
            
    print(*ans[1:])

Submission status: Runtime Error

Solution code:
N = int(input())
ab = [list(map(int,input().split())) for _ in range(N-1)]

#%%
# 1-indexed
adj_list = [[] for _ in range(N+1)]

for a,b in ab:
    adj_list[a].append(b)
    adj_list[b].append(a)

# DFSで各頂点を1，2に割り当てる．

group = [1]*(N+1)
group[0] = -1

def dfs(v,par,grp):
    # 頂点vからpar以外の子へ遷移
    # grpで頂点vの子のグループを持つ
    
    nxt_grp = grp^3
    for child in adj_list[v]:
        if child==par:
            continue
        group[child] = nxt_grp
        dfs(child,v,nxt_grp)
    
    return 

dfs(1,-1,1)

ans = [0]*(N+1)
used = [False]*(N+1)


group_num = [0]*2
for g in group[1:]:
    group_num[g-1] += 1
    



if min(group_num) <= N//3:
    if min(group_num) == group_num[0]:
        minidx = 1
    else:
        minidx = 2
    
    idx = 3
    idx_n = 1
    for i,g in group:
        if i==0:continue
        if g==minidx:
            ans[i] = idx            
            used[idx] = True
            idx += 3

    for i,g in group:
        if i==0:continue
        if ans[i]!=0:continue
        while used[idx_n]:
            idx_n += 1
        ans[i] = idx_n
        used[idx_n] = True
        idx_n += 1
    
    print(*ans[1:])

else:
    idx_1 = 1
    idx_2 = 2
    for i,g in enumerate(group):
        if i==0:continue
        if g==1:
            while used[idx_1]:
                idx_1 += 3                
                if idx_1>N:
                    idx_1 = 3
                
            ans[i] = idx_1
            used[idx_1] = True
        else:
            while used[idx_2]:
                idx_2 += 3
                if idx_2>N:
                    idx_2 = 3
            ans[i] = idx_2
            used[idx_2] = True
            
    print(*ans[1:])

Submission status: Runtime Error

Solution code:
N = int(input())
AB = [list(map(int, input().split())) for _ in range(N - 1)]


class Tree:
    def __init__(self, v):
        self.v = v
        self.neighbors = []

    def set_rank(self, rank, parent):
        self.rank = rank
        for neighbor in self.neighbors:
            if neighbor is parent:
                continue
            neighbor.set_rank(rank=rank + 1, parent=self)


trees = {i: Tree(i) for i in range(1, N + 1)}

for a, b in AB:
    trees[a].neighbors.append(trees[b])
    trees[b].neighbors.append(trees[a])
trees[2].set_rank(2, None)

group0 = [node.v for node in trees.values() if node.rank % 2 == 0]
group1 = [node.v for node in trees.values() if node.rank % 2]
x = [set(), set(), set()]
for i in range(1, N + 1):
    x[i % 3].add(i)
if len(group1) < len(group0):
    group1, group0 = group0, group1
result = {}
if len(group0) <= len(x[0]):
    while group0 and x[0]:
        result[group0.pop()] = x[0].pop()
    y = x[0] | x[1] | x[2]
    while group1 and y:
        result[group1.pop()] = y.pop()
else:
    while x[2] and group0:
        result[group0.pop()] = x[2].pop()
    while x[1] and group1:
        result[group1.pop()] = x[1].pop()
    while group0 and x[0]:
        result[group0.pop()] = x[0].pop()
    while group1 and x[0]:
        result[group1.pop()] = x[0].pop()
    if group0 or group1:
        print(-1)
        exit()

print(' '.join(str(result[i]) for i in range(1, N + 1)))

Submission status: Runtime Error

Solution code:
N = int(input())
AB = [list(map(int, input().split())) for _ in range(N - 1)]


class Tree:
    def __init__(self, v):
        self.v = v
        self.neighbors = []

    def set_rank(self, rank, parent):
        self.rank = rank
        for neighbor in self.neighbors:
            if neighbor is parent:
                continue
            neighbor.set_rank(rank=rank + 1, parent=self)


trees = {i: Tree(i) for i in range(1, N + 1)}

for a, b in AB:
    trees[a].neighbors.append(trees[b])
    trees[b].neighbors.append(trees[a])
trees[1].set_rank(1, None)

exit()
group0 = [node.v for node in trees.values() if node.rank % 2 == 0]
group1 = [node.v for node in trees.values() if node.rank % 2]
x = [set(), set(), set()]
for i in range(1, N + 1):
    x[i % 3].add(i)
if len(group1) < len(group0):
    group1, group0 = group0, group1
result = {}
if len(group0) <= len(x[0]):
    while group0 and x[0]:
        result[group0.pop()] = x[0].pop()
    y = x[0] | x[1] | x[2]
    while group1 and y:
        result[group1.pop()] = y.pop()
else:
    while x[2] and group0:
        result[group0.pop()] = x[2].pop()
    while x[1] and group1:
        result[group1.pop()] = x[1].pop()
    while group0 and x[0]:
        result[group0.pop()] = x[0].pop()
    while group1 and x[0]:
        result[group1.pop()] = x[0].pop()
    if group0 or group1:
        print(-1)
        exit()

print(' '.join(str(result[i]) for i in range(1, N + 1)))

Submission status: Runtime Error

Solution code:
N = int(input())
AB = [list(map(int, input().split())) for _ in range(N - 1)]


class Tree:
    def __init__(self, v):
        self.v = v
        self.neighbors = []

    def set_rank(self, rank, parent):
        self.rank = rank
        for neighbor in self.neighbors:
            if neighbor is parent:
                continue
            neighbor.set_rank(rank=rank + 1, parent=self)


trees = {i: Tree(i) for i in range(1, N + 1)}

for a, b in AB:
    trees[a].neighbors.append(trees[b])
    trees[b].neighbors.append(trees[a])
trees[1].set_rank(1, None)

group0 = [node.v for node in trees.values() if node.rank % 2 == 0]
group1 = [node.v for node in trees.values() if node.rank % 2]
x = [set(), set(), set()]
for i in range(1, N + 1):
    x[i % 3].add(i)
if len(group1) < len(group0):
    group1, group0 = group0, group1
exit()
result = {}
if len(group0) <= len(x[0]):
    while group0 and x[0]:
        result[group0.pop()] = x[0].pop()
    y = x[0] | x[1] | x[2]
    while group1 and y:
        result[group1.pop()] = y.pop()
else:
    while x[2] and group0:
        result[group0.pop()] = x[2].pop()
    while x[1] and group1:
        result[group1.pop()] = x[1].pop()
    while group0 and x[0]:
        result[group0.pop()] = x[0].pop()
    while group1 and x[0]:
        result[group1.pop()] = x[0].pop()
    if group0 or group1:
        print(-1)
        exit()

print(' '.join(str(result[i]) for i in range(1, N + 1)))

Submission status: Runtime Error

Solution code:
N = int(input())
AB = [list(map(int, input().split())) for _ in range(N-1)]

class Tree:
    def __init__(self, v):
        self.v = v
        self.neighbors = []

    def set_rank(self,rank,parent):
        self.rank = rank
        for neighbor in self.neighbors:
            if neighbor is parent:
                continue
            neighbor.set_rank(rank=rank+1,parent=self)



trees = {i:Tree(i) for i in range(1,N+1)}

for a,b in AB:
    trees[a].neighbors.append(trees[b])
    trees[b].neighbors.append(trees[a])
trees[1].set_rank(1,None)

group0 = [node.v for node in  trees.values() if node.rank %2 ==0]
group1 = [node.v for node in  trees.values() if node.rank %2]
x = [set(),set(),set()]
for i in range(1,N+1):
    x[i%3].add(i)
if len(group1) < len(group0):
    group1,group0 = group0,group1

result = {}
if len(group0) <= len(x[0]):
    while group0 and x[0]:
        result[group0.pop()]= x[0].pop()
    y = x[0]|x[1]|x[2]
    while group1 and y:
        result[group1.pop()] = y.pop()
    if y:
        import time
        time.sleep(10)
else:
    while x[2] and group0:
        result[group0.pop()] = x[2].pop()
    while x[1] and group1:
        result[group1.pop()] = x[1].pop()
    while group0 and x[0]:
        result[group0.pop()] = x[0].pop()
    while group1 and x[0]:
        result[group1.pop()] = x[0].pop()
    if group0 or group1:
        print(-1)
        exit()


print(' '.join(str(result[i]) for i in range(1,N+1)))

Submission status: Runtime Error

Solution code:
from collections import defaultdict

N = int(input())
AB = [list(map(int, input().split())) for _ in range(N-1)]

d = defaultdict(list)
class Tree:
    def __init__(self, v):
        self.v = v
        self.neighbors = []

    def set_rank(self,rank,parent):
        self.rank = rank
        for neighbor in self.neighbors:
            if neighbor == parent:
                continue
            neighbor.set_rank(rank=rank+1,parent=self)



trees = {i:Tree(i) for i in range(1,N+1)}

for a,b in AB:
    trees[a].neighbors.append(trees[b])
    trees[b].neighbors.append(trees[a])
trees[1].set_rank(1,None)

group0 = [node.v for node in  trees.values() if node.rank %2 ==0]
group1 = [node.v for node in  trees.values() if node.rank %2]
x = [set(),set(),set()]
for i in range(1,N+1):
    x[i%3].add(i)
if len(group1) < len(group0):
    group1,group0 = group0,group1

result = {}
if len(group0) <= len(x[0]):
    while group0 and x[0]:
        result[group0.pop()]= x[0].pop()
    y = x[0]|x[1]|x[2]
    while group1 and y:
        result[group1.pop()] = y.pop()
    if y:
        import time
        time.sleep(10)
else:
    while x[2] and group0:
        result[group0.pop()] = x[2].pop()
    while x[1] and group1:
        result[group1.pop()] = x[1].pop()
    while group0 and x[0]:
        result[group0.pop()] = x[0].pop()
    while group1 and x[0]:
        result[group1.pop()] = x[0].pop()
    if group0 or group1:
        print(-1)
        exit()


print(' '.join(str(result[i]) for i in range(1,N+1)))

Submission status: Runtime Error

Solution code:
from collections import defaultdict

N = int(input())
AB = [list(map(int, input().split())) for _ in range(N-1)]

d = defaultdict(list)
class Tree:
    def __init__(self, v):
        self.v = v
        self.neighbors = []

    def set_rank(self,rank,parent):
        self.rank = rank
        for neighbor in self.neighbors:
            if neighbor == parent:
                continue
            neighbor.set_rank(rank=rank+1,parent=self)



trees = {i:Tree(i) for i in range(1,N+1)}

for a,b in AB:
    trees[a].neighbors.append(trees[b])
    trees[b].neighbors.append(trees[a])
trees[1].set_rank(1,None)

group0 = [node.v for node in  trees.values() if node.rank %2 ==0]
group1 = [node.v for node in  trees.values() if node.rank %2]
x = [set(),set(),set()]
for i in range(1,N+1):
    x[i%3].add(i)
if len(group1) < len(group0):
    group1,group0 = group0,group1

result = {}
if len(group0) <= len(x[0]):
    while group0 and x[0]:
        result[group0.pop()]= x[0].pop()
    y = x[0]|x[1]|x[2]
    while group1:
        result[group1.pop()] = y.pop()
else:
    while x[2] and group0:
        result[group0.pop()] = x[2].pop()
    while x[1] and group1:
        result[group1.pop()] = x[1].pop()
    while group0 and x[0]:
        result[group0.pop()] = x[0].pop()
    while group1 and x[0]:
        result[group1.pop()] = x[0].pop()
    if group0 or group1:
        print(-1)
        exit()


print(' '.join(str(result[i]) for i in range(1,N+1)))

Submission status: Runtime Error

Solution code:
from collections import defaultdict

N = int(input())
AB = [list(map(int, input().split())) for _ in range(N-1)]

d = defaultdict(list)
class Tree:
    def __init__(self, v):
        self.v = v
        self.neighbors = []

    def set_rank(self,rank,parent):
        self.rank = rank
        for neighbor in self.neighbors:
            if neighbor == parent:
                continue
            neighbor.set_rank(rank=rank+1,parent=self)



trees = {i:Tree(i) for i in range(1,N+1)}

for a,b in AB:
    trees[a].neighbors.append(trees[b])
    trees[b].neighbors.append(trees[a])
trees[1].set_rank(1,None)

group0 = [node.v for node in  trees.values() if node.rank %2 ==0]
group1 = [node.v for node in  trees.values() if node.rank %2]
x = [set(),set(),set()]
for i in range(1,N+1):
    x[i%3].add(i)
if len(group1) < len(group0):
    group1,group0 = group0,group1

result = {}
if len(group0) <= len(x[0]):
    while group0 and x[0]:
        result[group0.pop()]= x[0].pop()
    y = x[0]|x[1]|x[2]
    while group1:
        result[group1.pop()] = y.pop()
else:
    while x[2] and group0:
        result[group0.pop()] = x[2].pop()
    while x[1] and group1:
        result[group1.pop()] = x[1].pop()
    while group0 and x[0]:
        result[group0.pop()] = x[0].pop()
    while group1 and x[0]:
        result[group1.pop()] = x[0].pop()
    if group0 or group1:
        import time
        time.sleep(10)


print(' '.join(str(result[i]) for i in range(1,N+1)))

Submission status: Runtime Error

Solution code:
from collections import defaultdict

N = int(input())
AB = [list(map(int, input().split())) for _ in range(N-1)]

d = defaultdict(list)
class Tree:
    def __init__(self, v):
        self.v = v
        self.neighbors = []

    def set_rank(self,rank,parent):
        self.rank = rank
        for neighbor in self.neighbors:
            if neighbor == parent:
                continue
            neighbor.set_rank(rank=rank+1,parent=self)



trees = {i:Tree(i) for i in range(1,N+1)}

for a,b in AB:
    trees[a].neighbors.append(trees[b])
    trees[b].neighbors.append(trees[a])
trees[1].set_rank(1,None)

group0 = [node.v for node in  trees.values() if node.rank %2 ==0]
group1 = [node.v for node in  trees.values() if node.rank %2]
x = [set(),set(),set()]
for i in range(1,N+1):
    x[i%3].add(i)
if len(group1) < len(group0):
    group1,group0 = group0,group1

result = {}
if len(group0) <= len(x[0]):
    while group0 and x[0]:
        result[group0.pop()]= x[0].pop()
    if group0:
        import time
        time.sleep(100)
    y = x[0]|x[1]|x[2]
    while group1:
        result[group1.pop()] = y.pop()
else:
    while x[2] and group0:
        result[group0.pop()] = x[2].pop()
    while x[1] and group1:
        result[group1.pop()] = x[1].pop()
    while group0 and x[0]:
        result[group0.pop()] = x[0].pop()
    while group1 and x[0]:
        result[group1.pop()] = x[0].pop()

print(' '.join(str(result[i]) for i in range(1,N+1)))

Submission status: Runtime Error

Solution code:
from collections import defaultdict

N = int(input())
AB = [list(map(int, input().split())) for _ in range(N-1)]

d = defaultdict(list)
class Tree:
    def __init__(self, v):
        self.v = v
        self.neighbors = []

    def set_rank(self,rank,parent):
        self.rank = rank
        for neighbor in self.neighbors:
            if neighbor == parent:
                continue
            neighbor.set_rank(rank=rank+1,parent=self)



trees = {i:Tree(i) for i in range(1,N+1)}

for a,b in AB:
    trees[a].neighbors.append(trees[b])
    trees[b].neighbors.append(trees[a])
trees[1].set_rank(1,None)

group0 = [node.v for node in  trees.values() if node.rank %2 ==0]
group1 = [node.v for node in  trees.values() if node.rank %2]
x = [set(),set(),set()]
for i in range(1,N+1):
    x[i%3].add(i)
if len(group1) < len(group0):
    group1,group0 = group0,group1

result = {}
if len(group0) <= len(x[0]):
    while group0:
        result[group0.pop()]= x[0].pop()
    y = x[0]|x[1]|x[2]
    while group1:
        result[group1.pop()] = y.pop()
else:
    while x[2] and group0:
        result[group0.pop()] = x[2].pop()
    while x[1] and group1:
        result[group1.pop()] = x[1].pop()
    while group0:
        result[group0.pop()] = x[0].pop()
    while group1:
        result[group1.pop()] = x[0].pop()

print(' '.join(str(result[i]) for i in range(1,N+1)))

Submission status: Runtime Error

Solution code:
from collections import defaultdict

N = int(input())
AB = [list(map(int, input().split())) for _ in range(N-1)]

d = defaultdict(list)
class Tree:
    def __init__(self, v):
        self.v = v
        self.neighbors = []

    def set_rank(self,rank,parent):
        self.rank = rank
        for neighbor in self.neighbors:
            if neighbor == parent:
                continue
            neighbor.set_rank(rank=rank+1,parent=self)



trees = {i:Tree(i) for i in range(1,N+1)}

for a,b in AB:
    trees[a].neighbors.append(trees[b])
    trees[b].neighbors.append(trees[a])
trees[1].set_rank(1,None)

group0 = [node.v for node in  trees.values() if node.rank %2 ==0]
group1 = [node.v for node in  trees.values() if node.rank %2]
x = [set(),set(),set()]
for i in range(1,N+1):
    x[i%3].add(i)
if len(group1) < len(group0):
    group1,group0 = group0,group1

result = {}
if len(group0) <= len(x[0]):
    while group0:
        result[group0.pop()]= x[0].pop()
    y = x[0]|x[1]|x[2]
    while group1:
        result[group1.pop()] = y.pop()
else:
    while x[1] and group0:
        result[group0.pop()] = x[2].pop()
    while x[2] and group1:
        result[group1.pop()] = x[1].pop()
    while group0:
        result[group0.pop()] = x[0].pop()
    while group1:
        result[group1.pop()] = x[0].pop()

print(' '.join(str(result[i]) for i in range(1,N+1)))