Problem:
Score : 1300 points

Problem Statement

There is a square-shaped grid with N vertical rows and N horizontal columns.
We will denote the square at the i-th row from the top and the j-th column from the left as (i,\ j).

Initially, each square is either white or black.
The initial color of the grid is given to you as characters a_{ij}, arranged in a square shape.
If the square (i,\ j) is white, a_{ij} is .. If it is black, a_{ij} is #.

You are developing a robot that repaints the grid.
It can repeatedly perform the following operation:

Select two integers i, j (1 ≤ i,\ j ≤ N). Memorize the colors of the squares (i,\ 1), (i,\ 2), ..., (i,\ N) as c_1, c_2, ..., c_N, respectively. Then, repaint the squares (1,\ j), (2,\ j), ..., (N,\ j) with the colors c_1, c_2, ..., c_N, respectively.

Your objective is to turn all the squares black.
Determine whether it is possible, and find the minimum necessary number of operations to achieve it if the answer is positive.

Constraints

2 ≤ N ≤ 500

a_{ij} is either . or #.

Partial Score

In a test set worth 300 points, N ≤ 3.

Input

The input is given from Standard Input in the following format:

N
a_{11}...a_{1N}
:
a_{N1}...a_{NN}

Output

If it is possible to turn all the squares black, print the minimum necessary number of operations to achieve the objective.
If it is impossible, print -1 instead.

Sample Input 1

2
#.
.#

Sample Output 1

3

For example, perform the operation as follows:

Select i = 1, j = 2.

Select i = 1, j = 1.

Select i = 1, j = 2.

The transition of the colors of the squares is shown in the figure below:

Sample Input 2

2
..
..

Sample Output 2

-1

Sample Input 3

2
##
##

Sample Output 3

0

Sample Input 4

3
.#.
###
.#.

Sample Output 4

2

Sample Input 5

3
...
.#.
...

Sample Output 5

5

Solution in Common Lisp (SBCL 1.1.14) (judge verdict: Runtime Error)

