[Python 3] Explanation with pictures, DFS
Each node has a depth and height. The longest path passing it has a length equals depth + height.\n\n\n\nWhen a node (Let\'s say D) is removed, all of its child
Each node has a **depth** and **height**. The longest path passing it has a length equals `depth + height`.\n\n![image](https://assets.leetcode.com/users/images/a10e9a89-fb45-45b7-9470-28adc3574d61_1667102453.8528125.png)\n\nWhen a node (Let\'s say **D**) is removed, all of its children are removed as well. So every path that goes through **D** stops by here. However, if **D** has some cousions, then the paths through these cousins will certainly be longer. We should look for the longest path among these paths through the cousins of **D**, which is equivalent to finding the cousin with the largest **height**.\n\n![image](https://assets.leetcode.com/users/images/c8438256-94e9-4810-8d60-fdaf73576791_1667102457.8192077.png)\n\nTherefore, we store the nodes according to **depth**. For nodes having the same depth, we sort them by their heights and only keep the top 2 of them that having the maximum depth.\n\n![image](https://assets.leetcode.com/users/images/b5bfc58a-3dc0-48f3-8348-34cf1bf38c80_1667104420.761939.png)\n\n\nOnce we \'remove\' a node from `queries`, we locate all of its cousins, find the one with the maximum height and the job is done.\n\n- If the size of `cousins[depth]` is 1, which means that the `removed` node has no cousin, so the longest resting path equals `depth - 1`. \n- Otherwise, at least one of them is the cousin, we get its depth.\n\n\nTCSC:\n- Time O(N)\n- Space O(N)\n\n<br>\n<br>\n\n\n\n```python\nclass Solution:\n    def treeQueries(self, R: Optional[TreeNode], Q: List[int]) -> List[int]:\n        Depth, Height = collections.defaultdict(int), collections.defaultdict(int)\n\n        def dfs(node, depth):\n            if not node:\n                return -1\n            Depth[node.val] = depth\n            cur = max(dfs(node.left, depth + 1), dfs(node.right, depth + 1)) + 1\n            Height[node.val] = cur\n            return cur\n        dfs(R, 0)\n\n        cousins = collections.defaultdict(list) # Group nodes according to their depth. Keep the top 2 heights.\n        for val, depth in Depth.items():\n            cousins[depth].append((-Height[val], val))\n            cousins[depth].sort()\n            if len(cousins[depth]) > 2:\n                cousins[depth].pop()\n\n        ans = []\n        for q in Q:\n            depth = Depth[q]\n            if len(cousins[depth]) == 1:  # No cousin, path length equals depth - 1.\n                ans.append(depth - 1)\n            elif cousins[depth][0][1] == q:  # The removed node has the largest height, look for the node with 2nd largest height.\n                ans.append(-cousins[depth][1][0] + depth)\n\t\t\telse:   # Look for the node with the largest height.\n                ans.append(-cousins[depth][0][0] + depth)\n        return ans\n```
[]