#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
#include <cstdio>
#include <string>
#include <cmath>
#include <queue>
#include <tuple>
#include <set>
#include <assert.h>
#include <sstream>
#include <string>
//#include <bits/stdc++.h>
#define maxs(x,y) x = max(x,y)
#define mins(x,y) x = min(x,y)
#define rep(i,n) for(int (i)=0;(i)<(n);(i)++)
#define repr(i, n) for (int i = (n) - 1; i >= 0; i--)
#define FOR(i,i0,n) for(int (i)=(i0);(i)<(n);(i)++)
#define FORR(i,i0,n) for(int (i)=(n)-1; (i)>=(i0);(i)--)
#define SORT(x) sort(x.begin(),x.end())
#define SORTR(x) sort(x.begin(),x.end(),greater <>())
#define rn return
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
typedef std::pair<int,int> P;
using namespace std;
using ll = long long;





// auto mod int
// https://youtu.be/L8grWxBlIZ4?t=9858
// https://youtu.be/ERZuLAxZffQ?t=4807 : optimize
// https://youtu.be/8uowVvQ_-Mo?t=1329 : division
const int mod = 1000000007;
struct mint {
    ll x; // typedef long long ll;
    mint(ll x=0):x((x%mod+mod)%mod){}
    mint& operator+=(const mint a) {
        if ((x += a.x) >= mod) x -= mod;
        return *this;
    }
    mint& operator-=(const mint a) {
        if ((x += mod-a.x) >= mod) x -= mod;
        return *this;
    }
    mint& operator*=(const mint a) {
        (x *= a.x) %= mod;
        return *this;
    }
    mint operator+(const mint a) const {
        mint res(*this);
        return res+=a;
    }
    mint operator-(const mint a) const {
        mint res(*this);
        return res-=a;
    }
    mint operator*(const mint a) const {
        mint res(*this);
        return res*=a;
    }
    mint pow(ll t) const {
        if (!t) return 1;
        mint a = pow(t>>1);
        a *= a;
        if (t&1) a *= *this;
        return a;
    }
    
    // for prime mod
    mint inv() const {
        return pow(mod-2);
    }
    mint& operator/=(const mint a) {
        return (*this) *= a.inv();
    }
    mint operator/(const mint a) const {
        mint res(*this);
        return res/=a;
    }
};
// combination mod prime
// https://www.youtube.com/watch?v=8uowVvQ_-Mo&t=1619
struct combination {
    vector<mint> fact, ifact;
    combination(int n):fact(n+1),ifact(n+1) {
        assert(n < mod);
        fact[0] = 1;
        for (int i = 1; i <= n; ++i) fact[i] = fact[i-1]*i;
        ifact[n] = fact[n].inv();
        for (int i = n; i >= 1; --i) ifact[i-1] = ifact[i]*i;
    }
    mint operator()(int n, int k) {
        if (k < 0 || k > n) return 0;
        return fact[n]*ifact[k]*ifact[n-k];
    }
};


vector<int> x(101010);
combination comb = combination(101010);
vector<mint> fact(101010);
mint solve(int j,int goal){
    mint d = goal - x[j];
    if (j == 0){
        rn d;
    }
    mint ans;
    mint s = solve(j-1,x[j]);
    rep(i,j+1){
        ans += ( fact[j]*d*(i+1))*comb(j,i);
    }
    rn ans+s*(j+1);
}

vector<int> travelx = {0,0,1,-1};
vector<int> travely = {1,-1,0,0};
vector<vector<char>> s(21,vector<char>(21));

int solve(int i, int j, int p, int q, int h, int w){
    vector<vector<int>> visited(h,vector<int>(w,0));
    rep(ii,h) rep (jj,w) {
        if (s[ii][jj] == '#') visited[ii][jj] = 1;
    }
    visited[i][j] = 1;
    
    vector<vector<int>> distance(h,vector<int>(w,-1));
    rep(ii,h) rep (jj,w) {
        if (s[ii][jj] == '#') distance[ii][jj] = -100;
    }
    distance[i][j] = 0;
    
    queue<pair<int,int>> que;
    que.push(mp(i,j));
    while(!que.empty()){
        P current = que.front();
        que.pop();
        rep(ii,4){
            int ci = current.fi+travely[ii];
            int cj = current.se+travelx[ii];
            if ( ci >= 0 && ci <h && cj < w &&  cj >= 0 && visited[ci][cj]!=1){
                distance[ci][cj] = max(distance[ci][cj],distance[current.fi][current.se] + 1);
                visited[ci][cj] = 1;
                que.push(mp(ci,cj));
            }
        }
    }
    int ans = 0;
    rep(ii,h){
        rep(jj,w){
            ans = max(ans,distance[ii][jj]);
        }
    }
    rn ans;
}

int main(){
    int h,w;
    cin >> h >> w;
    
    rep(i,h){
        rep(j,w){
            cin >> s[i][j];
        }
    }
    int ans = 0;
    rep(i,h){
        rep(j,w){
            rep(p,h){
                rep(q,w){
                    if (s[i][j] != '#' && s[p][q] != '#'){
                        ans = max(ans,solve(i,j,p,q,h,w));
                    }
                }
            }
        }
    }
    cout << ans;
    rn 0;
}


Measured memory_bytes: 3072