Java dfs
```java\nclass Solution {\n    public class Node {\n        int id;\n        int value;\n        List edges;\n        public Node(int id, int value) {\n        
```java\nclass Solution {\n    public class Node {\n        int id;\n        int value;\n        List<Edge> edges;\n        public Node(int id, int value) {\n            this.id = id;\n            this.value = value;\n            edges = new ArrayList<>();\n        }\n    }\n    \n    public class Edge {\n        int id1;\n        int id2;\n        int cost;\n        public Edge(int id1, int id2, int cost) {\n            this.id1 = id1;\n            this.id2 = id2;\n            this.cost = cost;\n        }\n    }\n    \n    public int maximalPathQuality(int[] values, int[][] edges, int maxTime) {\n        List<Node> nodes = new ArrayList<>();\n        for (int i = 0; i < values.length; i++) {\n            nodes.add(new Node(i, values[i]));\n        }\n        \n        for (int[] edge : edges) {\n            Edge e = new Edge(edge[0], edge[1], edge[2]);\n            nodes.get(edge[0]).edges.add(e);\n            nodes.get(edge[1]).edges.add(e);\n        }\n        \n        for (Node node : nodes) {\n            Collections.sort(node.edges, (e1, e2) -> {\n                return e1.cost - e2.cost;\n            });\n        }\n        \n        Set<Integer> qualityAdded = new HashSet<>();\n        qualityAdded.add(0);\n        return visit(nodes, 0, qualityAdded, maxTime, nodes.get(0).value, 0);\n    }\n    \n    private int visit(List<Node> nodes, int curId, Set<Integer> qualityAdded, int maxTime, int quality, int time) {     \n        if (time > maxTime) {\n            return Integer.MIN_VALUE;\n        }\n        \n        int maxQuality = Integer.MIN_VALUE;\n        if (curId == 0 && time <= maxTime) {\n            maxQuality = Math.max(maxQuality, quality);\n        }\n        \n        for (Edge edge : nodes.get(curId).edges) {\n            if (time + edge.cost > maxTime) {\n                break;\n            }\n            \n            int nbrId = edge.id1 != curId ? edge.id1 : edge.id2;\n            boolean hasAdded = qualityAdded.contains(nbrId);\n            qualityAdded.add(nbrId);\n            int newQuality = hasAdded ? quality : quality + nodes.get(nbrId).value;\n            maxQuality = Math.max(maxQuality, visit(nodes, nbrId, qualityAdded, maxTime, newQuality, time + edge.cost));\n            if (!hasAdded) {\n                qualityAdded.remove(nbrId);\n            }\n        }\n        \n        return maxQuality;\n    }\n}
[]