#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define vi vector<int>
#define vvi vector<vector<int>>
#define pii pair<int, int>
#define vs vector<string>
#define ll long long
#define ull unsigned long long
#define fastio ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
#define ld long double
#define mod 1000000007
using namespace std;
using namespace __gnu_pbds;

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

int main()
{
    int n, m;
    cin>>n>>m;
    vector<string> mat(n);
    for(int i = 0; i<n; ++i)
    {
        string s;
        cin>>s;
        mat[i] = s;
    }

    map<pii, map<pii, int>> graph;
    int dx[] = {-1, 0, 1, 0};
    int dy[] = {0, 1, 0, -1};


    for(int i = 0; i<n; ++i)
    {
        for(int j = 0; j<m; ++j)
        {
            for(int k = 0; k<n; ++k)
            {
                for(int l = 0; l<m; ++l)
                {
                    if(i==k && j==l) graph[{i, j}][{k, l}] = 0;
                    else graph[{i, j}][{k, l}] = 1e9;
                }
            }
        }
    }

    for(int i = 0; i<n; ++i)
    {
        for(int j = 0; j<m; ++j)
        {
            for(int k = 0; k<4; ++k)
            {
                int curx = dx[k] + i;
                int cury = dy[k] + j;
                if(curx<0 || curx>=n || cury<0 || cury>=m) continue;
                if(mat[curx][cury] == '#' || mat[i][j] == '#')
                {
                    graph[{i, j}][{curx, cury}] = 1e9;
                    graph[{curx, cury}][{i, j}] = 1e9;
                }
                else
                    graph[{i, j}][{curx, cury}] = 1;
            }
        }
    }

    map<pii, map<pii, int>> dist;

    for(int k = 0; k<n; ++k)
    {
        for(int l = 0; l<m; ++l)
        {
            for(int p = 0; p<n; ++p)
            {
                for(int q = 0; q<m; ++q)
                {
                    dist[{k, l}][{p, q}] = graph[{k, l}][{p, q}];
                }
             }
        }
    }

    for(int i = 0; i<n; ++i)
    {
        for(int j = 0; j<m; ++j)
        {
            for(int k = 0; k<n; ++k)
            {
                for(int l = 0; l<m; ++l)
                {
                    for(int p = 0; p<n; ++p)
                    {
                        for(int q = 0; q<m; ++q)
                        {
                            dist[{k, l}][{p, q}] = min(dist[{k, l}][{p, q}], dist[{k, l}][{i, j}] + dist[{i, j}][{p, q}]);
                        }
                     }
                }
            }
        }
    }

    int ans = -1;
    for(int k = 0; k<n; ++k)
    {
        for(int l = 0; l<m; ++l)
        {
            for(int p = 0; p<n; ++p)
            {
                for(int q = 0; q<m; ++q)
                {
                    if(dist[{k, l}][{p, q}] < 1e9)
                        ans = max(dist[{k, l}][{p, q}], ans);
                }
             }
        }
    }

    cout<<ans<<endl;
}