Java soln
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:\n<!-- Add your time complexity here, e.g. $$O(n)$$ -->\n\n- Space complexity:\n<!-- Add your space complexity here, e.g. $$O(n)$$ -->\n\n# Code\n```\nclass Solution {\n    /**\n    At each node, we need to find out if current subtree size is less than 3.\n    If so, we just set ans of that node = 1.\n    Otherwise, we need to gather costs of entire subtree including itself \n    and check for max of (top 3 products and top 1 * min top 2 products).\n    If the cost is coming negative, just set cur node ans as 0\n    \n    We then need to pass on the costs information to node above. If cost length\n    is < 5, we pass it as is. Otherwise, need to filter them out.\n    */\n\n    Map<Integer, List<Integer>> graph;\n\n    public long[] placedCoins(int[][] edges, int[] cost) {\n        int n = cost.length;\n        graph = new HashMap<>();\n        for (int[] edge : edges) {\n            graph.putIfAbsent(edge[0], new ArrayList<>());\n            graph.putIfAbsent(edge[1], new ArrayList<>());\n            graph.get(edge[0]).add(edge[1]);\n            graph.get(edge[1]).add(edge[0]);\n        }\n        Set<Integer> seen = new HashSet<>();\n        long[] ans = new long[n];\n        dfs(0, ans, cost, seen);\n        return ans;\n    }\n\n    private List<Integer> dfs(int curNode, long[] ans, int[] cost, Set<Integer> seen) {\n        seen.add(curNode);\n\n        List<Integer> curSubTreeCosts = new ArrayList<>();\n        curSubTreeCosts.add(cost[curNode]);\n        for (int child : graph.get(curNode)) {\n            if (!seen.contains(child))\n                curSubTreeCosts.addAll(dfs(child, ans, cost, seen));\n        }\n        Collections.sort(curSubTreeCosts);\n\n        int size = curSubTreeCosts.size();\n        if (size < 3) {\n            ans[curNode] = 1;\n            return curSubTreeCosts;\n        } else {\n            int max1 = curSubTreeCosts.get(size - 1);\n            int max2 = curSubTreeCosts.get(size - 2);\n            int max3 = curSubTreeCosts.get(size - 3);\n            int min1 = curSubTreeCosts.get(0);\n            int min2 = curSubTreeCosts.get(1);\n            ans[curNode] = Math.max((long) max1*max2*max3, (long) min1*min2*max1);\n            ans[curNode] = ans[curNode] < 0 ? 0 : ans[curNode];\n        }\n\n        if (size <= 5) {\n            return curSubTreeCosts;\n        } else {\n            List<Integer> ret = new ArrayList<>();\n            ret.add(curSubTreeCosts.get(size - 1));\n            ret.add(curSubTreeCosts.get(size - 2));\n            ret.add(curSubTreeCosts.get(size - 3));\n            ret.add(curSubTreeCosts.get(0));\n            ret.add(curSubTreeCosts.get(1));\n            return ret;\n        }\n    }\n}\n```
['Java']