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
115
116
#include <bits/stdc++.h>
#include <random>
#define ll long long int
#define pb push_back
#define st first
#define nd second
#define pii pair<int,int>
#define mp make_pair
#define pll pair<long long,long long>
#define ld long double
#define ull unsigned long long
#define mt make_tuple
#define K long double

using namespace std;

const int nax = 105;
ll binom[nax][nax];
void prep(){
    for(int i=0;i<nax;i++){
        binom[i][0] = 1;
        for(int j=1;j<=i;j++){
            binom[i][j] = (binom[i - 1][j - 1] + binom[i - 1][j]);
        }
    }
}

int a[nax][nax];
int n, m;

void solve(){
    prep();
    cin >> n >> m;
    int p = 0;
    for(int i=1;i<=n;i++){
        string s; cin >> s;
        for(int j=1;j<=m;j++){
            if(s[j - 1] == 'O'){
                p += (i + j);
            }
        }
    }
    int p2 = 0;
    for(int i=1;i<=n;i++){
        string s; cin >> s;
        for(int j=1;j<=m;j++){
            if(s[j - 1] == 'O'){
                p2 += (i + j);
                a[i][j] = 1;
            }
            else a[i][j] == 0;
        }
    }
    if(p % 2 != p2 % 2){
        cout << 0 << "\n";
        return;
    }
    int dobre = 0;
    vector<pii> dirs = {mp(-1, 0), mp(1, 0), mp(0, -1), mp(0, 1)};
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            for(pii cur : dirs){
                pii go = mp(i + cur.st, j + cur.nd);
                if(go.st >= 1 && go.st <= n && go.nd >= 1 && go.nd <= m){
                    if(a[i][j] == 1 && a[go.st][go.nd] == 0) dobre++;
                }
            }
        }
    }

    int ones = 0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            ones += a[i][j];
        }
    }

    ones--;

    ll wszystkie = 0;
    int na_np = (p2 % 2);
    for(int r=1;r<=n;r++){
        for(int c=1;c<=m;c++){
            int ok = 0;
            for(pii cur : dirs){
                pii go = mp(r + cur.st, c + cur.nd);
                if(go.st >= 1 && go.st <= n && go.nd >= 1 && go.nd <= m) ok++;
            }

            ll ways = 0;
            int wolne_p = (n * m + 1) / 2;
            int wolne_np = n * m - wolne_p;
            wolne_np--; wolne_p--;

            for(int i=0;i<=ones;i++){
                if((i + ((r + c) % 2 == 1)) % 2 == na_np) ways += binom[wolne_np][i] * binom[wolne_p][ones - i];
            }
            //cout << "TF" << r << " " << c << " " << ways << " " << ok << endl;
            wszystkie += ways * ok;
        }
    }

    K ans = (K)dobre / (K)wszystkie;
    cout << fixed << setprecision(17) << ans << "\n";

}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);

    int tt = 1;
    // cin >> tt;
    while(tt--) solve();

    return 0;
}