'use strict'

/**
 * Definition for undirected graph.
 * function UndirectedGraphNode(label) {
 *     this.label = label;
 *     this.neighbors = [];   // Array of UndirectedGraphNode
 * }
 */


function UndirectedGraphNode(label) {
    this.label = label
    this.neighbors = [] // Array of UndirectedGraphNode
}

/**
 * @param {UndirectedGraphNode} graph
 * @return {UndirectedGraphNode}
 */
var cloneGraph = function (graph) {
    if (graph == null) return null
    const map = new Map()
    return clone(graph, map)
}

/**
 * @param {UndirectedGraphNode} node 
 * @param {Map} map
 * @return {UndirectedGraphNode}
 */
function clone(node, map) { // DFS
    if (node === null) return null
    if (map.get(node.label) !== undefined)
        return map.get(node.label)
    const copy = new UndirectedGraphNode(node.label)
    map.set(copy.label, copy)
    for (const n of node.neighbors) {
        copy.neighbors.push(clone(n, map))
    }
    return copy
}

function __main__() {
    /* eslint no-console: ["error", {allow: ["log"]}] */
    const logger = console.log.bind(console)
    const n3 = new UndirectedGraphNode(3)
    const n2 = new UndirectedGraphNode(2)
    const n1 = new UndirectedGraphNode(1)
    n3.neighbors = [n2, n3]
    n2.neighbors = [n1, n3]
    n1.neighbors = [n2, n3]
    const n = cloneGraph(n1)
    logger(n)
}

__main__()