A monopole magnet is a magnet that only has one pole, either north or south. They don't actually exist since real magnets have two poles, but this is a programming contest problem, so we don't care.

There is an n× m grid. Initially, you may place some north magnets and some south magnets into the cells. You are allowed to place as many magnets as you like, even multiple in the same cell.

An operation is performed as follows. Choose a north magnet and a south magnet to activate. If they are in the same row or the same column and they occupy different cells, then the north magnet moves one unit closer to the south magnet. Otherwise, if they occupy the same cell or do not share a row or column, then nothing changes. Note that the south magnets are immovable.

Each cell of the grid is colored black or white. Let's consider ways to place magnets in the cells so that the following conditions are met.

  1. There is at least one south magnet in every row and every column. 
  2. If a cell is colored black, then it is possible for a north magnet to occupy this cell after some sequence of operations from the initial placement. 
  3. If a cell is colored white, then it is impossible for a north magnet to occupy this cell after some sequence of operations from the initial placement. 



Determine if it is possible to place magnets such that these conditions are met. If it is possible, find the minimum number of north magnets required (there are no requirements on the number of south magnets).

Input

The first line contains two integers n and m (1≤ n,m≤ 1000) — the number of rows and the number of columns, respectively.

The next n lines describe the coloring. The i-th of these lines contains a string of length m, where the j-th character denotes the color of the cell in row i and column j. The characters "#" and "." represent black and white, respectively. It is guaranteed, that the string will not contain any other characters.

Output

Output a single integer, the minimum possible number of north magnets required.

If there is no placement of magnets that satisfies all conditions, print a single integer -1.

Examples

Input


3 3
.#.
###
##.


Output


1


Input


4 2
##
.#
.#
##


Output


-1


Input


4 5
....#
####.
.###.
.#...


Output


2


Input


2 1
.
#


Output


-1


Input


3 5
.....
.....
.....


Output


0

Note

In the first test, here is an example placement of magnets:

<image>

In the second test, we can show that no required placement of magnets exists. Here are three example placements that fail to meet the requirements. The first example violates rule 3 since we can move the north magnet down onto a white square. The second example violates rule 2 since we cannot move the north magnet to the bottom-left black square by any sequence of operations. The third example violates rule 1 since there is no south magnet in the first column.

<image>

In the third test, here is an example placement of magnets. We can show that there is no required placement of magnets with fewer north magnets.

<image>

In the fourth test, we can show that no required placement of magnets exists. Here are two example placements that fail to meet the requirements. The first example violates rule 1 since there is no south magnet in the first row. The second example violates rules 1 and 3 since there is no south magnet in the second row and we can move the north magnet up one unit onto a white square.

<image>

In the fifth test, we can put the south magnet in each cell and no north magnets. Because there are no black cells, it will be a correct placement.
import java.io.*;
import java.util.*;

public class B implements Runnable {
	boolean judge = false;
	FastReader scn;
	PrintWriter out;
	String INPUT = "";

	void solve() {
		int n = scn.nextInt(), m = scn.nextInt(), one = 0;
		int[][] arr = new int[n][m];
		for(int i = 0; i < n; i++) {
			String s = scn.next();
			for(int j = 0; j < m; j++) {
				if(s.charAt(j) == '#') {
					arr[i][j] = 1;
					one++;
				}
			}
		}
		
		if(n * m == 1 || one == 0) {
			out.println(one);
			return;
		}
		
		if(n == 1 || m == 1) {
			if(one == n * m) {
				out.println(1);
			} else {
				out.println(-1);
			}
			return;
		}
		
		boolean ok = true;
		boolean[] row = new boolean[n];
		for(int i = 0; i < n && ok; i++) {
			ArrayList<Integer> ls = new ArrayList<>();
			ls.add(arr[i][0]);
			boolean zero = arr[i][0] == 0;
			for(int j = 1; j < m; j++) {
				if(arr[i][j] != 0) {
					zero = false;
				}
				if(arr[i][j] != arr[i][j - 1]) {
					ls.add(arr[i][j]);
				}
			}
			row[i] = zero;
			if((ls.size() == 3 && ls.get(0) == 1) || ls.size() > 3) {
				ok = false;
			}
		}
		
		boolean[] col = new boolean[m];
		for(int i = 0; i < m && ok; i++) {
			ArrayList<Integer> ls = new ArrayList<>();
			ls.add(arr[0][i]);
			boolean zero = arr[0][i] == 0;
			for(int j = 1; j < n; j++) {
				if(arr[j][i] != 0) {
					zero = false;
				}
				if(arr[j][i] != arr[j - 1][i]) {
					ls.add(arr[j][i]);
				}
			}
			col[i] = zero;
			if((ls.size() == 3 && ls.get(0) == 1) || ls.size() > 3) {
				ok = false;
			}
		}
		
		HashSet<Integer> a = new HashSet<Integer>(), b = new HashSet<Integer>();
		for(int i = 0; i < n; i++) {
			for(int j = 0; j < m; j++) {
				if(arr[i][j] == 1 || (row[i] && col[j])) {
					a.add(i);
					b.add(j);
				}
			}
		}
		
		if(a.size() != n || b.size() != m) {
			ok = false;
		}
		
		if(!ok) {
			out.println(-1);
			return;
		}
		
		DisJointSet dj = new DisJointSet(n * m);
		
		for(int i = 0; i < n; i++) {
			for(int j = 0; j < m; j++) {
				int cur = m * i + j;
				if(i - 1 >= 0 && arr[i][j] == arr[i - 1][j]) {
					int nx = m * (i - 1) + j;
					dj.union(cur, nx);
				}
				if(j - 1 >= 0 && arr[i][j] == arr[i][j - 1]) {
					int nx = m * i + (j - 1);
					dj.union(cur, nx);
				}
			}
		}
		
		int ans = 0;
		HashSet<Integer> set = new HashSet<>();
		for(int i = 0; i < n; i++) {
			for(int j = 0; j < m; j++) {
				if(arr[i][j] == 1) {
					int cur = m * i + j, rt = dj.root(cur);
					if(!set.contains(rt)) {
						ans++;
					}
					set.add(rt);
				}
			}
		}
		out.println(ans);
	}
	
