You have a grid with n rows and n columns. Each cell is either empty (denoted by '.') or blocked (denoted by 'X').

Two empty cells are directly connected if they share a side. Two cells (r1, c1) (located in the row r1 and column c1) and (r2, c2) are connected if there exists a sequence of empty cells that starts with (r1, c1), finishes with (r2, c2), and any two consecutive cells in this sequence are directly connected. A connected component is a set of empty cells such that any two cells in the component are connected, and there is no cell in this set that is connected to some cell not in this set.

Your friend Limak is a big grizzly bear. He is able to destroy any obstacles in some range. More precisely, you can choose a square of size k × k in the grid and Limak will transform all blocked cells there to empty ones. However, you can ask Limak to help only once.

The chosen square must be completely inside the grid. It's possible that Limak won't change anything because all cells are empty anyway.

You like big connected components. After Limak helps you, what is the maximum possible size of the biggest connected component in the grid?

Input

The first line of the input contains two integers n and k (1 ≤ k ≤ n ≤ 500) — the size of the grid and Limak's range, respectively.

Each of the next n lines contains a string with n characters, denoting the i-th row of the grid. Each character is '.' or 'X', denoting an empty cell or a blocked one, respectively.

Output

Print the maximum possible size (the number of cells) of the biggest connected component, after using Limak's help.

Examples

Input

5 2
..XXX
XX.XX
X.XXX
X...X
XXXX.


Output

10


Input

5 3
.....
.XXX.
.XXX.
.XXX.
.....


Output

25

Note

In the first sample, you can choose a square of size 2 × 2. It's optimal to choose a square in the red frame on the left drawing below. Then, you will get a connected component with 10 cells, marked blue in the right drawing.

<image>
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
import java.util.StringTokenizer;

public class ProblemC {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		FastScanner input = new FastScanner();
		int n = input.nextInt();
		int limak = input.nextInt();
		int limakFoot = limak * limak;
		char[][] in = new char[n][n];
		for (int a = 0; a < n; a++) {
			in[a] = input.next().toCharArray();
		}
		// Our graph is implicit, so we don't actually need to store the graph.

