#include <bits/stdc++.h>
using namespace std;
using LL = long long;
template <typename T>
inline T& unused_var(T& v) {
  return v;
}
struct cww {
  cww() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout << fixed;
    cout << setprecision(10);
  }
};
cww star;
template <typename T>
std::istream& operator>>(std::istream& is, std::vector<T>& v) {
  for (auto& it : v) is >> it;
  return is;
}
class reverse_range {
 private:
  struct I {
    int x;
    int operator*() { return x - 1; }
    bool operator!=(I& lhs) { return x > lhs.x; }
    void operator++() { --x; }
  };
  I i, n;

 public:
  reverse_range(int n) : i({0}), n({n}) {}
  reverse_range(int i, int n) : i({i}), n({n}) {}
  I& begin() { return n; }
  I& end() { return i; }
};
class range {
 private:
  struct I {
    int x;
    int operator*() { return x; }
    bool operator!=(I& lhs) { return x < lhs.x; }
    void operator++() { ++x; }
  };
  I i, n;

 public:
  range(int n) : i({0}), n({n}) {}
  range(int i, int n) : i({i}), n({n}) {}
  I& begin() { return i; }
  I& end() { return n; }
  reverse_range operator!() { return reverse_range(*i, *n); }
};
template <typename T>
struct min_op {
  static T exec(const T l, const T r) { return l < r ? l : r; }
};
template <typename T>
struct max_op {
  static T exec(const T l, const T r) { return l > r ? l : r; }
};
template <typename F, typename T>
inline T multi_op(T&& v) {
  return v;
}
template <typename F, typename T, typename... Ts>
inline T multi_op(const T head, Ts&&... tail) {
  return F::exec(head, multi_op<F>(tail...));
}
template <typename T, typename... Ts>
inline T multi_min(T&& head, Ts&&... tail) {
  return multi_op<min_op<T> >(head, tail...);
}
template <typename T, typename... Ts>
inline T multi_max(T&& head, Ts&&... tail) {
  return multi_op<max_op<T> >(head, tail...);
}
template <typename F, typename T, typename... Ts>
inline bool ch_op(T& target, Ts&&... candidates) {
  const T old = target;
  target = multi_op<F>(target, candidates...);
  return old != target;
}
template <typename T, typename... Ts>
inline bool chmin(T& target, Ts&&... candidates) {
  return ch_op<min_op<T> >(target, candidates...);
}
template <typename T, typename... Ts>
inline bool chmax(T& target, Ts&&... candidates) {
  return ch_op<max_op<T> >(target, candidates...);
}
const pid_t pid = getpid();
class XorShift32 {
 private:
  unsigned value;
  inline void update() {
    value = value ^ (value << 13);
    value = value ^ (value >> 17);
    value = value ^ (value << 5);
  }
  inline unsigned get() {
    unsigned v = value;
    update();
    return v;
  }

 public:
  template <int bit = 31>
  inline int next_int() {
    return (int)(get() >> (32 - bit));
  }
  template <int bit = 31>
  inline int next_signed() {
    unsigned v = get();
    return (int)((v >> (31 - bit)) - (1 << (bit)));
  }
  template <int bit = 31>
  inline int range_max() {
    return (int)((1u << bit) - 1);
  };
  XorShift32(const unsigned seed) {
    value = seed;
    update();
  }
  XorShift32() : XorShift32(pid) {}
};
using S = string;
using VS = vector<S>;
VS wrap(VS in) {
  int r = in.size();
  int c = in[0].size();
  VS out(r + 2, S(c + 2, '.'));
  for (int i : range(r)) {
    for (int j : range(c)) {
      out[i + 1][j + 1] = in[i][j];
    }
  }
  return out;
}
int dr[] = {1, -1, 0, 0};
int dc[] = {0, 0, 1, -1};
int main() {
  int r, c;
  cin >> r >> c;
  VS in(r);
  cin >> in;
  in = wrap(in);
  string ret = "Yes";
  for (int i : range(r + 2)) {
    for (int j : range(c + 2)) {
      if (in[i][j] == '#') {
        bool ok = false;
        for (int d : range(4)) {
          int nr = r + dr[d];
          int nc = c + dc[d];
          if (in[nr][nc] == '#') {
            ok = true;
          }
        }
        if (ok == false) {
          ret = "No";
        }
      }
    }
  }
  cout << ret << endl;
  return 0;
}
