#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
void getre() {
  int x = 0;
  printf("%d\n", 1 / x);
}
void gettle() {
  int res = 1;
  while (1) res <<= 1;
  printf("%d\n", res);
}
template <typename T, typename S>
inline bool upmin(T &a, const S &b) {
  return a > b ? a = b, 1 : 0;
}
template <typename T, typename S>
inline bool upmax(T &a, const S &b) {
  return a < b ? a = b, 1 : 0;
}
template <typename N, typename PN>
inline N flo(N a, PN b) {
  return a >= 0 ? a / b : -((-a - 1) / b) - 1;
}
template <typename N, typename PN>
inline N cei(N a, PN b) {
  return a > 0 ? (a - 1) / b + 1 : -(-a / b);
}
template <typename N>
N gcd(N a, N b) {
  return b ? gcd(b, a % b) : a;
}
template <typename N>
inline int sgn(N a) {
  return a > 0 ? 1 : (a < 0 ? -1 : 0);
}
inline void gn(long long &x) {
  int sg = 1;
  char c;
  while (((c = getchar()) < '0' || c > '9') && c != '-')
    ;
  c == '-' ? (sg = -1, x = 0) : (x = c - '0');
  while ((c = getchar()) >= '0' && c <= '9') x = x * 10 + c - '0';
  x *= sg;
}
inline void gn(int &x) {
  long long t;
  gn(t);
  x = t;
}
inline void gn(unsigned long long &x) {
  long long t;
  gn(t);
  x = t;
}
inline void gn(double &x) {
  double t;
  scanf("%lf", &t);
  x = t;
}
inline void gn(long double &x) {
  double t;
  scanf("%lf", &t);
  x = t;
}
inline void gs(char *s) { scanf("%s", s); }
inline void gc(char &c) {
  while ((c = getchar()) > 126 || c < 33)
    ;
}
inline void pc(char c) { putchar(c); }
inline long long sqr(long long a) { return a * a; }
inline double sqrf(double a) { return a * a; }
const int inf = 0x3f3f3f3f;
const double pi = 3.14159265358979323846264338327950288L;
const double eps = 1e-6;
const int maxn = 55;
int n, m;
char s[maxn][maxn];
bool usedRows[maxn];
bool usedCols[maxn];
struct mySet {
  set<int> rows, columns;
  void addRow(int i) {
    usedRows[i] = true;
    rows.insert(i);
    for (int j = 1; j <= m; j++) {
      if (s[i][j] == '#') {
        if (columns.count(j)) continue;
        addCol(j);
      }
    }
  }
  void addCol(int j) {
    usedCols[j] = true;
    columns.insert(j);
    for (int i = 1; i <= n; i++) {
      if (s[i][j] == '#') {
        if (rows.count(i)) continue;
        addRow(i);
      }
    }
  }
};
char t[maxn][maxn];
int main() {
  scanf("%d%d\n", &n, &m);
  for (int i = 1; i <= n; i++) {
    scanf("%s", s[i] + 1);
  }
  vector<mySet> vec;
  for (int i = 1; i <= n; i++) {
    if (usedRows[i]) continue;
    bool ok = false;
    for (int j = 1; !ok && j <= m; j++) {
      if (s[i][j] == '#') {
        ok = true;
      }
    }
    if (!ok) continue;
    mySet cur;
    cur.addRow(i);
    vec.push_back(move(cur));
  }
  memset(t, '.', sizeof(t));
  for (auto &ss : vec) {
    for (int i : ss.rows) {
      for (int j : ss.columns) {
        t[i][j] = '#';
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      if (s[i][j] != t[i][j]) {
        cout << "No";
        return 0;
      }
    }
  }
  cout << "Yes";
  return 0;
}
