There is a rectangular grid of n rows of m initially-white cells each.

Arkady performed a certain number (possibly zero) of operations on it. In the i-th operation, a non-empty subset of rows R_{i} and a non-empty subset of columns C_{i} are chosen. For each row r in R_{i} and each column c in C_{i}, the intersection of row r and column c is coloured black.

There's another constraint: a row or a column can only be chosen at most once among all operations. In other words, it means that no pair of (i, j) (i < j) exists such that $R_{i} \cap R_{j} \neq \varnothing$ or $C_{i} \cap C_{j} \neq \varnothing$, where [Image] denotes intersection of sets, and $\varnothing$ denotes the empty set.

You are to determine whether a valid sequence of operations exists that produces a given final grid.


-----Input-----

The first line contains two space-separated integers n and m (1 ≤ n, m ≤ 50) — the number of rows and columns of the grid, respectively.

Each of the following n lines contains a string of m characters, each being either '.' (denoting a white cell) or '#' (denoting a black cell), representing the desired setup.


-----Output-----

If the given grid can be achieved by any valid sequence of operations, output "Yes"; otherwise output "No" (both without quotes).

You can print each character in any case (upper or lower).


-----Examples-----
Input
5 8
.#.#..#.
.....#..
.#.#..#.
#.#....#
.....#..

Output
Yes

Input
5 5
..#..
..#..
#####
..#..
..#..

Output
No

Input
5 9
........#
#........
..##.#...
.......#.
....#.#.#

Output
No



-----Note-----

For the first example, the desired setup can be produced by 3 operations, as is shown below.

 [Image] 

For the second example, the desired setup cannot be produced, since in order to colour the center row, the third row and all columns must be selected in one operation, but after that no column can be selected again, hence it won't be possible to colour the other cells in the center column.

Source: codeforces | Difficulty: EASY
Tags: Implementation

Greedy algorithms


Solutions:
def main():
	(n, m) = list(map(int, input().split()))
	(aa, bb) = ([{i for (i, c) in enumerate(input()) if c == '#'} for _ in range(n)], [])
	for a in aa:
		if a:
			for b in bb:
				c = a & b
				if c and a != b:
					print('No')
					return
			bb.append(a)
	print('Yes')

def __starting_point():
	main()
__starting_point()


(n, m) = map(int, input().split())
num = []
used = []
usedstr = [0] * n
fl = True
usedstolb = [0] * m
for i in range(n):
	num.append(input())
for i in range(n):
	if usedstr[i] == 0:
		stroki = []
		stolbi = []
		for j in range(m):
			if num[i][j] == '#':
				stolbi.append(j)
				for x in range(n):
					if num[x][j] == '#' and x not in stroki:
						stroki.append(x)
		for x in range(len(stroki)):
			for y in range(m):
				if num[stroki[x]][y] == '#' and y not in stolbi:
					stolbi.append(y)
		for x in range(len(stolbi)):
			if usedstolb[stolbi[x]]:
				fl = False
				break
			else:
				usedstolb[stolbi[x]] = 1
		for x in range(len(stroki)):
			if usedstr[stroki[x]]:
				fl = False
				break
			else:
				usedstr[stroki[x]] = 1
		for x in range(len(stroki)):
			for y in range(len(stolbi)):
				if num[stroki[x]][stolbi[y]] == '.':
					fl = False
					break
		if not fl:
			break
if fl:
	print('Yes')
else:
	print('No')


st = input().split()
(n, m) = (int(st[0]), int(st[1]))
map = [input() for i in range(n)]
for i in range(n):
	for j in range(m):
		if map[i][j] == '#':
			for p in range(n):
				if p != i and map[p][j] == '#' and (map[p] != map[i]):
					print('No')
					exit()
print('Yes')


t = set((input() for _ in [0] * int(input().split()[0])))
print(['No', 'Yes'][all((sum((c < '.' for c in s)) < 2 for s in zip(*t)))])


n = 0
m = 0

def esht(a, b):
	nonlocal n, m
	for ptr in range(0, len(a)):
		if a[ptr] is '#' and a[ptr] == b[ptr]:
			return True
	return False

def main():
	nonlocal n, m
	(n, m) = [*list(map(int, input().split()))]
	s = ['' for i in range(0, n)]
	for i in range(0, n):
		s[i] = input()
	ans = True
	for i in range(0, n):
		for j in range(i + 1, n):
			if esht(s[i], s[j]) and s[i] != s[j]:
				ans = False
	if ans is True:
		print('Yes')
	else:
		print('No')
main()


(n, m) = map(int, input().split())
t = [0] * n
for j in range(n):
	s = input()
	for i in range(len(s)):
		t[j] += int(s[i] == '#')
		t[j] *= 2
ans = True
for i in range(n):
	for j in range(i + 1, n):
		if t[i] & t[j] != 0:
			if t[i] != t[j]:
				ans = False
if ans:
	print('Yes')
else:
	print('No')


(n, m) = map(int, input().split())
d = {}
for x in range(n):
	s = input()
	for y in range(len(s)):
		if s[y] == '#':
			if not x in d:
				d[x] = []
			d[x].append(y)
flag = True
for (x, y) in d.items():
	for (i, j) in d.items():
		if x != i and y != j:
			for z in y:
				if z in j:
					flag = False
					break
if flag:
	print('Yes')
else:
	print('No')


par = input()
par = list(map(int, par.split()))
(n, m) = (par[0], par[1])
mat = []
for i in range(n):
	row = list(input())
	mat.append(row)

def posColor(n, m, mt):
	for i in range(n):
		for j in range(m):
			if mt[i][j] == '#':
				for x in range(i + 1, n):
					if mt[x][j] == '#':
						for y in range(m):
							if mt[i][y] != mt[x][y]:
								return 'No'
	return 'Yes'
print(posColor(n, m, mat))


import sys
import math, bisect
from collections import defaultdict
from itertools import groupby, accumulate
from heapq import heapify, heappop, heappush
from collections import deque, Counter, OrderedDict

def neo():
	return map(int, input().split())

def Neo():
	return list(map(int, input().split()))
(n, m) = neo()
A = []
for i in range(n):
	A.append(input())
f = [False for i in range(m)]
Al = set(A)
for r in Al:
	for c in range(len(r)):
		if r[c] == '#':
			if f[c]:
				print('No')
				exit()
			else:
				f[c] = True
print('Yes')


(n, m) = map(int, input().split())
l = []
for _ in range(n):
	s = input()
	se = set()
	for i in range(m):
		if s[i] == '#':
			se.add(i)
	l.append(se)
for i in range(n):
	for j in range(i + 1, n):
		if not (l[i] == l[j] or l[i] & l[j] == set()):
			print('No')
			exit(0)
print('Yes')


(rows, cols) = list(map(int, input().split()))
painting = []
for row in range(rows):
	painting.append(input().strip())
