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.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Solution {

	static InputReader in = new InputReader(System.in);
	static OutputWriter out = new OutputWriter(System.out);
	static int exp = (int) (1e9);

	private static int getSingleBoardChanges(char[][] board, int size, char first, char second) {

		int changes = 0;

		for (int i = 0; i < size; i++) {
			for (int j = 0; j < size; j++) {
				if (((i & 1) == 0 && (j & 1) == 0) || ((i & 1) == 1 && (j & 1) == 1)) {
					if (board[i][j] == first) {
						changes++;
					}
				} else if (board[i][j] == second) {
					changes++;
				}
			}
		}
		return changes;
	}

	private static Pair getChanges(char[][] board, int n) {
		return new Pair(getSingleBoardChanges(board, n, '1', '0'), getSingleBoardChanges(board, n, '0', '1'));
	}

	public static void main(String[] args) {

		Board[] boards = new Board[4];
		int n = in.nextInt();

		for (int i = 0; i < 4; i++) {
			char[][] mat = new char[n][n];
			for (int j = 0; j < n; j++) {
				mat[j] = in.readLine().toCharArray();
			}
			if (i < 3) {
				in.readLine();
			}
			boards[i] = new Board(mat);
		}

		Pair p0 = getChanges(boards[0].board, n);
		Pair p1 = getChanges(boards[1].board, n);
		Pair p2 = getChanges(boards[2].board, n);
		Pair p3 = getChanges(boards[3].board, n);

		int[] scores = new int[6];

		scores[0] = p0.white + p1.white + p2.black + p3.black;
		scores[1] = p0.white + p2.white + p1.black + p3.black;
		scores[2] = p0.white + p3.white + p1.black + p2.black;
		scores[3] = p1.white + p2.white + p0.black + p3.black;
		scores[4] = p1.white + p3.white + p0.black + p2.black;
		scores[5] = p2.white + p3.white + p0.black + p1.black;

		int res = Integer.MAX_VALUE;
		for (Integer v : scores) {
			res = Math.min(res, v);
		}

		System.out.println(res);

	}
}

class Board {

	char[][] board;

	Board(char[][] board) {
		this.board = board;
	}

	@Override
	public String toString() {
		return "Board [board=" + Arrays.deepToString(board) + "]";
	}
};

class Pair {
	int white;
	int black;

	public Pair(int white, int black) {
		super();
		this.white = white;
		this.black = black;
	}

	@Override
	public String toString() {
		return "Pair [white=" + white + ", black=" + black + "]";
	}
};

class OutputWriter {
	public PrintWriter writer;

	public OutputWriter(OutputStream outputStream) {
		writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
	}

	public OutputWriter(Writer writer) {
		this.writer = new PrintWriter(writer);
	}

	public void print(Object... objects) {
		for (int i = 0; i < objects.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(objects[i]);
		}
	}

	public void println(Object... objects) {
		print(objects);
		writer.println();
	}

	public void close() {
		writer.close();
	}
}

class InputReader {
	private BufferedReader reader;
	private StringTokenizer tokenizer;

	public InputReader(InputStream stream) {
		reader = new BufferedReader(new InputStreamReader(stream), 32768);
		tokenizer = null;
	}

	public String next() {
		while (tokenizer == null || !tokenizer.hasMoreTokens()) {
			try {
				tokenizer = new StringTokenizer(reader.readLine());
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
		return tokenizer.nextToken();
	}

	public String readLine() {
		try {
			return reader.readLine();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	public char nextChar() {
		return next().charAt(0);
	}

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

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

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

	public float nextFloat() {
		return Float.parseFloat(next());
	}

}