	class DisJointSet {
		int[] table, rank, count;
		int size;

		DisJointSet(int size) {
			this.table = new int[size];
			this.rank = new int[size];
			this.count = new int[size];
			this.size = size;
			for (int i = 0; i < size; i++) {
				this.table[i] = i;
				this.rank[i] = 1;
				this.count[i] = 1;
			}
		}

		boolean isSame(int x, int y) {
			return root(x) == root(y);
		}

		int root(int node) {
			if (table[node] == node) {
				return node;
			} else {
				return table[node] = root(table[node]);
			}
		}

		void union(int x, int y) {
			x = root(x);
			y = root(y);
			if (x != y)
				this.size--;
			if (rank[x] < rank[y]) {
				table[x] = y;
				count[y] += count[x];
			} else if (rank[x] > rank[y]) {
				table[y] = x;
				count[x] += count[y];
			} else if (x != y) {
				table[y] = x;
				count[x] += count[y];
				rank[x]++;
			}
		}
	}

	public void run() {
		long time = System.currentTimeMillis();
		boolean oj = System.getProperty("ONLINE_JUDGE") != null || judge;
		out = new PrintWriter(System.out);
		scn = new FastReader(oj);
		solve();
		out.flush();
		if (!oj) {
			System.out.println(Arrays.deepToString(new Object[] { System.currentTimeMillis() - time + " ms" }));
		}
	}

	public static void main(String[] args) {
		new Thread(null, new B(), "Main", 1 << 28).start();
	}

	class FastReader {
		InputStream is;

		public FastReader(boolean onlineJudge) {
			is = onlineJudge ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		}

		byte[] inbuf = new byte[1024];
		public int lenbuf = 0, ptrbuf = 0;