ps = set(painting)
used = [False] * cols
for r in ps:
	for c in range(cols):
		if r[c] == '#':
			if used[c]:
				print('No')
				exit()
			else:
				used[c] = True
print('Yes')


(a, b) = map(int, input().split())
z = [0] * a
k = [input() for _ in ' ' * a]
ok = 1
for i in range(a):
	if z[i]:
		continue
	t = [0] * b
	for j in range(b):
		t[j] += 0 + (k[i][j] == '#')
	for j in range(i + 1, a):
		o = [0] * b
		for x in range(b):
			o[x] += 0 + (k[j][x] == '#')
		p = 0
		for x in range(b):
			p += 0 + (o[x] == t[x] == 1)
		if p != 0:
			if p != t.count(1) or p != o.count(1):
				ok = 0
			else:
				z[j] = 1
if ok:
	print('yes')
else:
	print('no')


arri = lambda : [int(s) for s in input().split()]
arrf = lambda : [float(s) for s in input().split()]

def f(s1, s2):
	have2 = False
	have1 = False
	for i in range(len(s1)):
		if s1[i] == s2[i] == '#':
			have2 = True
		elif s1[i] == '#' and s2[i] != '#' or (s2[i] == '#' and s1[i] != '#'):
			have1 = True
	return not (have2 and have1)
(n, m) = arri()
s = [input() for i in range(n)]
flag = True
for i in range(n - 1):
	for j in range(i + 1, n):
		if not f(s[i], s[j]):
			flag = False
print('Yes' if flag else 'No')


import sys
(n, m) = [int(i) for i in input().split(' ')]
grid = []
columns_idx = set()
lines_used = set()
for _ in range(n):
	line = input()
	grid.append(line)
for line in grid:
	if line not in lines_used:
		lines_used.add(line)
		for (i, c) in enumerate(line):
			if c == '#':
				if i in columns_idx:
					print('No')
					sys.exit()
				else:
					columns_idx.add(i)
print('Yes')


(n, m) = map(int, input().split())
mat = []
for i in range(n):
	mat.append(input())
arr = [[] for i in range(n)]
col = [[] for i in range(m)]
p = True
for i in range(n):
	s = mat[i]
	for j in range(m):
		if s[j] == '#':
			arr[i].append(j)
			col[j].append(i)
	for x in arr[i]:
		for y in col[x]:
			if y != i:
				if arr[y] != arr[i]:
					p = False
					break
		if not p:
			break
	if not p:
		break
if p:
	print('Yes')
else:
	print('No')


import re
(n, m) = map(int, input().split())
rows = [input() for _ in range(n)]
cols = set()
while rows:
	r = rows.pop()
	if r.find('#') >= 0:
		c = set([occ.start() for occ in re.finditer('#', r)])
		if c & cols:
			print('No')
			break
		cols |= c
		rows = [o for o in rows if o != r]
else:
	print('Yes')


def findInArray(c, arr):
	ind = []
	for i in range(len(arr)):
		if arr[i] == c:
			ind.append(i)
	return ind

def solve():
	(numRows, numCols) = map(int, input().strip().split())
	mat = [[0] * numCols for _ in range(numRows)]
	for i in range(numRows):
		mat[i] = list(input().strip())
	rows = [0] * numRows
	cols = [0] * numCols
	counter = 1
	for i in range(numRows):
		for j in range(numCols):
			if mat[i][j] == '#':
				if rows[i] == 0 and cols[j] == 0:
					rows[i] = counter
					cols[j] = counter
					mat[i][j] = counter
					counter += 1
				else:
					if (rows[i] != 0 and cols[j] != 0) and rows[i] != cols[j]:
						return 'No'
					c = max(rows[i], cols[j])
					rows[i] = c
					cols[j] = c
					mat[i][j] = c
	for c in range(1, counter):
		rowsEqualToC = findInArray(c, rows)
		colsEqualToC = findInArray(c, cols)
		for i in rowsEqualToC:
			for j in colsEqualToC:
				if mat[i][j] != c:
					return 'No'
	return 'Yes'

def main():
	print(solve())
main()


import sys
(n, m) = [int(x) for x in input().split(' ')]
a = []
for i in range(n):
	b = []
	s = input().strip()
	for j in range(m):
		if s[j] == '#':
			b.append(j)
	if b not in a:
		a.append(b)
c = [0] * m
ans = True
for i in a:
	for j in i:
		c[j] += 1
		if c[j] > 1:
			ans = False
			break
if ans:
	print('Yes')
else:
	print('No')


def partial_match(r1, r2):
	n = len(r1)
	match_found = False
	mismatch_found = False
	for i in range(n):
		if r1[i] == '#' and r2[i] == '#':
			match_found = True
		if r1[i] == '#' and r2[i] == '.':
			mismatch_found = True
		if r2[i] == '#' and r1[i] == '.':
			mismatch_found = True
	return match_found and mismatch_found
(n, m) = tuple(map(int, input().split()))
l = []
for i in range(n):
	l.append(input().strip())
invalid = False
for i in range(n):
	for j in range(n):
		if partial_match(l[i], l[j]):
			invalid = True
			break
if invalid:
	print('No')
else:
	print('Yes')


(n, m) = map(int, input().split())
s = [input() for _ in range(n)]
l = []
for i in range(n):
	se = set()
	for j in range(m):
		if s[i][j] == '#':
			se.add(j)
	for li in l:
		if len(se & li) != 0 and se != li:
			print('No')
			exit()
	l.append(se)
print('Yes')


def readline():
	return tuple(map(int, input().split()))

def main():
	(n, m) = readline()
	unique_rows = list()
	first_occ = [None] * m
	while n:
		n -= 1
		row = input()
		saved = None
		for (i, char) in enumerate(row):
			if char == '#':
				if first_occ[i] is not None:
					if row != unique_rows[first_occ[i]]:
						return False
					else:
						break
				else:
					if saved is None:
						unique_rows.append(row)
						saved = len(unique_rows) - 1
					first_occ[i] = saved
			else:
				assert char == '.'
	return True
print('Yes' if main() else 'No')


(n, m) = map(int, input().split())
a = []
for i in range(n):
	a.append(input())
f = [False for i in range(m)]
al = set(a)
for r in al:
	for c in range(len(r)):
		if r[c] == '#':
			if f[c]:
				print('No')
				exit()
			else:
				f[c] = True
print('Yes')


(n, m) = map(int, input().split())
a = []
for i in range(n):
	a.append(input())
for i in range(n):
	for j in range(i + 1, n):
		(eqv, no_inter) = (True, True)
		for z in range(m):
			if a[i][z] != a[j][z]:
				eqv = False
			if a[i][z] == a[j][z] == '#':
				no_inter = False
		if eqv == no_inter == False:
			print('No')
			exit()
print('Yes')


(n, m) = map(int, input().split())
l = []
for _ in range(n):
	s = input()
	l.append(s)
l = set(l)
l1 = list(l)
n = len(l1)
x = []
for _ in range(m):
	x.append(0)
