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.util.*;
import java.lang.*;
import java.math.*;
import java.io.*;
import java.util.HashSet;
import java.util.Arrays; 
import java.util.Scanner;
import java.util.Set;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.text.DecimalFormat;
import java.lang.Math;
import java.util.Iterator; 
import java.util.TreeSet;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.util.*;
public class C1343{
	public static PrintWriter out = new PrintWriter (new BufferedOutputStream(System.out));
	static long MOD = (long)(1e9+7);
	static FastReader sc = new FastReader();
	static int pInf = Integer.MAX_VALUE;
	static int nInf = Integer.MIN_VALUE;
	public static void main(String[] args) {
		int t = 1;
		int n = sc.nextInt();
		if(n>1){
	//	    int n = sc.nextInt();
		    char[][][] a = new char[4][n][n];
	//	    char[][] a2 = new char[n][n];
	//	    char[][] a3 = new char[n][n];
	//	    char[][] a4 = new char[n][n];
		    char[][] t1 = new char[n][n];
		    char[][] t2 = new char[n][n];
		    StringBuffer s1 = new StringBuffer("");
		    StringBuffer s2 = new StringBuffer("");
		    for(int i = 0; i < n; i++){
		        if((i&1)==0){
		            s1.append('1');
		            s2.append('0');
		        }
		        else{
		            s1.append('0');
		            s2.append('1');
		        }
		    }
		    for(int i = 0; i < n; i++){
		        if((i&1)==0){
		            t1[i] = s1.toString().toCharArray();
		            t2[i] = s2.toString().toCharArray();
		        }
		        else{
		            t1[i] = s2.toString().toCharArray();
		            t2[i] = s1.toString().toCharArray();
		        }
		    }
		    int[][] score = new int[2][4];
		    for(int g = 0; g < 4; g++){
		        for(int i = 0; i < n; i++){
		            String s;
		            if(i==n-1){
		                s = sc.nextLine();
		            }
		            else{
		                s = sc.next();
		            }
    		        for(int j = 0; j < n; j++){
    		            a[g][i][j] = s.charAt(j);
    		            if(a[g][i][j]!=t1[i][j]){
    		                score[0][g]++;
    		            }
    		            if(a[g][i][j]!=t2[i][j]){
    		                score[1][g]++;
    		            }
    		        }
    		    }
		    }
		    long ans = 0;
		    for(int i = 0; i < 2; i++){
		        Arrays.sort(score[i]);
		        for(int j = 0; j < 2; j++){
		            ans += score[i][j];
		        }
		    }
		    out.println(ans);
	/*	    for(int i = 0; i < n; i++){
		        for(int j = 0; j < n; j++){
		            out.print(t1[i][j]+" ");
		        }
		        out.println();
		    }
		    out.println();
		    for(int i = 0; i < n; i++){
		        for(int j = 0; j < n; j++){
		            out.print(t2[i][j]+" ");
		        }
		        out.println();
		    }*/
		}
		else{
		    String s1 = sc.next();
		    String s2 = sc.next();
		    String s3 = sc.next();
		    String s4 = sc.next();
		    int c1 = 0;
		    if(s1.equals("1")){
		        c1++;
		    }
		    if(s2.equals("1")){
		        c1++;
		    }
		    if(s3.equals("1")){
		        c1++;
		    }
		    if(s4.equals("1")){
		        c1++;
		    }
		    //out.println(c1);
		    if(c1==0|| c1==4){
		        out.println(2);
		    }
		    else if(c1==1 || c1==3){
		        out.println(1);
		    }
		    else if(c1==2){
		        out.println(0);
		    }
		}
		out.close();
	}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Merge Sort
	static void merge(long arr[], int l, int m, int r)
    {
        // Find sizes of two subarrays to be merged
        int n1 = m - l + 1;
        int n2 = r - m;
 
        /* Create temp arrays */
        long L[] = new long [n1];
        long R[] = new long [n2];
 
        /*Copy data to temp arrays*/
        for (int i=0; i<n1; ++i)
            L[i] = arr[l + i];
        for (int j=0; j<n2; ++j)
            R[j] = arr[m + 1+ j];
 
 
        /* Merge the temp arrays */
 
        // Initial indexes of first and second subarrays
        int i = 0, j = 0;
 
        // Initial index of merged subarry array
        int k = l;
        while (i < n1 && j < n2)
        {
            if (L[i] <= R[j])
            {
                arr[k] = L[i];
                i++;
            }
            else
            {
                arr[k] = R[j];
                j++;
            }
            k++;
        }
 
        /* Copy remaining elements of L[] if any */
        while (i < n1)
        {
            arr[k] = L[i];
            i++;
            k++;
        }
 
        /* Copy remaining elements of R[] if any */
        while (j < n2)
        {
            arr[k] = R[j];
            j++;
            k++;
        }
    }
 
