#include #include #include #include #include using namespace std; int main () { // usb type cの存在に注意。 int H, W; cin >> H >> W; vector S(H), T(H); for (int i = 0; i < H; i++) cin >> S[i]; for (int i = 0; i < H; i++) cin >> T[i]; bool up = [&]() { for (int i = 0; i < H; i++) { for (int j = 0; j < W; j++) if (S[i][j] == T[i][j]) return false; } return true; }(); bool down = [&]() { for (int i = 0; i < H; i++) { for (int j = 0; j < W; j++) if (S[H - i - 1][W - j - 1] == T[i][j]) return false; } return true; }(); if (!up && !down) { cout << -1 << "\n"; return 0; } // 閉じた式を得るのが結構辛い感じがする。 // 誤差ジャッジかつ試行回数が多くなるほど確率はめちゃくちゃ小さくなりそうなので、シミュレーション回すことにする。 double ans = 0; // P: 累積失敗確率 double P = 1; for (int i = 1; i <= 100; i++) { double success = 1 - 1 / pow(2., i - 1); if (i % 2 == 1 && up) { ans += i * P * success; P *= 1 - success; } if (i % 2 == 0 && down) { ans += i * P * success; P *= 1 - success; } } cout << setprecision(10); cout << ans << "\n"; }