flag = 0
for i in range(n):
	for j in range(m):
		if l1[i][j] == '#' and x[j] == 0:
			x[j] = x[j] + 1
		elif l1[i][j] == '#' and x[j] != 0:
			flag = 1
	if flag == 1:
		break
if flag == 1:
	print('No')
else:
	print('Yes')


import sys
(n_rows, n_cols) = [int(x) for x in input().split(' ')]
map = []
for i in range(n_rows):
	map.append(input())
map_lines = dict()
activated_cols = dict()
for line in map:
	activated = []
	for (col_i, col) in enumerate(line):
		if col == '#':
			activated.append(col_i)
	activated_str = ' '.join([str(x) for x in activated])
	if activated_str not in map_lines:
		for col in activated:
			if col in activated_cols:
				print('No')
				sys.exit()
			else:
				activated_cols[col] = True
	map_lines[activated_str] = True
print('Yes')


(n, m) = map(int, input().split())
a = []
b = []
for i in range(n):
	a.append(input())
	s = ''
	for j in a[i]:
		if j == '#':
			s += '1'
		else:
			s += '0'
	b.append(s)
for i in range(n):
	for j in range(i, n):
		if a[i] != a[j]:
			if '2' in str(int(b[i]) + int(b[j])):
				print('No')
				exit()
print('Yes')


(r, c) = [int(x) for x in input().split()]
m = []
for i in range(r):
	m.append(input())
m = list(set(m))
n = len(m)
x = [0] * c
flag = 0
for i in range(n):
	for j in range(c):
		if m[i][j] == '#' and x[j] == 0:
			x[j] += 1
		elif m[i][j] == '#' and x[j] != 0:
			flag = 1
			break
	if flag:
		break
if flag:
	print('No')
else:
	print('Yes')


(n, m) = map(int, input().split())
T = [[] for i in range(n)]
for i in range(n):
	a = list(input())
	T[i] = a
R = [[] for i in range(n)]
for i in range(n):
	for j in range(m):
		if T[i][j] == '#':
			R[i].append(j)
flag = True
for i in range(n):
	for j in range(n):
		if len(set(R[i]) & set(R[j])) == len(set(R[i])) or len(set(R[i]) & set(R[j])) == 0:
			continue
		else:
			flag = False
			break
if flag:
	print('Yes')
else:
	print('No')


(n, m) = list(map(int, input().split()))
a = [-1] * m
b = []
f = True
for i in range(n):
	s = input()
	q = set()
	for j in range(len(s)):
		if s[j] == '#':
			q.add(j)
	for j in range(len(s)):
		if s[j] == '#':
			if a[j] == -1:
				a[j] = i
			elif b[a[j]] != q:
				f = False
	b.append(q)
if f:
	print('Yes')
else:
	print('No')


from itertools import product
(n, m) = map(int, input().split())
l = []
satir = {i: [] for i in range(n)}
sutun = {i: [] for i in range(m)}
for i in range(n):
	l.append(list(input()))
g = [['.'] * m for _ in range(n)]
for i in range(n):
	for a in range(m):
		if l[i][a] == '#':
			satir[i].append(a)
			sutun[a].append(i)
for i in satir:
	sa = set()
	sa.add(i)
	su = set()
	for a in satir[i]:
		su.add(a)
		for k in sutun[a]:
			sa.add(k)
	res = product(sa, su)
	for (a, b) in res:
		g[a][b] = '#'
if g == l:
	print('Yes')
else:
	print('No')


(n, m) = map(int, input().split())
s = set((input() for _ in range(n)))
for c in zip(*s):
	if ''.join(c).count('#') > 1:
		print('No')
		exit()
print('Yes')


(n, m) = map(int, input().split())
a = []
f = 0
for i in range(n):
	a.append(input())
for i in range(n):
	for j in range(i + 1, n):
		r1 = a[i]
		r2 = a[j]
		f1 = f2 = 0
		for k in range(m):
			if r1[k] != r2[k]:
				f1 = 1
			if r1[k] == '#' and r2[k] == '#':
				f2 = 1
		if f1 == 1:
			if f2 == 1:
				f = 1
if f:
	print('No')
else:
	print('Yes')


(n, m) = map(int, input().split())
M = []
for i in range(n):
	M.append(input())
Adj = [[] for i in range(n + m)]
for i in range(n):
	for j in range(m):
		if M[i][j] == '#':
			Adj[i].append(n + j)
			Adj[n + j].append(i)
p = [-1] * (n + m)
comp = []
answer = 'Yes'
for i in range(n + m):
	if p[i] != -1:
		continue
	L = [i]
	comp.append([])
	numEdges = 0
	numA = 0
	numB = 0
	while L:
		v = L.pop()
		comp[-1].append((v, 'A') if v < n else (v - n, 'B'))
		if v < n:
			numA += 1
		else:
			numB += 1
		for u in Adj[v]:
			numEdges += 1
			if p[u] == -1 and u != i:
				p[u] = v
				L.append(u)
	if numEdges // 2 != numA * numB:
		answer = 'No'
print(answer)


(li, co) = map(int, input().split())
m = [[j for j in input()] for i in range(li)]
t = [[0 for j in range(li)] for i in range(co)]
for i in range(li):
	for j in range(co):
		t[j][i] = m[i][j]
flag = True
for i in range(li):
	if '#' in m[i]:
		k = m[i].index('#')
		for j in range(k + 1, co):
			if m[i][j] == '#' and t[j] != t[k]:
				flag = False
print('Yes' if flag else 'No')


def func(ss):
	occured = set()
	for (pr, s) in zip([''] + ss[:-1], ss):
		if pr == s:
			continue
		for (i, el) in enumerate(s):
			if el == '#':
				if i in occured:
					return False
				occured.add(i)
	return True
(n, m) = [int(x) for x in input().split()]
ss = [input() for _ in range(n)]
ss.sort()
print('Yes' if func(ss) else 'No')


(n, m) = map(int, input().split())
t = [set((i for (i, c) in enumerate(input()) if c == '#')) for _ in [0] * n]
print(['No', 'Yes'][all((x == y or not x & y for x in t for y in t))])


import sys
(n, m) = map(int, input().split())
sys.setrecursionlimit(10000)
grid = [[i for i in input()] for _ in range(n)]
visited_cells = [[False] * m for _ in range(n)]

