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.FileInputStream;
// import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;

import static java.lang.Math.*;
import static java.util.Arrays.copyOf;
import static java.util.Arrays.fill;
import static java.util.Arrays.sort;
import static java.util.Map.Entry;
import static java.util.Collections.reverseOrder;
import static java.util.Collections.sort;

public class Main {
    FastScanner in;
    PrintWriter out;
    int n;
    int[][][] a;
    int[][] b, c;

    private void solve() throws IOException {
        n = in.nextInt();
        a = new int[4][n][n];
        char[] s;
        for (int k = 0; k < 4; k++) {
            for (int i = 0; i < n; i++) {
                s = in.next().toCharArray();
                for (int j = 0; j < n; j++) {
                    a[k][i][j] = s[j] - '0';
                }
            }
        }

        b = new int[2 * n][2 * n];
        for (int i = 0; i < 2 * n; i++) {
            for (int j = 0; j < 2 * n; j++) {
                b[i][j] = (i % 2 + j % 2) % 2;
            }
        }
        c = new int[2 * n][2 * n];
        for (int i = 0; i < 2 * n; i++) {
            for (int j = 0; j < 2 * n; j++) {
                c[i][j] = (b[i][j] + 1) % 2;
            }
        }

        long min = Long.MAX_VALUE;
        min = min(min, cnt(0, 1, 2, 3));
        min = min(min, cnt(0, 1, 3, 2));
        min = min(min, cnt(0, 2, 1, 3));
        min = min(min, cnt(0, 2, 3, 1));
        min = min(min, cnt(0, 3, 1, 2));
        min = min(min, cnt(0, 3, 2, 1));

        min = min(min, cnt(1, 0, 2, 3));
        min = min(min, cnt(1, 0, 3, 2));
        min = min(min, cnt(1, 2, 0, 3));
        min = min(min, cnt(1, 2, 3, 0));
        min = min(min, cnt(1, 3, 0, 2));
        min = min(min, cnt(1, 3, 2, 0));

        min = min(min, cnt(2, 0, 1, 3));
        min = min(min, cnt(2, 0, 3, 1));
        min = min(min, cnt(2, 1, 0, 3));
        min = min(min, cnt(2, 1, 3, 0));
        min = min(min, cnt(2, 3, 0, 1));
        min = min(min, cnt(2, 3, 1, 0));

        min = min(min, cnt(3, 0, 1, 2));
        min = min(min, cnt(3, 0, 2, 1));
        min = min(min, cnt(3, 1, 0, 2));
        min = min(min, cnt(3, 1, 2, 0));
        min = min(min, cnt(3, 2, 0, 1));
        min = min(min, cnt(3, 2, 1, 0));
        out.print(min);
    }

    private long cnt(int lu, int ru, int ld, int rd) {
        int[][] d = new int[2 * n][2 * n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                d[i][j] = a[lu][i][j];
                d[i][j + n] = a[ru][i][j];
                d[i + n][j] = a[ld][i][j];
                d[i + n][j + n] = a[rd][i][j];
            }
        }

        return min(cmp(b, d), cmp(c, d));
    }

    private long cmp(int[][] a, int[][] b) {
        long cnt = 0;
        for (int i = 0; i < 2 * n; i++) {
            for (int j = 0; j < 2 * n; j++) {
                if (a[i][j] != b[i][j])
                    cnt++;
            }
        }
        return cnt;
    }

    class FastScanner {
        StringTokenizer st;
        BufferedReader br;

        FastScanner(InputStream s) {
            br = new BufferedReader(new InputStreamReader(s));
        }

        String next() throws IOException {
            while (st == null || !st.hasMoreTokens())
                st = new StringTokenizer(br.readLine());
            return st.nextToken();
        }

        boolean hasNext() throws IOException {
            return br.ready() || (st != null && st.hasMoreTokens());
        }

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

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

        double nextDouble() throws IOException {
            return Double.parseDouble(next().replace(',', '.'));
        }

        String nextLine() throws IOException {
            return br.readLine();
        }

        boolean hasNextLine() throws IOException {
            return br.ready();
        }
    }

    private void run() throws IOException {
        in = new FastScanner(System.in); // new FastScanner(new FileInputStream(".in"));
        out = new PrintWriter(System.out); // new PrintWriter(new FileOutputStream(".out"));

        solve();

        out.flush();
        out.close();
    }

    public static void main(String[] args) throws IOException {
        new Main().run();
    }
}
