Bit mask + DFS step by step (best practices)
Intuition\n Describe your first thoughts on how to solve this problem. \n\n# Approach\n Describe your approach to solving the problem. \n\n# Complexity\n- Time 
# Intuition\n<!-- Describe your first thoughts on how to solve this problem. -->\n\n# Approach\n<!-- Describe your approach to solving the problem. -->\n\n# Complexity\n- Time complexity: O(m * (2**n))\n<!-- Add your time complexity here, e.g. $$O(n)$$ -->\n\n- Space complexity: O(n + m)\n<!-- Add your space complexity here, e.g. $$O(n)$$ -->\n\n# Code\n```\nfrom collections import defaultdict\nclass Solution:\n    def countSubgraphsForEachDiameter(self, n: int, edges: List[List[int]]) -> List[int]:\n        # TC: O(m * (2**n)) SP: O(n + m)\n        diameters = defaultdict(int)\n        # I hate node start with 1, so I decrease all of them\n        for i in range(len(edges)):\n            edges[i][0] -= 1\n            edges[i][1] -= 1\n        def is_tree(bitmask):\n            if bitmask.bit_count() < 2: return False\n            created_edges = 0\n            for edge in edges:\n                if (1 << edge[0]) & bitmask and (1 << edge[1]) & bitmask:\n                    created_edges += 1\n            if created_edges == bitmask.bit_count() - 1:\n                return True\n            return False\n        \n        # create the tree:\n        def create_tree(bitmask):\n            tree = defaultdict(list)\n            for edge in edges:\n                if (1 << edge[0]) & bitmask and (1 << edge[1]) & bitmask:\n                    tree[edge[0]].append(edge[1])\n                    tree[edge[1]].append(edge[0])\n            return tree\n\n        # calculate the diameter;\n        def dfs(tree, node) -> int:\n            if not tree[node]: return 0\n            max_height = 0\n            second_height = 0\n            visited.add(node)\n            for child in tree[node]:\n                if child in visited: continue\n                height = 1 + dfs(tree, child)\n                if max_height > height >= second_height:\n                    second_height = height\n                elif height >= max_height:\n                    second_height = max_height\n                    max_height = height\n                diameter = max_height + second_height\n                longest_diameter[0] = max(longest_diameter[0], diameter)\n            return max_height\n\n        res = [0] * (n-1)\n        for bitmask in range(1, 1<<n):\n            if not is_tree(bitmask):\n                continue\n            # reset visited\n            visited = set()\n            # reset longest_diameter\n            longest_diameter = [0]\n            tree = create_tree(bitmask)\n            # choose random node to start dfs\n            root = list(tree.keys())[0]\n            dfs(tree, root)\n            # res start from 0 diameter, so -1 to be fit into res\n            res[longest_diameter[0]-1] += 1\n        return res\n            \n\n\n            \n\n\n```
['Python3']