def correct_grid(row, column, parent_row, parent_column):
	visited_cells[row][column] = True
	visited_rows[row] = True
	visited_columns[column] = True
	if row + 1 < n and (row + 1 != parent_row or column != parent_column):
		down = row + 1
		while down < n:
			if grid[down][column] == '.' and visited_rows[down]:
				print('No')
				sys.exit()
			elif grid[down][column] == '.':
				down += 1
			elif grid[down][column] == '#' and (not visited_cells[down][column]):
				correct_grid(down, column, down - 1, column)
				break
			else:
				break
	if row - 1 > -1 and (row - 1 != parent_row or column != parent_column):
		up = row - 1
		while up > -1:
			if grid[up][column] == '.' and visited_rows[up]:
				print('No')
				sys.exit()
			elif grid[up][column] == '.':
				up -= 1
			elif grid[up][column] == '#' and (not visited_cells[up][column]):
				correct_grid(up, column, up + 1, column)
				break
			else:
				break
	if column + 1 < m and (row != parent_row or column + 1 != parent_column):
		right = column + 1
		while right < m:
			if grid[row][right] == '.' and visited_columns[right]:
				print('No')
				sys.exit()
			elif grid[row][right] == '.':
				right += 1
			elif grid[row][right] == '#' and (not visited_cells[row][right]):
				correct_grid(row, right, row, right - 1)
				break
			else:
				break
	if column - 1 > -1 and (row != parent_row or column - 1 != parent_column):
		left = column - 1
		while left > -1:
			if grid[row][left] == '.' and visited_columns[left]:
				print('No')
				sys.exit()
			elif grid[row][left] == '.':
				left -= 1
			elif grid[row][left] == '#' and (not visited_cells[row][left]):
				correct_grid(row, left, row, left + 1)
				break
			else:
				break
for r in range(n):
	for col in range(m):
		if grid[r][col] == '#':
			visited_rows = [False] * n
			visited_columns = [False] * m
			correct_grid(r, col, r, col)
print('Yes')


(r, c) = map(int, input().split())
grid = [input() for x in range(r)]
rows_checked = []
black_set = []
for (i, row) in enumerate(grid):
	index_black = [x for (x, c) in enumerate(row) if c == '#']
	black_set.append(index_black)
done = False
for b1 in black_set:
	for b2 in black_set:
		if b1 == b2:
			continue
		if any((x in b2 for x in b1)):
			print('No')
			done = True
			break
	if done:
		break
else:
	print('Yes')


(n, m) = map(int, input().split())
s = {input() for i in range(n)}
print('No' if any((sum((si[j] == '#' for si in s)) > 1 for j in range(m))) else 'Yes')


(row, column) = map(int, input().strip().split())
rset = set()
cset = set()
flag = True
for i in range(row):
	line = input().strip()
	if line in rset:
		continue
	for j in range(column):
		if line[j] == '.':
			continue
		if j in cset:
			flag = False
			break
		else:
			cset.add(j)
	rset.add(line)
if flag:
	print('Yes')
else:
	print('No')


from collections import defaultdict as dd, deque
import sys
(R, C) = map(int, input().split())
A = [input() for i in range(R)]
At = [[A[i][j] for i in range(R)] for j in range(C)]
D = dd(list)
for (i, a) in enumerate(A):
	D[a].append(i)
for a in D:
	I = D[a]
	J = [i for (i, c) in enumerate(a) if c == '#']
	for j in J:
		nI = [i for i in range(R) if A[i][j] == '#']
		if I != nI:
			print('No')
			sys.exit(0)
print('Yes')


T = input().split(' ')
n = int(T[0])
m = int(T[1])
tab = []
for i in range(n):
	t = input()
	row = []
	for j in range(m):
		if t[j] == '.':
			row.append(0)
		else:
			row.append(1)
	tab.append(row)
b = True
for i in range(n):
	for j in range(i + 1, n):
		c1 = False
		c2 = False
		for k in range(m):
			if tab[i][k] == 1 and tab[j][k] == 1:
				c1 = True
			if tab[i][k] + tab[j][k] == 1:
				c2 = True
		if c1 and c2:
			b = False
if b:
	print('Yes')
else:
	print('No')


(n, m) = map(int, input().split())
x = []
for i in range(n):
	l = list(input())
	x.append(l)
for i in range(n):
	for j in range(n):
		if x[i] != x[j]:
			for z in range(m):
				if x[i][z] == x[j][z] == '#':
					print('No')
					exit()
print('Yes')


def read_data():
	(n, m) = list(map(int, input().strip().split()))
	a = []
	for i in range(n):
		line = list(input().strip())
		for j in range(len(line)):
			if line[j] == '.':
				line[j] = 0
			else:
				line[j] = 1
		a.append(line)
	return (n, m, a)

def get_step(i, j):
	rows = []
	cols = []
	for k in range(m):
		if a[i][k] == 1:
			cols.append(k)
			if k in usedc:
				return 'No'
			else:
				usedc.append(k)
	for k in range(n):
		if a[k][j] == 1:
			rows.append(k)
			if k in usedr:
				return 'No'
			else:
				usedr.append(k)
	for row in rows:
		for col in cols:
			if a[row][col] == 0:
				return 'No'
			else:
				a[row][col] = 0
	return 'Ok'

def solve():
	for i in range(n):
		for j in range(m):
			if a[i][j] == 1:
				step = get_step(i, j)
				if step == 'No':
					return 'No'
	return 'Yes'
(n, m, a) = read_data()
usedr = []
usedc = []
print(solve())


(n, m) = map(int, input().split(' '))
l = []
a = 0
for i in range(0, n):
	s = input()
	st = set()
	for j in range(0, m):
		if s[j] == '#':
			st.add(j)
	if st not in l:
		l.append(st)
for i in range(0, len(l)):
	for j in range(i + 1, len(l)):
		if l[i].intersection(l[j]) != set():
			a += 1
			break
if a >= 1:
	print('No')
else:
	print('Yes')


def table(n, m, lst):
	for i in range(n):
		for j in range(n):
			if lst[i] != lst[j]:
				for k in range(m):
					if lst[i][k] == lst[j][k] == '#':
						return 'No'
	return 'Yes'
(N, M) = [int(i) for i in input().split()]
b = list()
for i in range(N):
	z = list(input())
	b.append(z)
print(table(N, M, b))


import sys

def p(s):
	print(s)
	sys.exit(0)
(n, m) = list(map(int, input().split()))
t = [input() for _ in range(n)]
sts = []
for i in range(n):
	founds = set()
	for j in range(m):
		if t[i][j] == '#':
			founds.add(j)
	sts.append(founds)
for i in range(n):
	for j in range(i + 1, n):
		if len(sts[i] & sts[j]) != 0 and sts[i] != sts[j]:
			p('No')
p('Yes')


(n, m) = map(int, input().split())
(array, Columns, count) = ([], [], 1)
for i in range(n):
	array.append(list(input()))
while array != []:
	if array.count(array[0]) > 1:
		elem = array[0]
		for i in range(array.count(elem)):
			array.remove(elem)
		for k in range(elem.count('#')):
			index = elem.index('#')
			Columns.append(index)
			elem[index] = '.'
	else:
		elem = array[0]
		for p in range(elem.count('#')):
			index = elem.index('#')
			Columns.append(index)
			elem[index] = '.'
		array.pop(0)
for i in range(int(len(Columns) / 2)):
	if Columns.count(Columns[i]) > count:
		count = 2
if count == 1:
	print('Yes')
else:
	print('No')


