#include <bits/stdc++.h>
using namespace std;
constexpr int maxn = 1010;
constexpr int dx[5] = {0, 0, 1, -1};
constexpr int dy[5] = {1, -1, 0, 0};
using Node = struct { int x, y, v; };
char G[maxn][maxn];
bool vis[maxn][maxn];
int n, m;
vector<Node> p, ret;
inline bool ok(int x, int y) { return x >= 0 && x < n && y >= 0 && y < m; }
void gao(int x, int y) {
  int tot = 1;
  bool flag = true;
  bool yes = false;
  while (flag) {
    flag = false;
    int cnt = 0;
    for (int i = 0; i < 4; i++) {
      int tx = x + dx[i] * tot;
      int ty = y + dy[i] * tot;
      if (ok(tx, ty) && G[tx][ty] == '*') cnt++;
    }
    if (cnt != 4) break;
    for (int i = 0; i < 4; i++) {
      int tx = x + dx[i] * tot;
      int ty = y + dy[i] * tot;
      vis[tx][ty] = 1;
    }
    flag = true;
    yes = true;
    tot++;
  }
  if (yes) {
    vis[x][y] = 1;
    ret.push_back({x + 1, y + 1, tot - 1});
  }
}
signed main() {
  while (~scanf("%d%d", &n, &m)) {
    p.clear();
    ret.clear();
    memset(vis, 0, sizeof(vis));
    for (int i = 0; i < n; i++) scanf("%s", G[i]);
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        if (G[i][j] == '*') p.push_back({i, j, 0});
      }
    }
    if (p.size() == 0) {
      printf("0\n");
      continue;
    }
    for (auto t : p) gao(t.x, t.y);
    if (ret.size() == 0) {
      printf("-1\n");
      continue;
    }
    bool flag = 0;
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        if (!vis[i][j] && G[i][j] == '*') {
          flag = 1;
        }
      }
    }
    if (flag) {
      printf("-1\n");
      continue;
    }
    printf("%d\n", ret.size());
    for (auto t : ret) {
      printf("%d %d %d\n", t.x, t.y, t.v);
    }
  }
  return 0;
}
