#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma loop_opt(on)
using namespace std;
template <class T>
using vec = vector<T>;
template <class T>
using stack = stack<T, vec<T> >;
template <class T>
using MaxHeap = priority_queue<T, vec<T>, less<T> >;
template <class T>
using MinHeap = priority_queue<T, vec<T>, greater<T> >;
bool mp[1005][1005], used[1005][1005];
struct node {
  int x, y, w;
};
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int n, m;
  string str;
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    cin >> str;
    for (int j = 0; j < m; j++) {
      mp[i][j] = (str[j] != '.');
      used[i][j] = !mp[i][j];
    }
  }
  vec<node> ans;
  for (int i = 1; i < n; i++) {
    for (int j = 1; j < m; j++) {
      if (!mp[i][j]) continue;
      int cnt = 1;
      while (cnt <= min(min(i - 0, n - i), min(j - 0, m - j)) &&
             mp[i + cnt][j] && mp[i - cnt][j] && mp[i][j + cnt] &&
             mp[i][j - cnt]) {
        cnt++;
      }
      cnt--;
      if (cnt > 0) {
        ans.push_back(node{i, j, cnt});
        for (int k = 0; k < cnt + 1; k++) {
          used[i + k][j] = used[i - k][j] = used[i][j + k] = used[i][j - k] =
              true;
        }
      }
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (!used[i][j]) {
        cout << "-1\n";
        return 0;
      }
    }
  }
  cout << (int)ans.size() << '\n';
  for (auto &i : ans) {
    cout << i.x + 1 << ' ' << i.y + 1 << ' ' << i.w << '\n';
  }
}