(eval-when (:compile-toplevel :load-toplevel :execute)
  (sb-int:defconstant-eqx OPT
    #+swank '(optimize (speed 3) (safety 2))
    #-swank '(optimize (speed 3) (safety 0) (debug 0))
    #'equal)
  #+swank (ql:quickload '(:cl-debug-print :fiveam) :silent t)
  #-swank (set-dispatch-macro-character
           ;; enclose the form with VALUES to avoid being captured by LOOP macro
           #\# #\> (lambda (s c p) (declare (ignore c p)) `(values ,(read s nil nil t)))))
#+swank (cl-syntax:use-syntax cl-debug-print:debug-print-syntax)
#-swank (disable-debugger) ; for CS Academy

;; BEGIN_INSERTED_CONTENTS
(macrolet ((def (name fname)
             `(define-modify-macro ,name (new-value) ,fname)))
  (def minf min)
  (def maxf max)
  (def mulf *)
  (def divf /)
  (def iorf logior)
  (def xorf logxor)
  (def andf logand))

(defmacro dbg (&rest forms)
  #+swank
  (if (= (length forms) 1)
      `(format *error-output* "~A => ~A~%" ',(car forms) ,(car forms))
      `(format *error-output* "~A => ~A~%" ',forms `(,,@forms)))
  #-swank (declare (ignore forms)))

(defmacro define-int-types (&rest bits)
  `(progn
     ,@(mapcar (lambda (b) `(deftype ,(intern (format nil "UINT~A" b)) () '(unsigned-byte ,b))) bits)
     ,@(mapcar (lambda (b) `(deftype ,(intern (format nil "INT~A" b)) () '(signed-byte ,b))) bits)))
(define-int-types 2 4 7 8 15 16 31 32 62 63 64)

(declaim (inline println))
(defun println (obj &optional (stream *standard-output*))
  (let ((*read-default-float-format* 'double-float))
    (prog1 (princ obj stream) (terpri stream))))

(defconstant +mod+ 1000000007)

;;;
;;; Body
;;;

(defun main ()
  (let* ((n (read))
         (diagonal 0)
         (safe 0)
         (plan (make-array (list n n) :element-type 'bit :initial-element 0))
         (rows (make-array n :element-type 'uint32 :initial-element 0))
         (cols (make-array n :element-type 'uint32 :initial-element 0)))
    (dotimes (i n)
      (let ((line (read-line)))
        (dotimes (j n)
          (when (char= #\# (aref line j))
            (setf (aref plan i j) 1)
            (if (= i j)
                (incf diagonal)
                (incf safe))
            (incf (aref rows i))
            (incf (aref cols j))))))
    (when (= 0 diagonal safe)
      (println -1)
      (return-from main))
    (when (and (find n rows) (find n cols))
      (println (min (- n (count n cols))
                    (- n (count n rows))))
      (return-from main))
    (error "Huh?")
    (when (find n rows)
      (println (min (- n (count n cols))
                    (+ 1 (- n (count n rows)))))
      (return-from main))
    (when (find n cols)
      (println (min (- n (count n rows))
                    (+ 1 (- n (count n cols)))))
      (return-from main))
    ;; (error "Huh?")
    (let ((base (if (zerop safe)
                    #xffffffff
                    (+ 1 (min (reduce #'max rows :key (lambda (x) (- n x)))
                              (reduce #'max cols :key (lambda (x) (- n x))))))))
      #>base
      (dotimes (i n)
        (dotimes (j n)
          (when (= 1 (aref plan i j))
            (minf base (- n (aref rows j)))
            (minf base (- n (aref cols i)))
            (when (= i j)
              (minf base
                    (+ 1 (min (loop for row below n
                                    when (= 1 (aref plan row i))
                                    minimize (- n (aref rows row)))
                              (loop for col below n
                                    when (= 1 (aref plan j col))
                                    minimize (- n (aref cols col))))))))))
      (assert (< base #xffffffff))
      (println (+ base n)))))

#-swank (main)

;;;
;;; Test and benchmark
;;;

#+swank
(defun io-equal (in-string out-string &key (function #'main) (test #'equal))
  "Passes IN-STRING to *STANDARD-INPUT*, executes FUNCTION, and returns true if
the string output to *STANDARD-OUTPUT* is equal to OUT-STRING."
  (labels ((ensure-last-lf (s)
             (if (eql (uiop:last-char s) #\Linefeed)
                 s
                 (uiop:strcat s uiop:+lf+))))
    (funcall test
             (ensure-last-lf out-string)
             (with-output-to-string (out)
               (let ((*standard-output* out))
                 (with-input-from-string (*standard-input* (ensure-last-lf in-string))
                   (funcall function)))))))

#+swank
(defun get-clipbrd ()
  (with-output-to-string (out)
    (run-program "powershell.exe" '("-Command" "Get-Clipboard") :output out :search t)))

#+swank (defparameter *this-pathname* (uiop:current-lisp-file-pathname))
#+swank (defparameter *dat-pathname* (uiop:merge-pathnames* "test.dat" *this-pathname*))

#+swank
(defun run (&optional thing (out *standard-output*))
  "THING := null | string | symbol | pathname

null: run #'MAIN using the text on clipboard as input.
string: run #'MAIN using the string as input.
symbol: alias of FIVEAM:RUN!.
pathname: run #'MAIN using the text file as input."
  (let ((*standard-output* out))
    (etypecase thing
      (null
       (with-input-from-string (*standard-input* (delete #\Return (get-clipbrd)))
         (main)))
      (string
       (with-input-from-string (*standard-input* (delete #\Return thing))
         (main)))
      (symbol (5am:run! thing))
      (pathname
       (with-open-file (*standard-input* thing)
         (main))))))

#+swank
(defun gen-dat ()
  (uiop:with-output-file (out *dat-pathname* :if-exists :supersede)
    (format out "")))

#+swank
(defun bench (&optional (out (make-broadcast-stream)))
  (time (run *dat-pathname* out)))

;; To run: (5am:run! :sample)
#+swank
(it.bese.fiveam:test :sample
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "2
#.
.#
"
    "3
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "2
..
..
"
    "-1
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "2
##
##
"
    "0
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "3
.#.
###
.#.
"
    "2
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "3
...
.#.
...
"
    "5
")))