public RandomListNode copyRandomList(RandomListNode head) {
        if (head == null) return null;

        // replicate next nodes
        RandomListNode p = head;
        while (p != null) {
            RandomListNode copy = new RandomListNode(p.label);
            copy.next = p.next;
            p.next = copy;
            p = copy.next;
        }

        // replicate random nodes
        p = head;
        while (p != null) {
            RandomListNode copy = p.next;
            if (p.random != null) copy.random = p.random.next;
            p = copy.next;
        }

        // decouple two lists
        p = head;
        RandomListNode newHead = head.next;
        while (p != null) {
            RandomListNode copy = p.next;
            p.next = copy.next;
            if (copy.next != null) copy.next = copy.next.next;
            p = p.next;
        }
        return newHead;
    }