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.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class C {

	public static void main(String[] args){
		FastScanner scan = new FastScanner();	
		PrintWriter out = new PrintWriter(System.out);
		n = scan.nextInt();
		pieces = new char[4][n][n];
		for(int i = 0; i < 4; i++) {
			pieces[i] = scan.nextGrid(n, n);
			if(i < 3) scan.nextLine();
		}
		res = 0x3f3f3f3f;
		go(0, new int[4], new boolean[4]);
		out.println(res);
		out.close();
	}
	
	static int n, res;
	static char[][][] pieces;
	
	static void go(int k, int[] perm, boolean[] u) {
		if(k == 4) {
//			boolean f = Arrays.toString(perm).equals("[0, 3, 2, 1]");
			int w = 0, b = 0, t = 0;
			for(int i = 0; i < n; i++) {
				for(int j = 0; j < n; j++, t ^= 1) {
					if(t == 0 && i%2 == 0 || t == 1 && i%2 == 1) {
						if(pieces[perm[0]][i][j] == '0') w++;
						if(pieces[perm[0]][i][j] == '1') b++;
					} else {
						if(pieces[perm[0]][i][j] == '0') b++;
						if(pieces[perm[0]][i][j] == '1') w++;
					}
				}
				for(int j = 0; j < n; j++, t ^= 1) {
//					if(f) System.out.println(pieces[perm[1]][i][j]);
					if(t == 0 && i%2 == 0 || t == 1 && i%2 == 1) {
						if(pieces[perm[1]][i][j] == '0') w++;
						if(pieces[perm[1]][i][j] == '1') b++;
					} else {
						if(pieces[perm[1]][i][j] == '0') b++;
						if(pieces[perm[1]][i][j] == '1') w++;
					}
				}
			}
			for(int i = 0; i < n; i++) {
				for(int j = 0; j < n; j++, t ^= 1) {
//					if(f) System.out.println(pieces[perm[2]][i][j]);
					if(t == 0 && i%2 == 0 || t == 1 && i%2 == 1) {
						if(pieces[perm[2]][i][j] == '0') w++;
						if(pieces[perm[2]][i][j] == '1') b++;
					} else {
						if(pieces[perm[2]][i][j] == '0') b++;
						if(pieces[perm[2]][i][j] == '1') w++;
					}
				}
				for(int j = 0; j < n; j++, t ^= 1) {
//					if(f) System.out.println(pieces[perm[3]][i][j]);
					if(t == 0 && i%2 == 0 || t == 1 && i%2 == 1) {
						if(pieces[perm[3]][i][j] == '0') w++;
						if(pieces[perm[3]][i][j] == '1') b++;
					} else {
						if(pieces[perm[3]][i][j] == '0') b++;
						if(pieces[perm[3]][i][j] == '1') w++;
					}
				}
			}
//			System.out.println(Arrays.toString(perm));
//			System.out.println(b+" "+w);
			res = Math.min(res, w);
			res = Math.min(res, b);
		}
		for(int i = 0; i < 4; i++) if(!u[i]){
			u[i] = true;
			perm[k] = i;
			go(k+1, perm, u);
			u[i] = false;
		}
	}

	static class FastScanner {
		BufferedReader br;
		StringTokenizer st;

		public FastScanner() {
			try	{
				br = new BufferedReader(new InputStreamReader(System.in));
				st = new StringTokenizer(br.readLine());
			} catch (Exception e){e.printStackTrace();}
		}

		public String next() {
			if (st.hasMoreTokens())	return st.nextToken();
			try {st = new StringTokenizer(br.readLine());}
			catch (Exception e) {e.printStackTrace();}
			return st.nextToken();
		}

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

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

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

		public String nextLine() {
			String line = "";
			if(st.hasMoreTokens()) line = st.nextToken();
			else try {return br.readLine();}catch(IOException e){e.printStackTrace();}
			while(st.hasMoreTokens()) line += " "+st.nextToken();
			return line;
		}

		public int[] nextIntArray(int n) {
			int[] a = new int[n];
			for(int i = 0; i < n; i++) a[i] = nextInt();
			return a;
		}

		public long[] nextLongArray(int n){
			long[] a = new long[n];
			for(int i = 0; i < n; i++) a[i] = nextLong();
			return a;
		}

		public double[] nextDoubleArray(int n){
			double[] a = new double[n];
			for(int i = 0; i < n; i++) a[i] = nextDouble();
			return a;
		}

		public char[][] nextGrid(int n, int m){
			char[][] grid = new char[n][m];
			for(int i = 0; i < n; i++) grid[i] = next().toCharArray();
			return grid;
		}
	}


}