Magnus decided to play a classic chess game. Though what he saw in his locker shocked him! His favourite chessboard got broken into 4 pieces, each of size n by n, n is always odd. And what's even worse, some squares were of wrong color. j-th square of the i-th row of k-th piece of the board has color ak, i, j; 1 being black and 0 being white. 

Now Magnus wants to change color of some squares in such a way that he recolors minimum number of squares and obtained pieces form a valid chessboard. Every square has its color different to each of the neightbouring by side squares in a valid board. Its size should be 2n by 2n. You are allowed to move pieces but not allowed to rotate or flip them.

Input

The first line contains odd integer n (1 ≤ n ≤ 100) — the size of all pieces of the board. 

Then 4 segments follow, each describes one piece of the board. Each consists of n lines of n characters; j-th one of i-th line is equal to 1 if the square is black initially and 0 otherwise. Segments are separated by an empty line.

Output

Print one number — minimum number of squares Magnus should recolor to be able to obtain a valid chessboard.

Examples

Input

1
0

0

1

0


Output

1


Input

3
101
010
101

101
000
101

010
101
011

010
101
010


Output

2
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        ProblemCChessboard solver = new ProblemCChessboard();
        solver.solve(1, in, out);
        out.close();
    }

    static class ProblemCChessboard {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = Integer.parseInt(in.nextLine().trim());
            int[][][] correctPieces = new int[2][n][n];
            for (int i = 0; i < 2; i++) correctPieces[i] = construct(n, i);
            int[][][] pieces = new int[4][n][n];
            for (int i = 0; i < 4; i++) {
                char[][] map = in.nextCharMap(0, 0, n, n);
                for (int j = 0; j < n; j++) for (int k = 0; k < n; k++) pieces[i][j][k] = map[j][k] - '0';
                if (i < 3) in.nextLine();
            }
            int[][] differences = new int[4][2];
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 2; j++) {
                    differences[i][j] = difference(correctPieces[j], pieces[i], n);
                }
            }
            int answer = Integer.MAX_VALUE;
            for (int i = 0; i < (1 << 4); i++) {
                if (countOnes(i) == 2) {
                    int temp = i;
                    int localAnswer = 0;
                    for (int j = 0; j < 4; j++) {
                        int whichOne = temp & 1;
                        temp >>= 1;
                        localAnswer += differences[j][whichOne];
                    }
                    answer = Math.min(answer, localAnswer);
                }
            }
            out.println(answer);
        }

        int[][] construct(int n, int flag) {
            int[][] result = new int[n][n];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    result[i][j] = ((i + j) % 2) ^ (flag);
                }
            }
            return result;
        }

        int difference(int[][] a, int[][] b, int n) {
            int result = 0;
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    result += (a[i][j] != b[i][j]) ? 1 : 0;
                }
            }
            return result;
        }

        int countOnes(int n) {
            int result = 0;
            while (n > 0) {
                result += n & 1;
                n >>= 1;
            }
            return result;
        }

    }

    static class InputReader {
        private StringTokenizer tokenizer;
        private BufferedReader reader;

        public InputReader(InputStream inputStream) {
            reader = new BufferedReader(new InputStreamReader(inputStream));
        }

        public String nextLine() {
            assert tokenizer == null || !tokenizer.hasMoreTokens();
            try {
                return reader.readLine();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

        public char[][] nextCharMap(int offsetRows, int offsetCols, int rowsLength, int colsLength) {
            char[][] map = new char[offsetRows + rowsLength][];
            for (int i = offsetRows; i < offsetRows + rowsLength; i++) {
                char[] line = nextLine().trim().toCharArray();
                map[i] = new char[offsetCols + colsLength];
                System.arraycopy(line, 0, map[i], offsetCols, colsLength);
            }
            return map;
        }

    }
}

