# ========== EASY: Tree Beauty Problem ==========
import sys
sys.setrecursionlimit(300000)
from collections import defaultdict, Counter
MOD = 10**9 + 7
def factor_remove_squares(x):
"""Factor a number and remove perfect square factors"""
result = 1
d = 2
while d * d <= x:
count = 0
while x % d == 0:
count += 1
x //= d
if count % 2 == 1:
result *= d
d += 1 if d == 2 else 2
if x > 1:
result *= x
return result
def get_ans(n, par, a):
# Build tree
children = [[] for _ in range(n+1)]
for i in range(1, n):
children[par[i]].append(i+1)
# Process node values
node_reps = [0] * (n+1)
for i in range(n):
node_reps[i+1] = factor_remove_squares(a[i])
answer = 0
def dfs(u):
nonlocal answer
cnt = Counter()
cnt[node_reps[u]] = 1
total_pairs = 0
for v in children[u]:
child_cnt, child_pairs = dfs(v)
# Add child pairs to total
total_pairs += child_pairs
total_pairs %= MOD
# Count pairs between current subtree and child subtree
for rep, count in child_cnt.items():
if rep == 1: # Already perfect square
total_pairs += count
else:
# Find complement that makes perfect square
complement = 1
temp = rep
d = 2
while d * d <= temp:
cnt_exp = 0
while temp % d == 0:
cnt_exp += 1
temp //= d
if cnt_exp % 2 == 1:
complement *= d
d += 1 if d == 2 else 2
if temp > 1:
complement *= temp
total_pairs += cnt[complement] * count
# Merge child counter into current counter
for rep, count in child_cnt.items():
cnt[rep] += count
# beauty(u) = total_pairs
answer = (answer + total_pairs) % MOD
return cnt, total_pairs
dfs(1)
return answer % MOD
IyA9PT09PT09PT09IEVBU1k6IFRyZWUgQmVhdXR5IFByb2JsZW0gPT09PT09PT09PQppbXBvcnQgc3lzCnN5cy5zZXRyZWN1cnNpb25saW1pdCgzMDAwMDApCmZyb20gY29sbGVjdGlvbnMgaW1wb3J0IGRlZmF1bHRkaWN0LCBDb3VudGVyCgpNT0QgPSAxMCoqOSArIDcKCmRlZiBmYWN0b3JfcmVtb3ZlX3NxdWFyZXMoeCk6CiAgICAiIiJGYWN0b3IgYSBudW1iZXIgYW5kIHJlbW92ZSBwZXJmZWN0IHNxdWFyZSBmYWN0b3JzIiIiCiAgICByZXN1bHQgPSAxCiAgICBkID0gMgogICAgd2hpbGUgZCAqIGQgPD0geDoKICAgICAgICBjb3VudCA9IDAKICAgICAgICB3aGlsZSB4ICUgZCA9PSAwOgogICAgICAgICAgICBjb3VudCArPSAxCiAgICAgICAgICAgIHggLy89IGQKICAgICAgICBpZiBjb3VudCAlIDIgPT0gMToKICAgICAgICAgICAgcmVzdWx0ICo9IGQKICAgICAgICBkICs9IDEgaWYgZCA9PSAyIGVsc2UgMgogICAgaWYgeCA+IDE6CiAgICAgICAgcmVzdWx0ICo9IHgKICAgIHJldHVybiByZXN1bHQKCmRlZiBnZXRfYW5zKG4sIHBhciwgYSk6CiAgICAjIEJ1aWxkIHRyZWUKICAgIGNoaWxkcmVuID0gW1tdIGZvciBfIGluIHJhbmdlKG4rMSldCiAgICBmb3IgaSBpbiByYW5nZSgxLCBuKToKICAgICAgICBjaGlsZHJlbltwYXJbaV1dLmFwcGVuZChpKzEpCiAgICAKICAgICMgUHJvY2VzcyBub2RlIHZhbHVlcwogICAgbm9kZV9yZXBzID0gWzBdICogKG4rMSkKICAgIGZvciBpIGluIHJhbmdlKG4pOgogICAgICAgIG5vZGVfcmVwc1tpKzFdID0gZmFjdG9yX3JlbW92ZV9zcXVhcmVzKGFbaV0pCiAgICAKICAgIGFuc3dlciA9IDAKICAgIAogICAgZGVmIGRmcyh1KToKICAgICAgICBub25sb2NhbCBhbnN3ZXIKICAgICAgICBjbnQgPSBDb3VudGVyKCkKICAgICAgICBjbnRbbm9kZV9yZXBzW3VdXSA9IDEKICAgICAgICB0b3RhbF9wYWlycyA9IDAKICAgICAgICAKICAgICAgICBmb3IgdiBpbiBjaGlsZHJlblt1XToKICAgICAgICAgICAgY2hpbGRfY250LCBjaGlsZF9wYWlycyA9IGRmcyh2KQogICAgICAgICAgICAjIEFkZCBjaGlsZCBwYWlycyB0byB0b3RhbAogICAgICAgICAgICB0b3RhbF9wYWlycyArPSBjaGlsZF9wYWlycwogICAgICAgICAgICB0b3RhbF9wYWlycyAlPSBNT0QKICAgICAgICAgICAgCiAgICAgICAgICAgICMgQ291bnQgcGFpcnMgYmV0d2VlbiBjdXJyZW50IHN1YnRyZWUgYW5kIGNoaWxkIHN1YnRyZWUKICAgICAgICAgICAgZm9yIHJlcCwgY291bnQgaW4gY2hpbGRfY250Lml0ZW1zKCk6CiAgICAgICAgICAgICAgICBpZiByZXAgPT0gMTogICMgQWxyZWFkeSBwZXJmZWN0IHNxdWFyZQogICAgICAgICAgICAgICAgICAgIHRvdGFsX3BhaXJzICs9IGNvdW50CiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICMgRmluZCBjb21wbGVtZW50IHRoYXQgbWFrZXMgcGVyZmVjdCBzcXVhcmUKICAgICAgICAgICAgICAgICAgICBjb21wbGVtZW50ID0gMQogICAgICAgICAgICAgICAgICAgIHRlbXAgPSByZXAKICAgICAgICAgICAgICAgICAgICBkID0gMgogICAgICAgICAgICAgICAgICAgIHdoaWxlIGQgKiBkIDw9IHRlbXA6CiAgICAgICAgICAgICAgICAgICAgICAgIGNudF9leHAgPSAwCiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIHRlbXAgJSBkID09IDA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbnRfZXhwICs9IDEKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAgLy89IGQKICAgICAgICAgICAgICAgICAgICAgICAgaWYgY250X2V4cCAlIDIgPT0gMToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZW1lbnQgKj0gZAogICAgICAgICAgICAgICAgICAgICAgICBkICs9IDEgaWYgZCA9PSAyIGVsc2UgMgogICAgICAgICAgICAgICAgICAgIGlmIHRlbXAgPiAxOgogICAgICAgICAgICAgICAgICAgICAgICBjb21wbGVtZW50ICo9IHRlbXAKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICB0b3RhbF9wYWlycyArPSBjbnRbY29tcGxlbWVudF0gKiBjb3VudAogICAgICAgICAgICAKICAgICAgICAgICAgIyBNZXJnZSBjaGlsZCBjb3VudGVyIGludG8gY3VycmVudCBjb3VudGVyCiAgICAgICAgICAgIGZvciByZXAsIGNvdW50IGluIGNoaWxkX2NudC5pdGVtcygpOgogICAgICAgICAgICAgICAgY250W3JlcF0gKz0gY291bnQKICAgICAgICAKICAgICAgICAjIGJlYXV0eSh1KSA9IHRvdGFsX3BhaXJzCiAgICAgICAgYW5zd2VyID0gKGFuc3dlciArIHRvdGFsX3BhaXJzKSAlIE1PRAogICAgICAgIHJldHVybiBjbnQsIHRvdGFsX3BhaXJzCiAgICAKICAgIGRmcygxKQogICAgcmV0dXJuIGFuc3dlciAlIE1PRA==