import sys, math, os.path
FILE_INPUT = 'B.in'
DEBUG = os.path.isfile(FILE_INPUT)
if DEBUG:
	sys.stdin = open(FILE_INPUT)

def ni():
	return map(int, input().split(' '))

def nia():
	return list(map(int, input().split()))

def log(x):
	if DEBUG:
		print(x)
(n, m) = ni()
a = [input() for x in range(n)]
log(a)
r = [[] for k in range(n)]
c = [[] for k in range(m)]
for i in range(n):
	for j in range(m):
		if a[i][j] == '#':
			r[i] += [j]
			c[j] += [i]
log(r)
log(c)
check = [True for x in range(n)]
for i in range(n):
	for ci in r[i]:
		for rii in c[ci]:
			if r[rii] != r[c[ci][0]]:
				print('No')
				sys.exit()
print('Yes')


(n, m) = map(int, input().split())
arr = [0] * n
mp = {}
for i in range(n):
	arr[i] = input()
	t = ''
	l = []
	for j in range(m):
		if arr[i][j] == '#':
			l.append(j)
			t += str(j)
	if t not in mp:
		mp[t] = set()
		for y in range(len(l)):
			mp[t].add(l[y])
		mp[t].add('r' + str(i))
	else:
		mp[t].add('r' + str(i))
k = mp[t]
for i in mp:
	if i != t:
		if len(k.intersection(mp[i])) > 0:
			print('No')
			exit()
		else:
			for j in mp[i]:
				k.add(j)
print('Yes')


(n, m) = map(int, input().split())
mx = [list(input()) for i in range(n)]
s = set()
for i in range(n):
	if i in s:
		continue
	for j in range(m):
		if mx[i][j] == '#':
			s.add(i)
			for k in range(i + 1, n):
				if mx[k][j] == '#':
					if mx[k] != mx[i]:
						print('No')
						exit(0)
					s.add(k)
print('Yes')


import sys
[n, m] = map(int, sys.stdin.readline().strip().split())
table = [sys.stdin.readline().strip() for _ in range(n)]
first_to_row = dict()
poss = True
for row in table:
	first = row.find('#')
	if first in first_to_row:
		if first_to_row[first] != row:
			poss = False
			break
	else:
		first_to_row[first] = row
if poss:
	counts = [False for _ in range(m)]
	for row in first_to_row.values():
		for i in range(m):
			if row[i] == '#':
				if counts[i]:
					poss = False
					break
				counts[i] = True
		if not poss:
			break
if poss:
	print('Yes')
else:
	print('No')


(H, W) = map(int, input().split())
tiles = set()
for i in range(H):
	tiles.add(input().rstrip())
used = [0] * W
flg = True
for tile in tiles:
	for j in range(W):
		if tile[j] == '#':
			if used[j] == 0:
				used[j] = 1
			else:
				flg = False
				exit
if flg:
	print('Yes')
else:
	print('No')


(n, m) = map(int, input().split())
l = [0 for i in range(n)]
ans = [set() for i in range(n)]
for i in range(n):
	l[i] = input()
	for j in range(len(l[i])):
		if l[i][j] == '#':
			ans[i].add(j)
x = False
for i in range(n):
	for j in range(i, n):
		if ans[j] & ans[i] != set():
			if ans[i] - ans[j] != set() or ans[j] - ans[i] != set():
				x = True
				break
	if x:
		break
if x == True:
	print('No')
else:
	print('Yes')


(r, c) = input().split(' ')
r = int(r)
c = int(c)
st = [['0' for x in range(c)] for y in range(r)]
for i in range(r):
	st[i] = list(input())
st2 = []
for i in range(c):
	st2 = []
	for j in range(r):
		if st[j][i] == '#':
			st2.append(j)
	if len(st2) > 1:
		for k in range(len(st2) - 1):
			val = st2[k:k + 2]
			if st[val[0]] != st[val[1]]:
				print('No')
				exit()
print('Yes')


(N, M) = map(int, input().split())
grid = []
for _ in range(N):
	grid.append(input())
S = [set() for _ in range(N)]
for i in range(N):
	for j in range(M):
		if grid[i][j] == '#':
			S[i].add(j)
solved = [False for _ in range(N)]
used = [False for _ in range(M)]
for i in range(N):
	if not solved[i]:
		for c in S[i]:
			if used[c]:
				print('No')
				quit()
			used[c] = True
		for j in range(N):
			if S[i] == S[j]:
				solved[j] = True
print('Yes')


def run():
	(h, w) = (int(x) for x in input().split())
	g = []
	for _ in range(h):
		g.append(input())
	rows_tkn = [False] * h
	for i in range(h):
		if rows_tkn[i]:
			continue
		rows_tkn[i] = True
		curr_row = g[i]
		col_i = [i for (i, x) in enumerate(curr_row) if x == '#']
		if len(col_i) == 0:
			continue
		cols = [''.join([g[_][ind] for _ in range(h)]) for ind in col_i]
		curr_col = cols[0]
		for cccc in cols:
			if cccc != curr_col:
				return False
		rows = [curr_row]
		for (ii, x) in enumerate(curr_col):
			if x == '#':
				rows.append(g[ii])
				rows_tkn[ii] = True
		for rrrr in rows:
			if rrrr != curr_row:
				return False
	return True
print('Yes' if run() else 'No')


import sys
sys.setrecursionlimit(1000000)

def dfsn(x):
	global n, m, usedn, usedm, a
	usedn[x] = 1
	f = 1
	for i in range(m):
		if a[x][i] == '#':
			if usedm[i] == 2:
				return 0
			elif not usedm[i]:
				f = min(dfsm(i), f)
		elif usedm[i] == 1:
			return 0
	return f

def dfsm(x):
	global n, m, usedn, usedm, a
	usedm[x] = 1
	f = 1
	for i in range(n):
		if a[i][x] == '#':
			if usedn[i] == 2:
				return 0
			elif not usedn[i]:
				f = min(dfsn(i), f)
		elif usedn[i] == 1:
			return 0
	return f
(n, m) = map(int, input().split())
a = [input() for i in range(n)]
usedn = [0] * n
usedm = [0] * m
f = 1
for i in range(n):
	if not usedn[i]:
		if not dfsn(i):
			f = 0
		for j in range(n):
			if usedn[j] == 1:
				usedn[j] = 2
		for j in range(m):
			if usedm[j] == 1:
				usedm[j] = 2
for i in range(m):
	if not usedm[i]:
		if not dfsm(i):
			f = 0
		for j in range(m):
			if usedm[j] == 1:
				usedm[j] = 2
		for j in range(n):
			if usedn[j] == 1:
				usedn[j] = 2
if f:
	print('Yes')
else:
	print('No')


(n, m) = map(int, input().split())
s = []
a = []
for i in range(n):
	s.append(input())
for i in range(n):
	k = 0
	for j in range(m):
		if s[i][j] == '#':
			k += 1 << j
	a.append(k)
