//#include <ext/pb_ds/assoc_container.hpp> 
// #include <ext/pb_ds/tree_policy.hpp> 
#include <iostream>
#include <iomanip>
#include <sstream>
#include <cstring>
#include <vector>
#include <deque>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <iterator>
#include <functional>
#include <limits>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <cassert>
#include <unordered_map>
#include <unordered_set>
#include <stack>
using namespace std;
#define IOS ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define trace(x) cerr << #x << ": " << x << " " << endl;

typedef int64_t ll;

#define endl '\n'
#define int ll
ll mod=1e9+7;
ll mod1=1e9+6;

ll power(ll a,ll b)
{
    if(b==0) return 1;
    else if(b%2==0)
        return power((((a%mod)*(a%mod))%mod),b/2)%mod;
    else return ((a%mod)*(power((((a%mod)*(a%mod))%mod),b/2)%mod))%mod;
}

// using namespace __gnu_pbds;
// #define ordered_set tree<pair<int,int>, null_type,less<pair<int,int>>, rb_tree_tag,tree_order_statistics_node_update>
//find_by_order(k)  returns iterator to kth element starting from 0;
//order_of_key(k) returns count of elements strictly smaller than k;
//erase,insert same as normal set

int32_t main()
{
IOS

    
    int n,m;
    cin>>n>>m;
    char ch[n+1][m+1];
    int node=n*m;
    int gr[node+1][node+1];
    for(int i=1;i<=node;++i)
    {
        for(int j=1;j<=node;++j)
            gr[i][j]=1e9;
        gr[i][i]=0;
    }
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
            cin>>ch[i][j];
        for(int i=1;i<=n;++i)
        {
            for(int j=1;j<=m;++j)
            {
                if(ch[i][j]=='#')
                    continue;
                int nd=(i-1)*m+j;
                if(i!=1)
                {
                    if(ch[i-1][j]=='.')
                    {
                        int nd1=(i-2)*m+j;
                        gr[nd][nd1]=1;

                    }
                }
                if(i!=n)
                {
                    if(ch[i+1][j]=='.')
                    {
                        int nd1=(i)*m+j;
                        gr[nd][nd1]=1;
                    }
                }
                if(j!=1)
                {
                    if(ch[i][j-1]=='.')
                    {
                        int nd1=(i-1)*m+j-1;
                        gr[nd][nd1]=1;
                    }
                }
                if(j!=m)
                {
                    if(ch[i][j+1]=='.')
                    {
                        int nd1=(i-1)*m+j+1;
                        gr[nd][nd1]=1;
                    }
                }
            }

        }
        
        for(int i=1;i<=n*m;++i)
        {
            for(int j=1;j<=n*m;++j)
            {
                for(int k=1;k<=n*m;++k)
                {
                    if(gr[j][i]+gr[i][k]<gr[j][k])
                        gr[j][k]=gr[j][i]+gr[i][k];
                }
            }
        }
        // for(int i=1;i<=n*m;++i)
        // {
        //     for(int j=1;j<=n*m;++j)
        //     {
        //         cout<<gr[i][j]<<" ";
        //     }
        //     cout<<endl;
        // }

        int ans=0;
        for(int i=1;i<=n*m;++i)
            for(int j=1;j<=n*m;++j)
            {
                if(i==j)
                    continue;
                if(gr[i][j]!=1e9)
                    ans=max(ans,gr[i][j]);
            }

            cout<<ans;
    
}       

Measured memory_bytes: 1536