Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Problem L
Wall Making Game

The game Wall Making Game, a two-player board game, is all the rage.

This game is played on an $H \times W$ board. Each cell of the board is one of empty, marked, or wall. At the beginning of the game, there is no wall on the board.

In this game, two players alternately move as follows:

A player chooses one of the empty cells (not marked and not wall). If the player can't choose a cell, he loses.

Towards each of the four directions (upper, lower, left, and right) from the chosen cell, the player changes cells (including the chosen cell) to walls until the player first reaches a wall or the outside of the board.

Note that marked cells cannot be chosen in step 1, but they can be changed to walls in step 2.

Fig.1 shows an example of a move in which a player chooses the cell at the third row and the fourth
column.

Fig.1: An example of a move in Wall Making Game.

Your task is to write a program that determines which player wins the game if the two players play optimally from a given initial board.

Input

The first line of the input consists of two integers $H$ and $W$ $(1 \leq H, W \leq 20)$, where $H$ and $W$ are the height and the width of the board respectively. The following $H$ lines represent the initial board. Each of the $H$ lines consists of $W$ characters.

The $j$-th character of the $i$-th line is '.' if the cell at the $j$-th column of the $i$-th row is empty, or 'X' if the cell is marked.

Output

Print "First" (without the quotes) in a line if the first player wins the given game. Otherwise, print "Second" (also without the quotes) in a line.

Sample Input 1

2 2
..
..

Output for the Sample Input 1

Second

Sample Input 2

2 2
X.
..

Output for the Sample Input 2

First

Sample Input 3

4 5
X....
...X.
.....
.....

Output for the Sample Input 3

First

Solution in C++14 (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;

int grundy[21][21][21][21];

int calc_grundy(int y1, int x1, int y2, int x2, vector<string> const& v) {
    if(y2 <= y1 || x2 <= x1) {
        return grundy[y1][x1][y2][x2] = 0;
    }
    int& r = grundy[y1][x1][y2][x2];
    if(r != -1) {
        return r;
    }
    set<int> s;
    for(int i=y1; i<y2; ++i) {
        for(int j=x1; j<x2; ++j) {
            if(v[i][j] == 'X') {
                continue;
            }
            int g = 0;
            g ^= calc_grundy(y1, x1, i, j, v);
            g ^= calc_grundy(i+1, x1, y2, j, v);
            g ^= calc_grundy(y1, j+1, i, x2, v);
            g ^= calc_grundy(i+1, j+1, y2, x2, v);
            s.insert(g);
        }
    }
    r = 0;
    while(s.count(r) == 1) {
        r++;
    }
    return r;
}

string solve(vector<string> const& v) {
    const int H = v.size();
    const int W = v[0].size();
    return calc_grundy(0, 0, H, W, v) == 0 ? "Second" : "First";
}

int main() {
    int H, W;
    cin >> H >> W;
    for(int i=0; i<21; ++i) {
        for(int j=0; j<21; ++j) {
            for(int k=0; k<21; ++k) {
                for(int l=0; l<21; ++l) {
                    grundy[i][j][k][l] = -1;
                }
            }
        }
    }
    vector<string> v(H);
    for(int i=0; i<H; ++i) {
        cin >> v[i];
    }
    cout << solve(v) << endl;
}