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.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Scanner;
import java.util.StringTokenizer;

public class C {
	
	public static void main(String[] args) {
		try (final Scanner sc = new Scanner(System.in)) {
			final int n = sc.nextInt();
			
			final int SIZE = 4;
			int[][][] board = new int[SIZE][n][n];
			for(int k = 0; k < SIZE; k++){
				for(int i = 0; i < n; i++){
					final char[] chs = sc.next().toCharArray();
					for(int j = 0; j < n; j++){
						board[k][i][j] = chs[j] - '0';
					}
				}
			}
			
			
			long[] b_f = new long[SIZE];
			long[] w_f = new long[SIZE];
			for(int k = 0; k < SIZE; k++){
				for(int i = 0; i < n; i++){
					for(int j = 0; j < n; j++){
						final int w = (i + j) % 2;
						final int b = 1 - w;
						
						b_f[k] += board[k][i][j] == b ? 0 : 1;
						w_f[k] += board[k][i][j] == w ? 0 : 1;
					}
				}
			}
			final long b_all = Arrays.stream(b_f).sum();
			final long w_all = Arrays.stream(w_f).sum();
			
			//System.out.println(Arrays.toString(b_f));
			
			long min = Long.MAX_VALUE;
			for(int fst = 0; fst < SIZE; fst++){
				for(int snd = fst + 1; snd < SIZE; snd++){
					
					min = Math.min(min, (b_f[fst] + b_f[snd]) + (w_all - w_f[fst] - w_f[snd]));
					min = Math.min(min, (w_f[fst] + w_f[snd]) + (b_all - b_f[fst] - b_f[snd]));
				}
			}
			
			System.out.println(min);
		}
	}
	
	public static class Scanner implements Closeable {
		private BufferedReader br;
		private StringTokenizer tok;

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

		private void getLine() {
			try {
				while (!hasNext()) {
					tok = new StringTokenizer(br.readLine());
				}
			} catch (IOException e) { /* ignore */
			}
		}

		private boolean hasNext() {
			return tok != null && tok.hasMoreTokens();
		}

		public String next() {
			getLine();
			return tok.nextToken();
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}
		
		public long nextLong() {
			return Long.parseLong(next());
		}

		public void close() {
			try {
				br.close();
			} catch (IOException e) { /* ignore */
			}
		}
	}
}