for i in range(n):
	for j in range(i + 1, n):
		if a[i] != a[j] and a[i] & a[j]:
			print('no')
			quit()
print('yes')


(n, m) = tuple(map(int, input().split()))
mask = 0
collected = set()
while n:
	n -= 1
	row = 0
	for char in input():
		row = row << 1 | (char == '#')
	if row & mask:
		if row not in collected:
			print('No')
			break
	else:
		mask ^= row
		collected.add(row)
else:
	print('Yes')


(n, m) = list(map(int, input().split()))
grid = []
for i in range(n):
	l = input()
	grid.append(l)
g = set(grid)

def check_ok(i, g):
	count = 0
	for row in g:
		if row[i] == '#':
			count += 1
		if count >= 2:
			return False
	return count < 2
ans = True
for i in range(m):
	ans &= check_ok(i, g)
	if not ans:
		break
if ans:
	print('Yes')
else:
	print('No')


(n, m) = list(map(int, input().strip().split(' ')))
d = {}
visited = {}
ok = True
for i in range(n):
	line = input().strip()
	if line not in d:
		d[line] = 1
		for j in range(m):
			if line[j] == '#':
				if j in visited:
					ok = False
					break
				else:
					visited[j] = 1
if ok:
	print('Yes')
else:
	print('No')


(n, m) = map(int, input().split())
opTable = {}
answer = 'Yes'
for r in range(n):
	row = input()
	black = set()
	for i in range(m):
		if row[i] == '#':
			black.add(i)
			if i not in opTable:
				opTable[i] = black
	for b in black:
		diff = black.symmetric_difference(opTable[b])
		if len(diff) != 0:
			answer = 'No'
			break
	if answer == 'No':
		break
print(answer)


(n, m) = map(int, input().split())
l = [input() for i in range(n)]
flag = True
for i in range(n):
	for j in range(i + 1, n):
		if l[i] != l[j]:
			for q in range(m):
				if l[j][q] == l[i][q] == '#':
					print('NO')
					flag = False
					break
		if not flag:
			break
	if not flag:
		break
else:
	print('YES')


import sys

def read_two_int():
	return map(int, sys.stdin.readline().strip().split(' '))

def get_colored_rows(A, n, col):
	return {i for i in range(n) if A[i][col] == '#'}

def get_colored_columns(A, m, row):
	return {j for j in range(m) if A[row][j] == '#'}

def validate_step_correct(A, n, m, rows, columns):
	for row in rows:
		if get_colored_columns(A, m, row) != columns:
			return False
	for column in columns:
		if get_colored_rows(A, n, column) != rows:
			return False
	return True

def clear_step(A, rows, columns):
	for i in rows:
		for j in columns:
			A[i][j] = '.'

def validate_map(n, m, A):
	used_rows = [False for i in range(n)]
	used_columns = [False for j in range(m)]
	for i in range(n):
		for j in range(m):
			if A[i][j] != '#':
				continue
			rows = get_colored_rows(A, n, j)
			columns = get_colored_columns(A, m, i)
			if not validate_step_correct(A, n, m, rows, columns):
				return False
			clear_step(A, rows, columns)
	return True
(n, m) = read_two_int()
A = []
for i in range(n):
	row = sys.stdin.readline().strip()
	A.append([c for c in row])
print('Yes' if validate_map(n, m, A) else 'No')


TN = 1

def solution():
	(n, m) = map(int, input().split())
	lst = []
	ans = 'Yes'
	for i in range(n):
		lst.append(list(input()))
	l = []
	for i in range(n):
		k = []
		for j in range(m):
			if lst[i][j] == '#':
				k.append(j)
		l.append(k)
	R = []
	r = []
	C = []
	for i in range(n):
		if i not in r:
			k = [i]
			for j in range(i + 1, n):
				if l[i] == l[j]:
					k.append(j)
				else:
					for x in l[i]:
						if x in l[j]:
							ans = 'No'
							break
			R.append(k)
			r += k
			C.append(l[i])
	if len(R) != len(C):
		ans = 'No'
	print(ans)
while TN != 0:
	solution()
	TN -= 1


def row_not_empty(array, m, row):
	for col in range(m):
		if array[row][col] == '#':
			return True
	return False

def main():
	(n, m) = map(int, input().split())
	array = []
	for i in range(n):
		array.append(input())
	explored_rows = []
	explored_cols = []
	for row in range(n):
		curr_rows = []
		curr_cols = []
		if row not in explored_rows and row_not_empty(array, m, row):
			curr_rows.append(row)
			new = True
			while new == True:
				new = False
				for row in curr_rows:
					for col in range(m):
						if array[row][col] == '#' and col not in curr_cols:
							curr_cols.append(col)
							new = True
				for col in curr_cols:
					for row in range(n):
						if array[row][col] == '#' and row not in curr_rows:
							curr_rows.append(row)
							new = True
			for col in curr_cols:
				for row in curr_rows:
					if array[row][col] == '.':
						return False
			for col in curr_cols:
				if col in explored_cols:
					return False
				explored_cols.append(col)
			for row in curr_rows:
				if row in explored_rows:
					return False
				explored_rows.append(row)
	return True
if main():
	print('Yes')
else:
	print('No')


import math, sys, bisect, heapq
from collections import defaultdict, Counter, deque
from itertools import groupby, accumulate
input = iter(sys.stdin.buffer.read().decode().splitlines()).__next__
ilele = lambda : map(int, input().split())
alele = lambda : list(map(int, input().split()))

def list2d(a, b, c):
	return [[c] * b for i in range(a)]

def list3d(a, b, c, d):
	return [[[d] * c for j in range(b)] for i in range(a)]

def Y(c):
	print(['NO', 'YES'][c])

def y(c):
	print(['no', 'yes'][c])

def Yy(c):
	print(['No', 'Yes'][c])
(n, m) = ilele()
A = []
for i in range(n):
	s = input()
	B = set()
	for j in range(m):
		if s[j] == '#':
			B.add(j)
	A.append(B)
f = 0
for i in range(n):
	for j in range(i + 1, n):
		if A[i] != A[j] and len(A[i].intersection(A[j])) != 0:
			Yy(0)
			f = 1
			break
	if f == 1:
		break
if f == 0:
	Yy(1)


(n, m) = map(int, input().split())
st = []
for i in range(n):
	s = input()
	x = set()
	for j in range(m):
		if s[j] == '#':
			x.add(j)
	for i in st:
		if i & x and i != x:
			print('No')
			exit()
	st.append(x)
print('Yes')


from queue import Queue
global a, element

def coin(st):
	global element
	s = set()
	if not stroka[st]:
		for i in stStroka[st]:
			if not stolbic[i]:
				for j in stStolbic[i]:
					if not stroka[j]:
						if test(st, j):
							s.add(j)
							element -= 1
			stolbic[i] = True
	for k in s:
		stroka[k] = True
	return

def test(st, j):
	if st == j:
		return True
	for i in stStroka[st]:
		if not i in stStroka[j]:
			return False
	else:
		return True
