#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000 + 5;
const int maxm = 1000 + 5;
int n, m;
char s[maxn][maxm];
int lef[maxn][maxm], rig[maxn][maxm], top[maxn][maxm], bot[maxn][maxm];
int f[maxn][maxm], g[maxn][maxm];
template <typename T>
inline const T &min(const T &a, const T &b, const T &c, const T &d) {
  return min(min(a, b), min(c, d));
}
struct answer {
  int x, y, s;
  answer(int x, int y, int s) : x(x), y(y), s(s) {}
};
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) {
      if (s[i][j] == '*') {
        lef[i][j] = lef[i][j - 1] + 1;
        top[i][j] = top[i - 1][j] + 1;
      }
    }
  }
  for (int i = n; i >= 1; --i) {
    for (int j = m; j >= 1; --j) {
      if (s[i][j] == '*') {
        rig[i][j] = rig[i][j + 1] + 1;
        bot[i][j] = bot[i + 1][j] + 1;
      }
    }
  }
  vector<answer> ans;
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= m; ++j) {
      int s = min(lef[i][j], rig[i][j], top[i][j], bot[i][j]) - 1;
      if (s >= 1) {
        ans.push_back(answer(i, j, s));
        f[i][j - s]++;
        f[i][j + s + 1]--;
        g[i - s][j]++;
        g[i + s + 1][j]--;
      }
    }
  }
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= m; ++j) {
      f[i][j] += f[i][j - 1];
      g[i][j] += g[i - 1][j];
    }
  }
  bool ok = true;
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= m; ++j) {
      if (s[i][j] == '*') {
        ok &= f[i][j] + g[i][j] > 0;
      }
    }
  }
  if (!ok) {
    return puts("-1"), 0;
  }
  printf("%d\n", (int)ans.size());
  for (int i = 0; i < ans.size(); ++i) {
    printf("%d %d %d\n", ans[i].x, ans[i].y, ans[i].s);
  }
  return 0;
}
