public UndirectedGraphNode cloneGraphII(UndirectedGraphNode node) {
		if (node == null)
			return node;

		Set<UndirectedGraphNode> set = new HashSet<>();
		Stack<UndirectedGraphNode> unvisited = new Stack<>();
		unvisited.add(node);

		while (!unvisited.isEmpty()) {
			UndirectedGraphNode current = unvisited.pop();
			set.add(current);
			for (UndirectedGraphNode n : current.neighbors) { // only add to unvisited if they are unvisited!
				if (n != null && !set.contains(n)) {
					unvisited.add(n);
				}
			}
		}

		Map<UndirectedGraphNode, UndirectedGraphNode> old2NewMapping = new HashMap<>();

		for (UndirectedGraphNode old : set) {
			UndirectedGraphNode newNode = new UndirectedGraphNode(old.label);
			old2NewMapping.put(old, newNode);
		}

		for (UndirectedGraphNode old : set) {
			UndirectedGraphNode newNode = old2NewMapping.get(old);
			for (UndirectedGraphNode neighbor : old.neighbors) {
				newNode.neighbors.add(old2NewMapping.get(neighbor));
			}
		}

		return old2NewMapping.get(node);
	}