(n, m) = list(map(int, input().split()))
stStolbic = {i: set() for i in range(1, m + 1)}
stStroka = {i: set() for i in range(1, n + 1)}
element = 0
stroka = [False] * (n + 1)
stolbic = [False] * (m + 1)
for i in range(1, n + 1):
	string = input()
	for j in range(len(string)):
		if string[j] == '#':
			element += 1
			stStroka[i].add(j + 1)
			stStolbic[j + 1].add(i)
for i in range(1, n + 1):
	if not stroka[i]:
		coin(i)
if element == 0:
	print('Yes')
else:
	print('No')


def read3():
	ent0 = input().split()
	line = input().split()
	ent = input().split()
	return (int(ent[0]), int(ent[1]), list(map(int, line)))

def time(s, f, A):
	d = f - s
	msum = sum(A[:d])
	csum = msum
	mind = 0
	n = len(A)
	A.extend(A[:d])
	for i in range(1, n):
		csum += A[i + d - 1] - A[i - 1]
		print(mind, msum, csum)
		if csum > msum:
			msum = csum
			mind = i
	print(mind)
	if s - mind > 0:
		return s - mind
	print(mind, msum, csum)
	return n + (s - mind)

def read3():
	ent = input()
	line = input()
	return (int(ent), line)

def Ax(n, line):
	for (i, l) in enumerate(line):
		if l != '?' and i + 1 < n and (line[i + 1] == l):
			return 'No'
		if l == '?' and i in [0, n - 1]:
			return 'Yes'
		if l == '?' and i - 1 >= 0 and (i + 1 < n) and ('?' != line[i - 1] == line[i + 1] != '?'):
			return 'Yes'
		if l == '?' and i - 1 >= 0 and (i + 2 < n) and (line[i + 1] == '?') and ('?' != line[i - 1] == line[i + 2] != '?'):
			return 'Yes'
	return 'No'

def rea():
	(rn, cn) = list(map(int, input().split()))
	T = []
	for r in range(rn):
		T.append(input())
	return (rn, cn, T)

def table(rn, cn, T):
	he = {}
	for r in range(rn):
		if T[r] in he:
			he[T[r]].add(r)
		else:
			he[T[r]] = set()
	hcol = set()
	for r in range(rn):
		for c in range(cn):
			if T[r][c] == '#' and r not in he[T[r]]:
				if c in hcol:
					return 'No'
				else:
					hcol.add(c)
	return 'Yes'
print(table(*rea()))


(BLACK, WHITE) = ('#', '.')
(n, m) = list(map(int, input().split()))
blacks = [{i for (i, c) in enumerate(input()) if c == BLACK} for i in range(n)]
answer = 'Yes'
for i in range(n):
	for j in range(i):
		if blacks[i] & blacks[j] and blacks[i] != blacks[j]:
			answer = 'No'
print(answer)


(n, m) = map(int, input().split())
x = []
for i in range(n):
	q = []
	y = input()
	for j in y:
		q.append(j)
	x.append(q)
ind = True
for i in range(n):
	for j in range(m):
		if x[i][j] == '#':
			for k in range(i + 1, n):
				if x[k][j] == '#' and x[k] != x[i]:
					ind = False
					break
if ind:
	print('Yes')
else:
	print('No')


used = []
a = []

def dfs(v, c):
	vert = v + 100 * c
	if used[vert] == 0:
		used[vert] = 1
		a[c].append(v)
		for i in range(0, len(g[vert])):
			if used[g[vert][i]] == 0:
				dfs(g[vert][i] - (1 - c) * 100, 1 - c)
(n, m) = map(int, input().split())
r = []
for i in range(0, n):
	s = input()
	r.append(s)
g = []
for i in range(0, 200):
	g.append([])
	used.append(0)
for i in range(0, n):
	for j in range(0, m):
		if r[i][j] == '#':
			g[i].append(100 + j)
			g[100 + j].append(i)
for i in range(0, n):
	a = [[], []]
	dfs(i, 0)
	for j in range(0, len(a[0])):
		for k in range(0, len(a[1])):
			if r[a[0][j]][a[1][k]] != '#':
				print('NO')
				raise SystemExit
print('YES')


class CDisjointSet(object):

	def __init__(self):
		self.leader = {}
		self.group = {}

	def Add(self, a, b):
		leadera = self.leader.get(a)
		leaderb = self.leader.get(b)
		if leadera is not None:
			if leaderb is not None:
				if leadera == leaderb:
					return
				groupa = self.group[leadera]
				groupb = self.group[leaderb]
				if len(groupa) < len(groupb):
					(a, leadera, groupa, b, leaderb, groupb) = (b, leaderb, groupb, a, leadera, groupa)
				groupa |= groupb
				del self.group[leaderb]
				for k in groupb:
					self.leader[k] = leadera
			else:
				self.group[leadera].add(b)
				self.leader[b] = leadera
		elif leaderb is not None:
			self.group[leaderb].add(a)
			self.leader[a] = leaderb
		else:
			self.leader[a] = self.leader[b] = a
			self.group[a] = set([a, b])

def Judge():
	ds = CDisjointSet()
	(n, m) = map(int, input().split())
	arr = list()
	for i in range(n):
		arr.append(input())
	for i in range(n):
		for j in range(m):
			if arr[i][j] == '#':
				ds.Add(i + 1, 101 + j)
	for vs in ds.group.values():
		rs = list()
		cs = list()
		for v in vs:
			if v < 100:
				rs.append(v - 1)
			else:
				cs.append(v - 101)
		for i in rs:
			for j in range(m):
				if j in cs and arr[i][j] == '.':
					return False
				if j not in cs and arr[i][j] == '#':
					return False
	return True
print('Yes') if Judge() else print('No')


(n, m) = map(int, input().split())
r = set()
c = set()
ss = []
for i in range(n):
	s = input()
	ss.append(s)
for i in range(n):
	s1 = set()
	for j in range(m):
		if ss[i][j] == '#':
			s1.add(j)
	for j in range(n):
		s2 = set()
		for k in range(m):
			if ss[j][k] == '#':
				s2.add(k)
		isi = len(s1.intersection(s2))
		if isi != 0 and (isi != len(s1) or isi != len(s2)):
			print('No')
			exit()
for i in range(m):
	s1 = set()
	for j in range(n):
		if ss[j][i] == '#':
			s1.add(j)
	for j in range(m):
		s2 = set()
		for k in range(n):
			if ss[k][j] == '#':
				s2.add(k)
		isi = len(s1.intersection(s2))
		if isi != 0 and (isi != len(s1) or isi != len(s2)):
			print('No')
			exit()
print('Yes')


(n, m) = map(int, input().split())
s = []
for i in range(n):
	s.append(input())
