Problem:
Score : 300 points

Problem Statement

We have N sticks with negligible thickness.
The length of the i-th stick is A_i.

Snuke wants to select four different sticks from these sticks and form a rectangle (including a square), using the sticks as its sides.
Find the maximum possible area of the rectangle.

Constraints

4 \leq N \leq 10^5

1 \leq A_i \leq 10^9

A_i is an integer.

Input

Input is given from Standard Input in the following format:

N
A_1 A_2 ... A_N

Output

Print the maximum possible area of the rectangle.
If no rectangle can be formed, print 0.

Sample Input 1

6
3 1 2 4 2 1

Sample Output 1

2

1 \times 2 rectangle can be formed.

Sample Input 2

4
1 2 3 4

Sample Output 2

0

No rectangle can be formed.

Sample Input 3

10
3 3 3 3 4 4 4 5 5 5

Sample Output 3

20

Solution in Common Lisp (SBCL 1.1.14) (judge verdict: Accepted)

(eval-when (:compile-toplevel :load-toplevel :execute)
  (defparameter OPT
    #+swank '(optimize (speed 3) (safety 1))
    #-swank '(optimize (speed 3) (safety 0) (debug 0)))
  #+swank (ql:quickload '(:cl-debug-print :fiveam)))
#+swank (cl-syntax:use-syntax cl-debug-print:debug-print-syntax)

;; BEGIN_INSERTED_CONTENTS
(defun ensure-list (x) (if (listp x) x (list x)))
(defmacro nlet (name args &body body)
  (let ((args (mapcar #'ensure-list args)))
    `(labels ((,name ,(mapcar #'car args) ,@body))
       (,name ,@(mapcar #'cadr args)))))

(declaim (inline split-to-list))
(defun split-to-list (str size)
  (declare (optimize (speed 3) (safety 1))
           (fixnum size)
           (string str))
  (loop for idx below size
        for pos1 = 0 then (1+ pos2)
        for pos2 = (position #\space str :start pos1 :test #'char=)
        collect (parse-integer str :start pos1 :end pos2)))

(defmacro println (obj &optional (stream '*standard-output*))
  `(let ((*read-default-float-format* 'double-float))
     (prog1 (princ ,obj ,stream) (terpri ,stream))))

;; Hauptteil
(declaim (inline extract-available-bars))
(defun extract-available-bars (list)
  (nlet recurse ((list list) (hash (make-hash-table)) res)
    (cond ((null list) res)
          ((gethash (car list) hash)
           (setf (gethash (car list) hash) nil)
           (recurse (cdr list) hash (cons (car list) res)))
          (t (setf (gethash (car list) hash) t)
             (recurse (cdr list) hash res)))))

(deftype uint nil `(integer 0 ,(expt 10 9)))
(defun main ()
  (declare #.OPT)
  (let* ((n (read))
         (bars (split-to-list (read-line) n))
         (available-bars (extract-available-bars bars)))
    (if (null (cdr available-bars))
        (println 0)
        (let* ((longest (reduce #'max available-bars))
               (second-longest (reduce #'max (delete longest available-bars :count 1))))
          (println (* longest second-longest))))))

#-swank(main)