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

public class C {

	public static void main(String[] args) {
		FastScanner fs=new FastScanner();
		int n=fs.nextInt();
		int[] counts=new int[4];
		for (int b=0; b<4; b++) {
			int count=0;
			for (int y=0; y<n; y++) {
				String line=fs.next();
				for (int x=0; x<n; x++) {
					boolean white=(x+y)%2==0;
					boolean isW=line.charAt(x)=='0';
					if (white^isW)
						count++;
				}
			}
			counts[b]=count;
		}
		Arrays.sort(counts);
		long min=counts[0]+counts[1]+n*n+n*n-counts[2]-counts[3];
//		System.out.println(Arrays.toString(counts));
		System.out.println(min);
	}
	
	
	static class Rect {
		int x1, x2, y1, y2;
		public Rect(int x1, int y1, int x2, int y2) {
			this.x1=x1;
			this.x2=x2;
			this.y1=y1;
			this.y2=y2;
		}
		
		public Rect union(Rect o) {
			return new Rect(Math.max(x1, o.x1), Math.max(y1, o.y1), Math.min(x2, o.x2), Math.min(y2, o.y2));
		}
		
		public boolean valid() {
			return x1<=x2&&y1<=y2;
		}
	}
	
	static class Song implements Comparable<Song> {
		long uncompressed, compressed;
		public Song(long uncompressed, long compressed) {
			this.uncompressed=uncompressed;
			this.compressed=compressed;
		}
		
		public int compareTo(Song o) {
			long diff=(uncompressed-compressed);
			long oDiff=o.uncompressed-o.compressed;
			return Long.compare(oDiff, diff);
		}
	}
	
	static double eval(int first, int second) {
		return (first*(double)first+second*second)/(first*second);
	}
	
	static class FastScanner {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st=new StringTokenizer("");
		
		public String next() {
			while (!st.hasMoreElements())
				try {
					st=new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			return st.nextToken();
		}
		
		public int nextInt() {
			return Integer.parseInt(next());
		}
		
		public long nextLong() {
			return Long.parseLong(next());
		}
		
		public int[] readArray(int n) {
			int[] a=new int[n];
			for (int i=0; i<n; i++) {
				a[i]=nextInt();
			}
			return a;
		}
		
		public double nextDouble() {
			return Double.parseDouble(next());
		}
		
	}

}
