[Python DFS] for each subtree, find its diameter
DFS to find all subtrees (expand_tree).\nFor each subtree, DFS to find its diameter (get_diameter).\nCode self-explains, with inline comments:\n\nfrom functools
DFS to find all subtrees (`expand_tree`).\nFor each subtree, DFS to find its diameter (`get_diameter`).\nCode self-explains, with inline comments:\n```\nfrom functools import lru_cache\nfrom collections import defaultdict\n\nclass Solution:\n    def countSubgraphsForEachDiameter(self, n: int, edges: List[List[int]]) -> List[int]:\n            \n        def each_one_bit(binary):\n            while binary:\n                next_binary = binary & binary - 1\n                yield binary - next_binary  # yield the right-most bit 1 of `binary`\n                binary = next_binary\n\n        def get_diameter(node, subtree, frm):\n            depth = max_res = 0\n            for neighbor in each_one_bit(graph[node]):\n                if neighbor == frm:\n                    continue  # do not go back\n                if neighbor & subtree == 0:\n                    continue  # neighbor not in subtree\n                this_depth, this_max_res = get_diameter(neighbor, subtree, node)\n                max_res = max(max_res, this_max_res, depth + this_depth)\n                depth = max(depth, this_depth)\n            return depth + 1, max_res  # (max depth, max diameter)\n\n        @lru_cache(1 << n)  # do not search a same subtree again\n        def expand_tree(subtree):\n            _, max_res = get_diameter(subtree - ((subtree - 1) & subtree), subtree, 0)  # find the diameter of the subtree, by DFS from the smallest node\n            res[max_res] += 1\n            for shift in range(n):\n                candidate = 1 << shift  # candidate to expand from the subtree\n                if candidate & subtree != 0:\n                    continue  # already in subtree\n                candidate_neighbors = graph[candidate]\n                if candidate_neighbors & subtree == 0:\n                    continue  # not connected\n                expand_tree(subtree | candidate)\n                \n        # make graph\n        graph = defaultdict(int)\n        for u, v in edges:\n            graph[1 << (u - 1)] |= 1 << (v - 1)\n            graph[1 << (v - 1)] |= 1 << (u - 1)\n        res = [0] * n\n        # expand subtrees from each single node\n        for shift in range(n):\n            expand_tree(1 << shift)\n        return res[1:]\n```
[]