		int readByte() {
			if (lenbuf == -1)
				throw new InputMismatchException();
			if (ptrbuf >= lenbuf) {
				ptrbuf = 0;
				try {
					lenbuf = is.read(inbuf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (lenbuf <= 0)
					return -1;
			}
			return inbuf[ptrbuf++];
		}

		boolean isSpaceChar(int c) {
			return !(c >= 33 && c <= 126);
		}

		int skip() {
			int b;
			while ((b = readByte()) != -1 && isSpaceChar(b))
				;
			return b;
		}

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

		char nextChar() {
			return (char) skip();
		}

		String next() {
			int b = skip();
			StringBuilder sb = new StringBuilder();
			while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
				sb.appendCodePoint(b);
				b = readByte();
			}
			return sb.toString();
		}

		String nextLine() {
			int b = skip();
			StringBuilder sb = new StringBuilder();
			while ((!isSpaceChar(b) || b == ' ')) { // when nextLine, (isSpaceChar(b) && b != ' ')
				sb.appendCodePoint(b);
				b = readByte();
			}
			return sb.toString();
		}

		char[] next(int n) {
			char[] buf = new char[n];
			int b = skip(), p = 0;
			while (p < n && !(isSpaceChar(b))) {
				buf[p++] = (char) b;
				b = readByte();
			}
			return n == p ? buf : Arrays.copyOf(buf, p);
		}

		int nextInt() {
			int num = 0, b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-') {
				minus = true;
				b = readByte();
			}

			while (true) {
				if (b >= '0' && b <= '9') {
					num = num * 10 + (b - '0');
				} else {
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

		long nextLong() {
			long num = 0;
			int b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-') {
				minus = true;
				b = readByte();
			}

			while (true) {
				if (b >= '0' && b <= '9') {
					num = num * 10 + (b - '0');
				} else {
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

		char[][] nextMatrix(int n, int m) {
			char[][] map = new char[n][];
			for (int i = 0; i < n; i++)
				map[i] = next(m);
			return map;
		}

		int[] nextIntArray(int n) {
			int[] a = new int[n];
			for (int i = 0; i < n; i++)
				a[i] = nextInt();
			return a;
		}

		long[] nextLongArray(int n) {
			long[] a = new long[n];
			for (int i = 0; i < n; i++)
				a[i] = nextLong();
			return a;
		}

		int[][] next2DInt(int n, int m) {
			int[][] arr = new int[n][];
			for (int i = 0; i < n; i++) {
				arr[i] = nextIntArray(m);
			}
			return arr;
		}

		long[][] next2DLong(int n, int m) {
			long[][] arr = new long[n][];
			for (int i = 0; i < n; i++) {
				arr[i] = nextLongArray(m);
			}
			return arr;
		}

		int[] shuffle(int[] arr) {
			Random r = new Random();
			for (int i = 1, j; i < arr.length; i++) {
				j = r.nextInt(i);
				int c = arr[i];
				arr[i] = arr[j];
				arr[j] = c;
			}
			return arr;
		}

		long[] shuffle(long[] arr) {
			Random r = new Random();
			for (int i = 1, j; i < arr.length; i++) {
				j = r.nextInt(i);
				long c = arr[i];
				arr[i] = arr[j];
				arr[j] = c;
			}
			return arr;
		}

		int[] uniq(int[] arr) {
			arr = scn.shuffle(arr);
			Arrays.sort(arr);
			int[] rv = new int[arr.length];
			int pos = 0;
			rv[pos++] = arr[0];
			for (int i = 1; i < arr.length; i++) {
				if (arr[i] != arr[i - 1]) {
					rv[pos++] = arr[i];
				}
			}
			return Arrays.copyOf(rv, pos);
		}

		long[] uniq(long[] arr) {
			arr = scn.shuffle(arr);
			Arrays.sort(arr);
			long[] rv = new long[arr.length];
			int pos = 0;
			rv[pos++] = arr[0];
			for (int i = 1; i < arr.length; i++) {
				if (arr[i] != arr[i - 1]) {
					rv[pos++] = arr[i];
				}
			}
			return Arrays.copyOf(rv, pos);
		}

		int[] reverse(int[] arr) {
			int l = 0, r = arr.length - 1;
			while (l < r) {
				arr[l] = arr[l] ^ arr[r];
				arr[r] = arr[l] ^ arr[r];
				arr[l] = arr[l] ^ arr[r];
				l++;
				r--;
			}
			return arr;
		}

		long[] reverse(long[] arr) {
			int l = 0, r = arr.length - 1;
			while (l < r) {
				arr[l] = arr[l] ^ arr[r];
				arr[r] = arr[l] ^ arr[r];
				arr[l] = arr[l] ^ arr[r];
				l++;
				r--;
			}
			return arr;
		}

		int[] compress(int[] arr) {
			int n = arr.length;
			int[] rv = Arrays.copyOf(arr, n);
			rv = uniq(rv);
			for (int i = 0; i < n; i++) {
				arr[i] = Arrays.binarySearch(rv, arr[i]);
			}
			return arr;
		}

		long[] compress(long[] arr) {
			int n = arr.length;
			long[] rv = Arrays.copyOf(arr, n);
			rv = uniq(rv);
			for (int i = 0; i < n; i++) {
				arr[i] = Arrays.binarySearch(rv, arr[i]);
			}
			return arr;
		}

		void deepFillInt(Object array, int val) {
			if (!array.getClass().isArray()) {
				throw new IllegalArgumentException();
			}
			if (array instanceof int[]) {
				int[] intArray = (int[]) array;
				Arrays.fill(intArray, val);
			} else {
				Object[] objArray = (Object[]) array;
				for (Object obj : objArray) {
					deepFillInt(obj, val);
				}
			}
		}

		void deepFillLong(Object array, long val) {
			if (!array.getClass().isArray()) {
				throw new IllegalArgumentException();
			}
			if (array instanceof long[]) {
				long[] intArray = (long[]) array;
				Arrays.fill(intArray, val);
			} else {
				Object[] objArray = (Object[]) array;
				for (Object obj : objArray) {
					deepFillLong(obj, val);
				}
			}
		}
	}
}