    // Main function that sorts arr[l..r] using
    // merge()
    static void sort(long arr[], int l, int r)
    {
        if (l < r)
        {
            // Find the middle point
            int m = (l+r)/2;
 
            // Sort first and second halves
            sort(arr, l, m);
            sort(arr , m+1, r);
 
            // Merge the sorted halves
            merge(arr, l, m, r);
        }
    }
	static class Pair implements Comparable<Pair>{
		int x;
		int y;
		public Pair(int x, int y) {
			this.x = x;
			this.y = y;
		}
		@Override
		public int compareTo(Pair o) {
			// TODO Auto-generated method stub
			if(this.x==o.x){
			    return (this.y-o.y);
			}
			return (this.x-o.x);
		}
	}
//Brian Kernighan’s Algorithm
    static long countSetBits(long n){
        if(n==0) return 0;
        return 1+countSetBits(n&(n-1));
    }
//Factorial
    static long factorial(long n){
        if(n==1) return 1;
        if(n==2) return 2;
        if(n==3) return 6;
        return n*factorial(n-1);
    }
//Euclidean Algorithm
    static long gcd(long A,long B){
        if(B==0) return A;
        return gcd(B,A%B);
    }
//Modular Exponentiation
    static long fastExpo(long x,long n){
        if(n==0) return 1;
        if((n&1)==0) return fastExpo((x*x)%MOD,n/2)%MOD;
        return ((x%MOD)*fastExpo((x*x)%MOD,(n-1)/2))%MOD;
    }
//AKS Algorithm
    static boolean isPrime(long n){
        if(n<=1) return false;
        if(n<=3) return true;
        if(n%2==0 || n%3==0) return false;
        for(int i=5;i*i<=n;i+=6)
            if(n%i==0 || n%(i+2)==0) return false;
        return true;
    }
//Sieve of eratosthenes
    static int[] findPrimes(int n){
        boolean isPrime[]=new boolean[n+1];
        ArrayList<Integer> a=new ArrayList<>();
        int result[];
        Arrays.fill(isPrime,true);
        isPrime[0]=false;
        isPrime[1]=false;
        for(int i=2;i*i<=n;++i){
            if(isPrime[i]==true){
                for(int j=i*i;j<=n;j+=i) isPrime[j]=false;
            }
        }
        for(int i=0;i<=n;i++) if(isPrime[i]==true) a.add(i);
        result=new int[a.size()];
        for(int i=0;i<a.size();i++) result[i]=a.get(i);
        return result;
        
    }
//Euler Totent function
    static long countCoprimes(long n){
        ArrayList<Long> prime_factors=new ArrayList<>();
        long x=n,flag=0;
        while(x%2==0){
            if(flag==0) prime_factors.add(2L);
            flag=1;
            x/=2;
        }
        for(long i=3;i*i<=x;i+=2){
            flag=0;
            while(x%i==0){
                if(flag==0) prime_factors.add(i);
                flag=1;
                x/=i;
            }
        }
        if(x>2) prime_factors.add(x);
        double ans=(double)n;
        for(Long p:prime_factors){
            ans*=(1.0-(Double)1.0/p);
        }
        return (long)ans;
    }
	public static int bSearch(int n,ArrayList<Integer> A){
	    int s = 0;
	    int e = A.size()-1;
	    while(s<=e){
	        int m = s+(e-s)/2;
	        if(A.get(m)==(long)n){
	            return A.get(m);
	        }
	        else if(A.get(m)>(long)n){
	            e = m-1;
	        }
	        else{
	            s = m+1;
	        }
	    }
	    return A.get(e);
	}
	static long modulo = (long)1e9+7;
	public static long modinv(long x){
	    return modpow(x, modulo-2);
	}
	public static long modpow(long a, long b){
	    if(b==0){
	        return 1;
	    }
	    long x = modpow(a, b/2);
	    x = (x*x)%modulo;
	    if(b%2==1){
	        return (x*a)%modulo;
	    }
	    return x;
	}
	public static class FastReader {
		BufferedReader br;
		StringTokenizer st;
		//it reads the data about the specified point and divide the data about it ,it is quite fast
		//than using direct 

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

		String next() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception r) {
					r.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());//converts string to integer
		}

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

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

		String nextLine() {
			String str = "";
			try {
				str = br.readLine();
			} catch (Exception r) {
				r.printStackTrace();
			}
			return str;
		}
	}
}