1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include <bits/stdc++.h>
#define ll long long
#define ld long double

const int MAX_N = 8;
int T[MAX_N+3][MAX_N+3];
int n, m, k;

int bin[MAX_N * MAX_N+3][MAX_N+3];

void calc_bin() {
    bin[0][0] = 1;
    for (int i = 1; i <= n*m; i++) {
        bin[i][0] = 1;
        for (int j = 1; j <= 7; j++)
            bin[i][j] = bin[i-1][j-1] + bin[i-1][j];
    }
}

ll line(int l) {
    if (l == 1) return 0;
    if (l == 2) return 2;

    ll edge, rest; edge = rest = 0;

    edge = bin[l-2][k-1];
    rest = bin[l-3][k-1] * 2;
    if (k >= 2) rest += 2 * bin[l-3][k-2];

    return edge * 2 + rest * (l-2);
}

ll calc_num_of_edges() {
    ll M = 0;
    if (n == 1) return line(m);
    else if (m == 1) return line(n);
    
    // n, m >= 2
    ll corner, edge, rest; corner = edge = rest = 0;
    
    // corner
    for (int j = 0; j <= std::min(k-1, 1); j++)
        corner += bin[2][j] * bin[n*m-3][k-j-1] * (2 - j);

    // edge
    if (n >= 3 || m >= 3) {
        for (int j = 0; j <= std::min(k-1, 2); j++)
            edge += bin[3][j] * bin[n*m-4][k-j-1] * (3 - j);
    }

    // rest
    if (n >= 3 && m >= 3) {
        for (int j = 0; j <= std::min(k-1, 3); j++)
            rest += bin[4][j] * bin[n*m-5][k-j-1] * (4 - j);
    }

    // std::cout << "corner = " << corner << "\n";
    // std::cout << "edge = " << edge << "\n";
    // std::cout << "rest = " << rest << "\n";

    M = (corner * 4) + (edge * ((m-2)*2 + (n-2)*2)) + (rest * ((n-2)*(m-2)));
    return M;
}

ll calc_deg_of_T() {
    ll D = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (T[i][j]) {
                if (i > 0 && !T[i-1][j]) D++;
                if (i < n-1 && !T[i+1][j]) D++;
                if (j > 0 && !T[i][j-1]) D++;
                if (j < m-1 && !T[i][j+1]) D++;
            }
        }
    }
    return D;
}

int main() {
    std::ios_base::sync_with_stdio(0); std::cin.tie(NULL);
    std::cin >> n >> m;
    calc_bin();

    int X, Y; X = Y = 0;
    for (int i = 0; i < n; i++) {
        std::string s; std::cin >> s;
        for (int j = 0; j < s.length(); j++) {
            if (s[j] == 'O' && (i%2) == (j%2)) X++;
            if (s[j] == 'O') k++;
        }
    }

    int kk = 0;
    for (int i = 0; i < n; i++) {
        std::string s; std::cin >> s;
        for (int j = 0; j < s.length(); j++) {
            if (s[j] == 'O' && (i%2) == (j%2)) Y++;
            if (s[j] == 'O') { T[i][j] = 1; kk++; }
        }
    }

    if ((X%2) != (Y%2) || k != kk) std::cout << "0\n";
    else {
        ld M = calc_num_of_edges();
        M /= (ld)(2);
        ld L = calc_deg_of_T();

        // std::cout << "M = " << M << "\n";
        // std::cout << "L = " << L << "\n";

        std::cout << std::setprecision(15) << std::fixed << (L/M) << "\n";
    }
}