```go
package main
import (
"bufio"
"fmt"
"os"
"strconv"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
scanner.Split(bufio.ScanWords)
if !scanner.Scan() {
return
}
n, _ := strconv.Atoi(scanner.Text())
if !scanner.Scan() {
return
}
m, _ := strconv.Atoi(scanner.Text())
obsRow := make([]int, n)
for i := range obsRow {
obsRow[i] = -1
}
obsCol := make([]int, m)
for i := range obsCol {
obsCol[i] = -1
}
numObstacles := 0
for i := 0; i < n; i++ {
if !scanner.Scan() {
break
}
line := scanner.Text()
for j := 0; j < m && j < len(line); j++ {
if line[j] == 'X' {
obsRow[i] = j
obsCol[j] = i
numObstacles++
}
}
}
R := make([]int64, n)
for i := 0; i < n; i++ {
if obsRow[i] != -1 {
R[i] = int64(m - 1)
} else {
R[i] = int64(m)
}
}
C := make([]int64, m)
for j := 0; j < m; j++ {
if obsCol[j] != -1 {
C[j] = int64(n - 1)
} else {
C[j] = int64(n)
}
}
var sumR int64 = 0
for i := 0; i < n; i++ {
for j := 0; j < n; j++ {
diff := int64(i - j)
if diff < 0 {
diff = -diff
}
sumR += R[i] * R[j] * diff
}
}
var sumC int64 = 0
for i := 0; i < m; i++ {
for j := 0; j < m; j++ {
diff := int64(i - j)
if diff < 0 {
diff = -diff
}
sumC += C[i] * C[j] * diff
}
}
var penaltyR int64 = 0
for i := 0; i < n; i++ {
if obsRow[i] != -1 {
k := int64(obsRow[i])
L := k
REmpty := int64(m) - 1 - k
penaltyR += 4 * L * REmpty
}
}
var penaltyC int64 = 0
for j := 0; j < m; j++ {
if obsCol[j] != -1 {
k := int64(obsCol[j])
U := k
D := int64(n) - 1 - k
penaltyC += 4 * U * D
}
}
totalSum := sumR + sumC + penaltyR + penaltyC
E := int64(n*m - numObstacles)
avg := float64(totalSum) / float64(E*E)
fmt.Printf("%.9f\n", avg)
}
```