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.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Time;
import java.util.*;

public class cc2 {

    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        public FastReader() {
            br = new BufferedReader(new
                    InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
    public static void main(String[] args) {
        FastReader fr = new FastReader();
        int n = fr.nextInt();
        boolean matrices[][][] = new boolean[4][n][n];
        boolean[] typeA = new boolean[n] , typeB = new boolean[n];
        for(int i=0;i<n;++i){
            if(i%2 == 0){
                typeB[i] = true;
            }
            else{
                typeA[i] = true;
            }
        }
        for(int i=0;i<4;++i){
            for(int j=0;j<n;++j){
                String s = fr.next();
                for(int k=0;k<s.length();++k){
                    if(s.charAt(k) == '1'){
                        matrices[i][j][k] = true;
                    }
                }
            }
        }
        // Check with 01010..
        int mapA[] = new int[4];
        for(int i=0;i<4;++i) {
            boolean A = true;
            int cnt = 0;
            for (int j = 0; j < n; ++j) {
                if (A) { // j%2 == 0 always.
                    for (int k = 0; k < n; ++k) {
                        if(typeA[k] != matrices[i][j][k]) {
                            ++cnt;
                        }
                    }
                } else {
                    for (int k = 0; k < n; ++k) {
                        if(typeB[k] != matrices[i][j][k]) {
                            ++cnt;
                        }
                    }
                }
                A = !A;
            }
            mapA[i] = cnt;
        }
        // Check with 1010101..
        int mapB[] = new int[4];
        for(int i=0;i<4;++i) {
            boolean B = true;
            int cnt = 0;
            for (int j = 0; j < n; ++j) {
                if (B) {
                    for (int k = 0; k < n; ++k) {
                        if(typeB[k] != matrices[i][j][k]) {
                            ++cnt;
                        }
                    }
                } else {
                    for (int k = 0; k < n; ++k) {
                        if(typeA[k] != matrices[i][j][k]) {
                            ++cnt;
                        }
                    }
                }
                B = !B;
            }
            mapB[i] = cnt;
        }

        if(n%2 == 0){
            System.out.println(Math.min(mapA[0]+mapA[1]+mapA[2]+mapA[3] ,  mapB[0]+mapB[1]+mapB[2]+mapB[3]));
        }
        else {
            int min = Integer.MAX_VALUE;
            for (int i = 0; i < 4; ++i) {
                for (int j = i+1; j < 4; ++j) {
                    boolean ar[] = new boolean[4];
                    ar[i] = true;
                    ar[j] = true;
                    int res = 0;
                    for (int k = 0; k < 4; ++k) {
                        if (ar[k]) {
                            res += mapA[k];
                        } else {
                            res += mapB[k];
                        }
                    }
                    min = Math.min(min, res);
                }
            }

        /*min = Math.min(min , mapA[0]+mapA[1]+mapB[2]+mapB[3]);
        min = Math.min(min , mapA[0]+mapA[2]+mapB[1]+mapB[3]);
        min = Math.min(min , mapA[0]+mapA[3]+mapB[1]+mapB[2]);
        min = Math.min(min , mapA[1]+mapA[2]+mapB[0]+mapB[3]);
        min = Math.min(min , mapA[1]+mapA[3]+mapB[0]+mapB[2]);
        min = Math.min(min , mapA[2]+mapA[3]+mapB[0]+mapB[1]);*/

            System.out.println(min);
        }
    }
}
