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
//package com.company;

import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class Main {
    static long TIME_START, TIME_END;
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
//        Scanner sc = new Scanner(new FileInputStream("Test.in"));
        PrintWriter pw = new PrintWriter(System.out);
//        PrintWriter pw = new PrintWriter(new FileOutputStream("Test.out"));
//        PrintWriter pw = new PrintWriter(new FileOutputStream("Test.in"));

        Runtime runtime = Runtime.getRuntime();
        long usedMemoryBefore = runtime.totalMemory() - runtime.freeMemory();
        TIME_START = System.currentTimeMillis();
        Task t = new Task();
        t.solve(sc, pw);
        TIME_END = System.currentTimeMillis();
        long usedMemoryAfter = runtime.totalMemory() - runtime.freeMemory();
        pw.close();
//        System.out.println("Memory increased:" + (usedMemoryAfter-usedMemoryBefore) / 1000000 );
//        System.out.println("Time used: " + (TIME_END - TIME_START) + ".");

    }

    public static class Task {


        public void solve(Scanner sc, PrintWriter pw) throws IOException {
            int n = sc.nextInt();
            int[][] a = new int[n][n];
            int[][] b = new int[n][n];
            int[][] c = new int[n][n];
            int[][] d = new int[n][n];
            fill(a, n, sc);
            fill(b, n, sc);
            fill(c, n, sc);
            fill(d, n, sc);

            int s = Integer.MAX_VALUE;
            s = Math.min(s, sp1(a, b, c, d, n));
            s = Math.min(s, sp1(b, a, c, d, n));
            s = Math.min(s, sp1(c, b, a, d, n));
            s = Math.min(s, sp1(d, b, c, a, n));

            pw.println(s);
        }
        public void fill(int[][] a, int n, Scanner sc) throws IOException {
            for (int i = 0; i < n; i++) {
                String s = sc.next();
                for (int j = 0; j < n; j++) {
                    a[i][j] = s.charAt(j) - '0';
                }
            }
        }

        public int sp1(int[][] a, int[][] b, int[][] c, int[][] d, int n) {
            int[] t1 = new int[6];
            t1[0] = so(a, b, c, d, n);
            t1[1] = so(a, b, d, c, n);
            t1[2] = so(a, c, b, d, n);
            t1[3] = so(a, c, d, b, n);
            t1[4] = so(a, d, b, c, n);
            t1[5] = so(a, d, c, b, n);
            int m = Integer.MAX_VALUE;
            for (int i = 0; i < 6; i++) {
                m = Math.min(m, t1[i]);
            }
            return m;
        }
        public int so(int[][] a, int[][] b, int[][] c, int[][] d, int n) {
            return need(formboard(a, b, c, d, n));
        }
        public int[][] formboard(int[][] a, int[][] b, int[][] c, int[][] d, int n){
            int[][] g = new int[2 * n][2 * n];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    g[i][j] = a[i][j];
                }
            }
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    g[i + n][j] = b[i][j];
                }
            }
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    g[i][j + n] = c[i][j];
                }
            }
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    g[i + n][j + n] = d[i][j];
                }
            }
            return g;
        }
        public int need(int[][] g) {
            int p1 = 0, p2 = 0;
            for (int i = 0; i < g.length; i++) {
                for (int j = 0; j < g.length; j++) {
                    if (g[i][j] == (i + j) % 2) {
                        p1 ++;
                    } else {
                        p2 ++;
                    }
                }
            }
            return Math.min(p1, p2);
        }




    }

    static class Scanner {
        StringTokenizer st;
        BufferedReader br;

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

        public Scanner(FileReader s) throws FileNotFoundException {br = new BufferedReader(s);}

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

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

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

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

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

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