#include <bits/stdc++.h>
using namespace std;
const int inf = 0x0f0f0f0f;
template <class S, class T>
inline pair<S, T> MP(S a, T b) {
  return make_pair(a, b);
}
template <class T>
inline auto LX(T &X) -> decltype((X.first)) {
  return X.first;
}
template <class T>
inline auto LX(const T &X) -> const decltype((X.first)) {
  return X.first;
}
template <class T>
inline auto RX(T &X) -> decltype((X.second)) {
  return X.second;
}
template <class T>
inline auto RX(const T &X) -> const decltype((X.second)) {
  return X.second;
}
template <class T>
inline void RST(T &a) {
  memset(a, 0, sizeof(a));
}
template <class T>
inline void RST1(T &a) {
  memset(a, -1, sizeof(a));
}
template <class T>
inline void SINF(T &a) {
  memset(a, 0x0f, sizeof(a));
}
template <class S, class T>
inline void RST(S &a, T b) {
  fill((T *)a, (T *)a + (sizeof(a) / sizeof(b)), b);
}
template <class T>
inline void CLR(T &a) {
  a.clear();
}
template <class S, class T>
inline void CPY(S &a, T &b) {
  memcpy(a, b, sizeof(a));
}
template <class S, class T>
inline bool chkmin(S &a, T b) {
  return b < a ? a = b, 1 : 0;
}
template <class S, class T>
inline bool chkmax(S &a, T b) {
  return a < b ? a = b, 1 : 0;
}
template <class T>
inline T sqr(T x) {
  return x * x;
}
template <class T>
inline int SZ(T &a) {
  return (int)(a.size());
}
template <class T>
inline bool EPT(T &a) {
  return a.empty();
}
template <class T>
inline auto FRT(T &a) -> decltype((a.front())) {
  return a.front();
}
template <class T>
inline auto FRT(const T &a) -> const decltype((a.front())) {
  return a.front();
}
template <class T>
inline auto BK(T &a) -> decltype(a.back()) & {
  return a.back();
}
template <class T>
inline auto BK(const T &a) -> const decltype((a.back())) {
  return a.back();
}
template <class T>
inline auto TOP(T &a) -> decltype((a.top())) {
  return a.top();
}
template <class T>
inline auto TOP(const T &a) -> const decltype((a.top())) {
  return a.top();
}
int n, m;
char s[1010][1010], s2[1010][1010];
set<int> c, r;
bool print(int l1, int r1, int l2, int r2) {
  for (int i = l1; i <= l2; i++) {
    if (!s[i][r1] || !s[i][r2]) return 0;
    s2[i][r1] = s2[i][r2] = 1;
  }
  for (int j = r1; j <= r2; j++) {
    if (!s[l1][j] || !s[l2][j]) return 0;
    s2[l1][j] = s2[l2][j] = 1;
  }
  return 1;
}
bool pd() {
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
      if (s[i][j] != s2[i][j]) return 0;
  return 1;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) scanf("%s", s[i] + 1);
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) s[i][j] = s[i][j] == '#';
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) {
      if (s[i][j] && s[i - 1][j] && s[i + 1][j]) c.insert(j);
      if (s[i][j] && s[i][j - 1] && s[i][j + 1]) r.insert(i);
    }
  if (c.size() > 4) c.erase(++ ++c.begin(), -- --c.end());
  if (r.size() > 4) r.erase(++ ++r.begin(), -- --r.end());
  for (int l1 : r)
    for (int l2 : r)
      for (int l3 : r)
        for (int l4 : r)
          for (int r1 : c)
            for (int r2 : c)
              for (int r3 : c)
                for (int r4 : c)
                  if (l2 > l1 + 1 && r2 > r1 + 1 && l4 > l3 + 1 &&
                      r4 > r3 + 1) {
                    RST(s2, 0);
                    if (print(l1, r1, l2, r2) && print(l3, r3, l4, r4) && pd())
                      return printf("YES\n%d %d %d %d\n%d %d %d %d\n", l1, r1,
                                    l2, r2, l3, r3, l4, r4),
                             0;
                  }
  puts("NO");
  return 0;
}
