#include <bits/stdc++.h>
using namespace std;
int N, M;
bool G[1000 + 1][1000 + 1];
struct pos {
  int x, y;
};
int* d[101][101][101];
double Solve_20() {
  for (int i = 1; i <= N; i++)
    for (int j = 1; j <= M; j++)
      for (int k = 1; k <= N; k++) {
        d[i][j][k] = new int[M + 1];
        for (int l = 1; l <= M; l++) {
          if (G[i][j] || G[k][l])
            d[i][j][k][l] = -2;
          else
            d[i][j][k][l] = -1;
        }
      }
  int NE = 0;
  for (int i = 1; i <= N; i++)
    for (int j = 1; j <= M; j++) {
      if (G[i][j]) continue;
      NE++;
      queue<pos> BFSQueue;
      BFSQueue.push((pos){i, j});
      d[i][j][i][j] = 0;
      while (!BFSQueue.empty()) {
        pos cur = BFSQueue.front();
        BFSQueue.pop();
        int k = cur.x, l = cur.y;
        if (l - 1 > 0 && d[i][j][k][l - 1] == -1) {
          d[i][j][k][l - 1] = d[i][j][k][l] + 1;
          BFSQueue.push((pos){k, l - 1});
        }
        if (l + 1 <= M && d[i][j][k][l + 1] == -1) {
          d[i][j][k][l + 1] = d[i][j][k][l] + 1;
          BFSQueue.push((pos){k, l + 1});
        }
        if (k - 1 > 0 && d[i][j][k - 1][l] == -1) {
          d[i][j][k - 1][l] = d[i][j][k][l] + 1;
          BFSQueue.push((pos){k - 1, l});
        }
        if (k + 1 <= N && d[i][j][k + 1][l] == -1) {
          d[i][j][k + 1][l] = d[i][j][k][l] + 1;
          BFSQueue.push((pos){k + 1, l});
        }
      }
    }
  long long sum = 0;
  for (int i = 1; i <= N; i++)
    for (int j = 1; j <= M; j++)
      for (int k = 1; k <= N; k++)
        for (int l = 1; l <= M; l++) {
          if (G[i][j] || G[k][l]) continue;
          sum += d[i][j][k][l];
        }
  double ans = (double)sum / (double)NE / (double)NE;
  return ans;
}
long long fl[1000 + 2][1000 + 2], fr[1000 + 2][1000 + 2];
int pointx[1000 + 1];
int pointy[1000 + 1];
int PreSumPx[1000 + 1];
int InvSumPx[1000 + 2];
double Solve() {
  long long ddist = 0;
  for (int i = 1; i <= N; i++) {
    int x = -1;
    for (int j = 1; j <= M; j++)
      if (G[i][j]) {
        x = j;
        break;
      }
    if (x > 0) ddist += 2 * (x - 1) * (M - x);
  }
  for (int j = 1; j <= M; j++) {
    int x = -1;
    for (int i = 1; i <= N; i++)
      if (G[i][j]) {
        x = i;
        break;
      }
    if (x > 0) ddist += 2 * (x - 1) * (N - x);
  }
  for (int j = 1; j <= M; j++)
    for (int i = 1; i <= N; i++)
      if (G[i][j]) {
        pointx[j] = i;
        break;
      }
  for (int i = 1; i <= N; i++)
    for (int j = 1; j <= M; j++)
      if (G[i][j]) {
        pointy[i] = j;
        break;
      }
  int sd = 0;
  int LastPoint = 0;
  int l = 1, r = 1;
  for (; r <= M; r++) {
    if (pointx[r] < LastPoint) {
      for (; l < r; l++) {
        sd -= N - pointx[l];
        if (pointx[l]) ddist += 2 * (pointx[l] - 1) * sd;
      }
    }
    LastPoint = pointx[r];
    sd += N - pointx[r];
  }
  for (; l <= M; l++) {
    sd -= N - pointx[l];
    if (pointx[l]) ddist += 2 * (pointx[l] - 1) * sd;
  }
  LastPoint = 0;
  l = M, r = M;
  assert(sd == 0);
  for (; l >= 1; l--) {
    if (pointx[l] < LastPoint) {
      for (; r > l; r--) {
        sd -= N - pointx[r];
        if (pointx[r]) ddist += 2 * (pointx[r] - 1) * sd;
      }
    }
    LastPoint = pointx[l];
    sd += N - pointx[l];
  }
  for (; r >= 1; r--) {
    sd -= N - pointx[r];
    if (pointx[r]) ddist += 2 * (pointx[r] - 1) * sd;
  }
  LastPoint = 0;
  int up = 1, down = 1;
  assert(sd == 0);
  for (; down <= N; down++) {
    if (pointy[down] < LastPoint) {
      for (; up < down; up++) {
        sd -= M - pointy[up];
        if (pointy[up]) ddist += 2 * (pointy[up] - 1) * sd;
      }
    }
    LastPoint = pointy[down];
    sd += M - pointy[down];
  }
  for (; up <= N; up++) {
    sd -= M - pointy[up];
    if (pointy[up]) ddist += 2 * (pointy[up] - 1) * sd;
  }
  LastPoint = 0;
  up = N, down = N;
  assert(sd == 0);
  for (; up >= 1; up--) {
    if (pointy[up] < LastPoint) {
      for (; down > up; down--) {
        sd -= M - pointy[down];
        if (pointy[down]) ddist += 2 * (pointy[down] - 1) * sd;
      }
    }
    LastPoint = pointy[up];
    sd += M - pointy[up];
  }
  for (; down >= 1; down--) {
    sd -= M - pointy[down];
    if (pointy[down]) ddist += 2 * (pointy[down] - 1) * sd;
  }
  for (int j = 1; j <= M; j++) PreSumPx[j] = PreSumPx[j - 1] + (pointx[j] > 0);
  for (int j = M; j >= 1; j--) InvSumPx[j] = InvSumPx[j + 1] + (pointx[j] > 0);
  for (int j = 1; j <= M; j++) {
    for (int i = 1; i <= N; i++) {
      fl[i][j] = fl[i][j - 1] + (N * (j - 1) - PreSumPx[j - 1]) +
                 i * (i - 1) / 2 + (N - i + 1) * (N - i) / 2;
      if (pointx[j])
        fl[i][j] -= ((pointx[j] - i) > 0 ? (pointx[j] - i) : -(pointx[j] - i));
    }
  }
  for (int j = M; j >= 1; j--) {
    for (int i = 1; i <= N; i++) {
      fr[i][j] = fr[i][j + 1] + (N * (M - j) - InvSumPx[j + 1]) +
                 i * (i - 1) / 2 + (N - i + 1) * (N - i) / 2;
      if (pointx[j])
        fr[i][j] -= ((pointx[j] - i) > 0 ? (pointx[j] - i) : -(pointx[j] - i));
    }
  }
  long long sum = 0;
  int NE = 0;
  for (int i = 1; i <= N; i++)
    for (int j = 1; j <= M; j++) {
      if (!G[i][j]) {
        sum += fr[i][j] + fl[i][j - 1] + (N * (j - 1) - PreSumPx[j - 1]);
        NE++;
      }
    }
  sum += 2 * ddist;
  double ans = (double)sum / (double)NE / (double)NE;
  return ans;
}
int main(int argc, char** argv) {
  scanf("%d %d", &N, &M);
  for (int i = 1; i <= N; i++) {
    char status[1000 + 2];
    scanf("%s", &status[1]);
    for (int j = 1; j <= M; j++) {
      if (status[j] == 'X')
        G[i][j] = true;
      else
        G[i][j] = false;
    }
  }
  if (N <= 10 && M <= 10)
    printf("%.12lf\n", Solve_20());
  else
    printf("%.12lf\n", Solve());
  return 0;
}
