# your code goes here
def palindromePaths(tree_nodes, tree_from, tree_to, arr, queries):
# 1. Build the adjacency list for the undirected tree
adj = [[] for _ in range(tree_nodes)]
for u, v in zip(tree_from, tree_to):
adj[u].append(v)
adj[v].append(u)
# 2. Array to store the precalculated answer for every node
node_answers = [0] * tree_nodes
# 3. Hash map to store the frequency of masks of the ancestors
freq = {}
# 4. Stack for Iterative DFS to avoid RecursionError on deep trees.
# Elements: (current_node, parent_node, path_mask_to_parent, state)
# State 0: Entering the node (pre-order)
# State 1: Exiting the node (post-order, for backtracking)
stack = [(0, -1, 0, 0)]
while stack:
u, p, current_mask, state = stack.pop()
if state == 0:
# Toggle the bit corresponding to the character at node `u`
char_idx = ord(arr[u]) - ord('a')
P_u = current_mask ^ (1 << char_idx)
# Add the parent's path mask to our active ancestor frequencies
freq[current_mask] = freq.get(current_mask, 0) + 1
# Count valid ancestors v where the path from u to v is a palindrome
# Condition: P_u ^ P_parent(v) has at most 1 bit set (0 or power of 2)
# Case 1: 0 bits set (perfectly even frequencies)
count = freq.get(P_u, 0)
# Case 2: exactly 1 bit set (one odd character frequency)
for i in range(26):
count += freq.get(P_u ^ (1 << i), 0)
# Save the answer for the current node
node_answers[u] = count
# Push the backtrack state for the current node
stack.append((u, p, current_mask, 1))
# Push children to the stack
for v in adj[u]:
if v != p:
stack.append((v, u, P_u, 0))
else:
# Backtrack: Remove the current ancestor mask as we exit the branch
freq[current_mask] -= 1
if freq[current_mask] == 0:
del freq[current_mask]
# 5. Return answers for the required queries in O(1) time each
return [node_answers[q] for q in queries]
print(palindromePaths(7, [0,1,2,2,4,4,7], [1,2,3,4,5,6], ['a', 'b', 'c', 'a', 'c','b', 'c'], [6,5,3]))
IyB5b3VyIGNvZGUgZ29lcyBoZXJlCmRlZiBwYWxpbmRyb21lUGF0aHModHJlZV9ub2RlcywgdHJlZV9mcm9tLCB0cmVlX3RvLCBhcnIsIHF1ZXJpZXMpOgogICAgIyAxLiBCdWlsZCB0aGUgYWRqYWNlbmN5IGxpc3QgZm9yIHRoZSB1bmRpcmVjdGVkIHRyZWUKICAgIGFkaiA9IFtbXSBmb3IgXyBpbiByYW5nZSh0cmVlX25vZGVzKV0KICAgIGZvciB1LCB2IGluIHppcCh0cmVlX2Zyb20sIHRyZWVfdG8pOgogICAgICAgIGFkalt1XS5hcHBlbmQodikKICAgICAgICBhZGpbdl0uYXBwZW5kKHUpCgogICAgIyAyLiBBcnJheSB0byBzdG9yZSB0aGUgcHJlY2FsY3VsYXRlZCBhbnN3ZXIgZm9yIGV2ZXJ5IG5vZGUKICAgIG5vZGVfYW5zd2VycyA9IFswXSAqIHRyZWVfbm9kZXMKCiAgICAjIDMuIEhhc2ggbWFwIHRvIHN0b3JlIHRoZSBmcmVxdWVuY3kgb2YgbWFza3Mgb2YgdGhlIGFuY2VzdG9ycwogICAgZnJlcSA9IHt9CgogICAgIyA0LiBTdGFjayBmb3IgSXRlcmF0aXZlIERGUyB0byBhdm9pZCBSZWN1cnNpb25FcnJvciBvbiBkZWVwIHRyZWVzLgogICAgIyBFbGVtZW50czogKGN1cnJlbnRfbm9kZSwgcGFyZW50X25vZGUsIHBhdGhfbWFza190b19wYXJlbnQsIHN0YXRlKQogICAgIyBTdGF0ZSAwOiBFbnRlcmluZyB0aGUgbm9kZSAocHJlLW9yZGVyKQogICAgIyBTdGF0ZSAxOiBFeGl0aW5nIHRoZSBub2RlIChwb3N0LW9yZGVyLCBmb3IgYmFja3RyYWNraW5nKQogICAgc3RhY2sgPSBbKDAsIC0xLCAwLCAwKV0KCiAgICB3aGlsZSBzdGFjazoKICAgICAgICB1LCBwLCBjdXJyZW50X21hc2ssIHN0YXRlID0gc3RhY2sucG9wKCkKCiAgICAgICAgaWYgc3RhdGUgPT0gMDoKICAgICAgICAgICAgIyBUb2dnbGUgdGhlIGJpdCBjb3JyZXNwb25kaW5nIHRvIHRoZSBjaGFyYWN0ZXIgYXQgbm9kZSBgdWAKICAgICAgICAgICAgY2hhcl9pZHggPSBvcmQoYXJyW3VdKSAtIG9yZCgnYScpCiAgICAgICAgICAgIFBfdSA9IGN1cnJlbnRfbWFzayBeICgxIDw8IGNoYXJfaWR4KQoKICAgICAgICAgICAgIyBBZGQgdGhlIHBhcmVudCdzIHBhdGggbWFzayB0byBvdXIgYWN0aXZlIGFuY2VzdG9yIGZyZXF1ZW5jaWVzCiAgICAgICAgICAgIGZyZXFbY3VycmVudF9tYXNrXSA9IGZyZXEuZ2V0KGN1cnJlbnRfbWFzaywgMCkgKyAxCgogICAgICAgICAgICAjIENvdW50IHZhbGlkIGFuY2VzdG9ycyB2IHdoZXJlIHRoZSBwYXRoIGZyb20gdSB0byB2IGlzIGEgcGFsaW5kcm9tZQogICAgICAgICAgICAjIENvbmRpdGlvbjogUF91IF4gUF9wYXJlbnQodikgaGFzIGF0IG1vc3QgMSBiaXQgc2V0ICgwIG9yIHBvd2VyIG9mIDIpCiAgICAgICAgICAgIAogICAgICAgICAgICAjIENhc2UgMTogMCBiaXRzIHNldCAocGVyZmVjdGx5IGV2ZW4gZnJlcXVlbmNpZXMpCiAgICAgICAgICAgIGNvdW50ID0gZnJlcS5nZXQoUF91LCAwKQogICAgICAgICAgICAKICAgICAgICAgICAgIyBDYXNlIDI6IGV4YWN0bHkgMSBiaXQgc2V0IChvbmUgb2RkIGNoYXJhY3RlciBmcmVxdWVuY3kpCiAgICAgICAgICAgIGZvciBpIGluIHJhbmdlKDI2KToKICAgICAgICAgICAgICAgIGNvdW50ICs9IGZyZXEuZ2V0KFBfdSBeICgxIDw8IGkpLCAwKQoKICAgICAgICAgICAgIyBTYXZlIHRoZSBhbnN3ZXIgZm9yIHRoZSBjdXJyZW50IG5vZGUKICAgICAgICAgICAgbm9kZV9hbnN3ZXJzW3VdID0gY291bnQKCiAgICAgICAgICAgICMgUHVzaCB0aGUgYmFja3RyYWNrIHN0YXRlIGZvciB0aGUgY3VycmVudCBub2RlCiAgICAgICAgICAgIHN0YWNrLmFwcGVuZCgodSwgcCwgY3VycmVudF9tYXNrLCAxKSkKCiAgICAgICAgICAgICMgUHVzaCBjaGlsZHJlbiB0byB0aGUgc3RhY2sKICAgICAgICAgICAgZm9yIHYgaW4gYWRqW3VdOgogICAgICAgICAgICAgICAgaWYgdiAhPSBwOgogICAgICAgICAgICAgICAgICAgIHN0YWNrLmFwcGVuZCgodiwgdSwgUF91LCAwKSkKICAgICAgICBlbHNlOgogICAgICAgICAgICAjIEJhY2t0cmFjazogUmVtb3ZlIHRoZSBjdXJyZW50IGFuY2VzdG9yIG1hc2sgYXMgd2UgZXhpdCB0aGUgYnJhbmNoCiAgICAgICAgICAgIGZyZXFbY3VycmVudF9tYXNrXSAtPSAxCiAgICAgICAgICAgIGlmIGZyZXFbY3VycmVudF9tYXNrXSA9PSAwOgogICAgICAgICAgICAgICAgZGVsIGZyZXFbY3VycmVudF9tYXNrXQoKICAgICMgNS4gUmV0dXJuIGFuc3dlcnMgZm9yIHRoZSByZXF1aXJlZCBxdWVyaWVzIGluIE8oMSkgdGltZSBlYWNoCiAgICByZXR1cm4gW25vZGVfYW5zd2Vyc1txXSBmb3IgcSBpbiBxdWVyaWVzXQogICAgCiAgICAKcHJpbnQocGFsaW5kcm9tZVBhdGhzKDcsIFswLDEsMiwyLDQsNCw3XSwgWzEsMiwzLDQsNSw2XSwgWydhJywgJ2InLCAnYycsICdhJywgJ2MnLCdiJywgJ2MnXSwgWzYsNSwzXSkp