/*---------------Go Code GO---------------*/

#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

template<typename T>
using Order_Set = tree<T, null_type,less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define     PI              acos(-1.0)
#define     O_O             ios_base::sync_with_stdio(false); cin.tie(NULL)
#define     precision(a)    fixed<<setprecision(a)
#define     endl            '\n'
#define     Flush           cout<<flush
#define     LLMX            0x3fffffffffffffff


long long H,W;
char Maze[22][22];
int dis[22][22], sx,sy, mx;

int X[] = {0,0,-1,1};
int Y[] = {1,-1,0,0};
void bfs(int x, int y)
{
    queue<pair<int,int> > qu;
    qu.push({x,y});
    dis[x][y]=0;
    while(qu.size())
    {
        x=qu.front().first;
        y=qu.front().second;
        qu.pop();
        for(int i=0; i<4; i++)
        {
            int dx = x + X[i];
            int dy = y + Y[i];
            if(Maze[dx][dy]=='.'&&dis[dx][dy]>dis[x][y]+1)
            {
                dis[dx][dy]=dis[x][y]+1;
                if(mx<dis[dx][dy])
                {
                    sx = dx;
                    sy = dy;
                    mx= dis[dx][dy];
                }
                qu.push({dx,dy});
            }
        }
    }
}


int main()
{
    O_O;
    long long i,j,k,l,tst=0,ans=0, csno=0 ;
    cin>>H>>W;
    for(i=1; i<=H; i++)
    {
        for(j=1; j<=W; j++)
        {
            cin>>Maze[i][j];
            if(Maze[i][j]=='.') sx=i, sy=j;
        }
    }
    memset(dis, 0x3f, sizeof(dis));
    bfs(sx,sy);
    mx=0;
    memset(dis, 0x3f, sizeof(dis));
    bfs(sx,sy);
    cout<<mx<<endl;

    return 0;
}
