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.util.ArrayList;
import java.util.HashSet;
import java.util.StringTokenizer;

public class Main {
	private static int N;
	private static int[][] standard1, standard2, board;
	private static ArrayList<int[]> permutations = new ArrayList<int[]>();
	private static int[][][] pieces;

	public static void main(String[] args) throws IOException {
		BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(f.readLine());
		N = Integer.parseInt(st.nextToken());
		standard1 = new int[2 * N][2 * N];
		standard2 = new int[2 * N][2 * N];
		pieces = new int[4][N][N];
		for (int i = 0; i < 2 * N; i++) {
			for (int k = 0; k < 2 * N; k++) {
				if (i % 2 == 0) {
					if (k % 2 == 0) {
						standard1[i][k] = 0;
						standard2[i][k] = 1;
					} else {
						standard1[i][k] = 1;
						standard2[i][k] = 0;
					}
				} else {
					if (k % 2 == 0) {
						standard1[i][k] = 1;
						standard2[i][k] = 0;
					} else {
						standard1[i][k] = 0;
						standard2[i][k] = 1;
					}
				}
			}
		}
		generate(new int[4], 0);
		for (int k = 0; k < 4; k++) {
			for (int i = 0; i < N; i++) {
				String str = f.readLine();
				for (int j = 0; j < N; j++) {
					pieces[k][i][j] = Integer.parseInt(str.substring(j, j + 1));
				}
			}
			if (k != 3) {
				f.readLine();
			}
		}
		int res = Integer.MAX_VALUE;
		for (int[] array : permutations) {
			createBoard(array);
			res = Math.min(res, check());
		}
		System.out.println(res);
	}

	public static void createBoard(int[] array) {
		board = new int[2 * N][2 * N];
		int[][] b0 = pieces[array[0]];
		int[][] b1 = pieces[array[1]];
		int[][] b2 = pieces[array[2]];
		int[][] b3 = pieces[array[3]];
		for (int i = 0; i < N; i++) {
			for (int k = 0; k < N; k++) {
				board[i][k] = b0[i][k];
				board[i][k + N] = b1[i][k];
				board[i + N][k] = b2[i][k];
				board[i + N][k + N] = b3[i][k];
			}
		}
	}

	public static int check() {
		int res1 = 0;
		int res2 = 0;
		for (int i = 0; i < 2 * N; i++) {
			for (int k = 0; k < 2 * N; k++) {
				if (board[i][k] != standard1[i][k]) {
					res1++;
				}
				if (board[i][k] != standard2[i][k]) {
					res2++;
				}
			}
		}
		return Math.min(res1, res2);
	}

	public static void generate(int[] array, int index) {
		if (index == 4) {
			int[] copy = array.clone();
			HashSet<Integer> set = new HashSet<Integer>();
			for (int i : copy)
				set.add(i);
			if (set.size() < 4)
				return;
			permutations.add(copy);
			return;
		}
		for (int i = 0; i < 4; i++) {
			array[index] = i;
			generate(array, index + 1);
		}
	}
}