		// First, we need to do connected components.
		int[][] componentId = new int[n][n];
		for (int a = 0; a < n; a++) {
			for (int b = 0; b < n; b++) {
				componentId[a][b] = -1;
			}
		}
		ArrayList<Integer> componentSizes = new ArrayList<Integer>();
		int component = 0;
		for (int a = 0; a < n; a++) {
			for (int b = 0; b < n; b++) {
				int num = bfs(a, b, in, componentId, component);
				if (num > 0) {
					component++;
					componentSizes.add(num);
				}
			}
		}
		// now we built our connected components
		// we are going to try every single possible bear location. We need to
		// be able to see how large of a connected component such a bear would
		// create.
		// n^3 is OK, n^4 is not. Therefore, we can do operations around the
		// perimiter of each possible spot, but not the area. My initial plan is
		// to go around the grid, and see what components are going inside.
		// Then, take the sum of those components (O(n)), and then do prefix
		// sums to get the number of 'wall' squares inside the grid. (O(n)).
		// Unfortunately, this doesn't handle if there is a connected component
		// entirely hidden under the bear's foot.
		// Could we do dynamic programming? When we start, we could have a
		// hashmap of what is under the foot, and then add/remove such things as
		// we 'move' the foot. This would be O(n) for each move, O(n) to count
		// the components, but it would be O(n^2) on the starting point.
		int bestAnswer = limak * limak;
		for (int a = 0; a < n - limak + 1; a++) {
			// these are all the starting 'x' coordinates
			int b = 0;
			BearFoot foot = startBear(a, b, limak, componentId, componentSizes);
			// startBear calculates what is under the bear's foot.
			for (; b < n - limak + 1; b++) {
//				System.out.println("(" + a + ", " + b + ") " + foot);
				int answer = bearWithMe(foot);
				if (answer > bestAnswer) {
					bestAnswer = answer;
				}
				if (b != n - limak) {
					moveBear(foot, a, b, limak, componentId, componentSizes);
				}
			}
		}
		System.out.println(bestAnswer);
	}

	private static void moveBear(BearFoot foot, int a, int b, int limak,
			int[][] componentId, ArrayList<Integer> componentSizes) {
		// TODO Auto-generated method stub
		for (int c = 0; c < limak; c++) {
			if (componentId[a + c][b] < 0) {
				foot.footStomp--;
			}
		}
		for (int c = 0; c < limak; c++) {
			try {
				if (componentId[a + c][b - 1] >= 0) {
					foot.componentFreq[componentId[a + c][b - 1]]--;
					if (foot.componentFreq[componentId[a + c][b - 1]] == 0) {
						foot.componentSum -= componentSizes.get(componentId[a
								+ c][b - 1]);
					}
				}
			} catch (Exception e) {

			}
		}
		try {
			if (componentId[a - 1][b] >= 0) {
				foot.componentFreq[componentId[a - 1][b]]--;
				if (foot.componentFreq[componentId[a -1][b]] == 0) {
					foot.componentSum -= componentSizes.get(componentId[a-1][b]);
				}
			}
		} catch (Exception e) {

		}
		try {
			if (componentId[a + limak][b] >= 0) {
				foot.componentFreq[componentId[a + limak][b]]--;
				if (foot.componentFreq[componentId[a + limak][b]] == 0) {
					foot.componentSum -= componentSizes.get(componentId[a+ limak][b]);
				}
			}
		} catch (Exception e) {

		}
		
		
		for (int c = 0; c < limak; c++) {
			if (componentId[a + c][b + limak] < 0) {
				foot.footStomp++;
			}
		}
		for (int c = 0; c < limak; c++) {
			try {
				if (componentId[a + c][b + limak + 1] >= 0) {
					foot.componentFreq[componentId[a + c][b + limak + 1]]++;
					if (foot.componentFreq[componentId[a + c][b + limak + 1]] == 1) {
						foot.componentSum += componentSizes.get(componentId[a
								+ c][b + limak + 1]);
					}
				}
			} catch (Exception e) {

			}
		}
		try {
			if (componentId[a - 1][b + limak] >= 0) {
				foot.componentFreq[componentId[a - 1][b + limak]]++;
				if (foot.componentFreq[componentId[a -1][b + limak]] == 1) {
					foot.componentSum += componentSizes.get(componentId[a-1][b + limak]);
				}
			}
		} catch (Exception e) {

		}
		try {
			if (componentId[a + limak][b + limak] >= 0) {
				foot.componentFreq[componentId[a + limak][b + limak]]++;
				if (foot.componentFreq[componentId[a + limak][b + limak]] == 1) {
					foot.componentSum += componentSizes.get(componentId[a+ limak][b + limak]);
				}
			}
		} catch (Exception e) {

		}
	}

	private static int bearWithMe(BearFoot foot) {
		// TODO Auto-generated method stub
		return foot.componentSum + foot.footStomp;
	}

	private static BearFoot startBear(int a, int b, int limak,
			int[][] componentId, ArrayList<Integer> componentSizes) {
		// TODO Auto-generated method stub
		int[] componentFreq = new int[componentSizes.size()];
		int footStomp = 0;
		for (int aS = a; aS < a + limak; aS++) {
			for (int bS = b; bS < b + limak; bS++) {
				if (componentId[aS][bS] < 0) {
					footStomp++;
				}
			}
		}
		for (int aS = a - 1; aS < a + limak + 1; aS++) {
			for (int bS = b - 1; bS < b + limak + 1; bS++) {
				boolean aIsBound = aS == a - 1 || aS == a + limak;
				boolean bIsBound = bS == b - 1 || bS == b + limak;
				if (aIsBound && bIsBound) {

				} else {
					try {
						if (componentId[aS][bS] >= 0) {
							componentFreq[componentId[aS][bS]]++;
						}
					} catch (Exception e) {

					}
				}
			}
		}
		int componentSum = 0;
		for (int c = 0; c < componentFreq.length; c++) {
			if (componentFreq[c] > 0) {
				componentSum += componentSizes.get(c);
			}
		}

		return new BearFoot(componentSum, footStomp, componentFreq);
	}

	public static class BearFoot {
		int componentSum;
		int footStomp;
		int[] componentFreq;

		public BearFoot(int _componentSum, int _footStomp, int[] _componentFreq) {
			componentSum = _componentSum;
			footStomp = _footStomp;
			componentFreq = _componentFreq;
		}

		public String toString() {
			return componentSum + " " + footStomp + " "
					+ Arrays.toString(componentFreq);
		}
	}

	private static int bfs(int a, int b, char[][] in, int[][] componentId,
			int component) {
		if (illegalBound(a, b, in) || in[a][b] == 'X'
				|| componentId[a][b] != -1) {
			return 0;
		}
		componentId[a][b] = component;
		int up = bfs(a - 1, b, in, componentId, component);
		int down = bfs(a + 1, b, in, componentId, component);
		int right = bfs(a, b + 1, in, componentId, component);
		int left = bfs(a, b - 1, in, componentId, component);
		return up + down + right + left + 1;
	}

	private static boolean illegalBound(int a, int b, char[][] in) {
		return a < 0 || a >= in.length || b < 0 || b >= in[0].length;
	}

	public static class Point {
		int x;
		int y;

		public Point(int _x, int _y) {
			x = _x;
			y = _y;
		}
	}

	// FASTSCANNER2016
	public static class FastScanner {
		BufferedReader br;
		StringTokenizer st;

		public FastScanner(Reader in) {
			br = new BufferedReader(in);
		}

		public FastScanner() {
			this(new InputStreamReader(System.in));
		}

		String next() {
			while (st == null || !st.hasMoreElements()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

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

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

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

		// Slightly different from java.util.Scanner.nextLine(),
		// which returns any remaining characters in current line,
		// if any.
		String readNextLine() {
			String str = "";
			try {
				str = br.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return str;
		}
	}
}