visited = [False for i in range(n)]
used = [False for i in range(m)]
ch = True
count = 0
for i in range(n):
	if not visited[i]:
		rows = []
		visited[i] = True
		for j in range(m):
			if s[i][j] == '#':
				rows.append(j)
				if used[j]:
					ch = False
					break
				used[j] = True
		if not ch:
			break
		if len(rows) == 0:
			continue
		cols = []
		for k in range(n):
			j = rows[0]
			if s[k][j] == '#':
				cols.append(k)
		for j in cols:
			visited[j] = True
		for j in rows:
			cols2 = []
			for k in range(n):
				if s[k][j] == '#':
					cols2.append(k)
			if cols != cols2:
				ch = False
				break
		if not ch:
			break
		for k in cols:
			rows2 = []
			for j in range(m):
				if s[k][j] == '#':
					rows2.append(j)
			if rows != rows2:
				ch = False
				break
if ch:
	print('yes')
else:
	print('no')


pairs = [int(s) for s in input().split(' ')]
R = int(pairs[0])
C = int(pairs[1])

def convert(s):
	if s == '.':
		return 0
	else:
		return 1
lines = []
matrix = []
for i in range(R):
	inpt = input()
	lines.append(inpt.replace('.', 'D'))
	matrix.append([convert(s) for s in list(inpt)])
can = True
for i in range(R):
	if 1 not in matrix[i]:
		pass
	step_R = []
	step_C = []
	for j in range(C):
		if matrix[i][j] == 1:
			step_C.append(j)
	for j_ in step_C:
		for i_ in range(R):
			if matrix[i_][j_] == 1:
				step_R.append(i_)
	for i_ in step_R:
		indices = [i for (i, x) in enumerate(matrix[i_]) if x == 1]
		if indices != step_C:
			can = False
			break
	indices = []
	for j_ in step_C:
		for i_ in range(R):
			if matrix[i_][j_] == 1:
				indices.append(i_)
	if indices != step_R:
		can = False
		break
	if can == False:
		break
	for i_ in step_R:
		for j_ in step_C:
			matrix[i_][j_] = 0
if can == True:
	print('Yes')
else:
	print('No')


(n, m) = [int(x) for x in input().split()]
dic = {}
di = {}
for i in range(0, n):
	x = input()
	if x in di.keys():
		di[x] += 1
	else:
		di[x] = 1
for i in range(0, m):
	dic[i] = 0
fl = 1
for i in di:
	for j in range(0, len(i)):
		if i[j] == '#':
			if dic[j] == 1:
				fl = 0
				break
			else:
				dic[j] = 1
	if fl == 0:
		break
if fl == 0:
	print('No')
else:
	print('yes')


(n, m) = map(int, input().split())
a = []
b = []
for i in range(n):
	l = input()
	r = list(l)
	a.append(r)
	b.append(l)
for j in range(m):
	s = []
	for i in range(n):
		if a[i][j] == '#':
			s.append(b[i])
	if len(list(set(s))) > 1:
		print('No')
		exit(0)
print('Yes')


(n, m) = map(int, input().split())
a = []
for i in range(n):
	a.append(input())
flak = 1
for i in range(n):
	d = []
	for j in range(m):
		if a[i][j] == '#':
			d.append(j)
	for j in range(1, len(d)):
		for k in range(n):
			if a[k][d[j - 1]] != a[k][d[j]]:
				flak = 0
if flak == 1:
	print('Yes')
else:
	print('No')


from collections import defaultdict
(r, c) = map(int, input().split())
h = defaultdict(list)
flg = []
for i in range(r):
	st = input()
	st = str(st)
	y = []
	for j in range(c):
		if st[j] == '#':
			y.append(j)
	if y in list(h.values()):
		flg.append(1)
	else:
		for k in y:
			for item in list(h.values()):
				if k in item:
					flg.append(0)
					break
	h[i] = y
if 0 in flg:
	print('No')
else:
	print('Yes')


from sys import stdin, stdout

def rint():
	return map(int, stdin.readline().split())
(r, c) = rint()
mat = []
for i in range(r):
	tmp = input()
	tmp = ''.join(['0' if s is '.' else '1' for s in tmp])
	mat.append(tmp)
for i in range(r):
	l = mat[i]
	li = int(l, 2)
	if li == 0:
		continue
	for j in range(i, r):
		l = mat[j]
		lj = int(l, 2)
		if li & lj != 0 and li != lj:
			print('No')
			exit()
print('Yes')


aa = input().split()
xx = int(aa[0])
yy = int(aa[1])
dd = [0] * yy
prime = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659]
fflag = 0
for i in range(0, xx):
	ss = input()
	ll = []
	flag = 0
	for j in range(0, len(ss)):
		if ss[j] == '#':
			ll.append(j)
			if dd[j] > 0:
				flag = 1
	if flag == 0:
		mul = 0
		for j in range(0, len(ll)):
			dd[ll[j]] = i + 1
	else:
		max = dd[ll[0]]
		for j in range(0, len(ll)):
			temp = dd[ll[j]]
			if temp != max:
				print('No')
				fflag = 1
				break
			else:
				for k in range(0, yy):
					if dd[k] == temp:
						if k not in ll:
							print('No')
							fflag = 1
							break
			if fflag == 1:
				break
	if fflag == 1:
		break
if fflag == 0:
	print('Yes')


(n, m) = map(int, input().split())
field = [''] * n
for i in range(n):
	field[i] = input()
for j in range(0, m):
	nums = []
	for i in range(0, n):
		if field[i][j] == '#':
			nums.append(i)
	if len(nums) > 0:
		for i in nums:
			if field[i] != field[nums[0]]:
				print('no')
				exit(0)
print('yes')


import functools
import sys

def with_args(deco):

	@functools.wraps(deco)
	def wrapper(*args, **kwargs):

		def res(func):
			return deco(func, *args, **kwargs)
		return res
	return wrapper

@with_args
def deco(func, str='я бесполезен'):

	@functools.wraps(func)
	def res(*args, **kwargs):
		print(str, end='\n')
		return func(*args, **kwargs)
	return res

@deco()
def id(x):
	return x

def fib(n):
	a = b = 1
	for i in range(n):
		yield a
		(a, b) = (b, a + b)
(n, m) = map(int, input().split())
vec = []
for i in range(n):
	s = input()
	res = set()
	for j in range(m):
		if s[j] == '#':
			res.add(j)
	vec.append(res)
flag = False
for i in range(n):
	for j in range(i, n):
		a = vec[i].intersection(vec[j])
		flag = flag or ((a != vec[i] or a != vec[j]) and a != set())
print('No' if flag else 'Yes')


(n, m) = map(int, input().split())
p = [list(input()) for _ in range(n)]
for i in range(n):
	column = []
	for j in range(m):
		if p[i][j] == '#':
			column.append(j)
	st1 = ''
	for (pos, el) in enumerate(column):
		st = ''
		for k in range(n):
			st += p[k][el]
		if pos == 0:
			st1 = st
		elif st1 != st:
			print('No')
			break
	else:
		continue
	break
else:
	print('Yes')