#include<iostream>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <climits>
#include <utility>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <iomanip>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
const long long int mod1=1000000007;
const long long int mod2 = -1;
#define fast ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define pb push_back
#define pp pop_back                                       
#define ff first
#define ss second
#define ll long long int
#define ull unsigned long long int
#define ordered_set tree<ll,null_type,less_equal<ll>,rb_tree_tag,tree_order_statistics_node_update>
#define ordered1 tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>
#define inf mod1
ll gcd(ll a, ll b){
    ll c;
     while(b){
        c = b;
        b = a % b;
        a = c;
     }
     return a;
}
ll power1(ll a, ll b){
     if(b == 0) return 1;
     else if(b % 2) return a * power1(a, b - 1);
     else {
        ll temp = power1(a, b / 2);
        return temp * temp;
     }
}
ll power2(ll a, ll b, ll m){
     a %= m;
     if(b == 0) return 1;
     else if(b % 2) return (a * power2(a, b - 1, m)) % m;
     else{
        ll temp = power2(a, b / 2, m);
        return (temp * temp) % m;
     }
}
ll mod(ll x, ll p){
return (x % p + p) % p;
}
ll lcm(ll x, ll y){
return (x * y)/gcd(x, y);
}
ll h, w, q;
ll g[500][500] = {};
ll dist[500][500];
ll a[100][100];
bool check(ll x, ll y){
    if(x >= 0 && x <= h - 1 && y >= 0 && y <= w - 1 && a[x][y] == 1){
        return true;
    }
    return false;
}
ll val(ll x, ll y){
    return w * x + y;
}
void add(ll x, ll y, ll a , ll b){
    ll q1 = val(x, y);
    ll w1 = val(a, b);
    g[q1][w1] = 1;
    g[w1][q1] = 1;
}
int main(){
    fast;
    ll h1 = 1;
    //cin >> h;
    while(h1--){
        //ll h, w;
        cin >> h >> w;
        ll q = h * w;
        for(int i = 0; i < h; i++){
            for(int j = 0; j < w; j++){
                char x;
                cin >> x;
                //cout << x << endl;
                if(x == '#'){
                a[i][j] = 0;
            }
                else{
                    a[i][j] = 1;
                }
               // cout << a[i][j] << endl;
            }
        }
        //cout << "hmm" << endl;  
        for(int i = 0; i < h; i++){
            for(int j = 0; j < w; j++){
                if(a[i][j]){
                    //cout << i << " " << j << endl;
                    if(check(i + 1, j)){
                        add(i, j, i + 1, j);
                    }
                    if(check(i - 1, j)){
                        add(i, j, i - 1, j);
                    }
                    if(check(i, j + 1)){
                        //cout << i << " " << j + 1 << endl;
                        add(i, j, i, j + 1);
                    }
                    if(check(i, j - 1)){
                        add(i, j, i, j - 1);
                    }
                }
            }
        }
        //cout << g[0][1] << endl;
        for(int i = 0; i < q; i++){
            for(int j = 0;j < q; j++){
                if(i == j){
                    dist[i][j] = 0;
                }
                else if(g[i][j]){
                    dist[i][j] = 1;
                }
                else{
                    dist[i][j] = 100000;
                }
            }
        }
        for(int i = 0; i < q; i++){
            for(int j = 0; j < q; j++){
                for(int k = 0; k < q; k++){
                    if (dist[j][i] + dist[i][k] < dist[j][k])  
                        dist[j][k] = dist[j][i] + dist[i][k];  
                }
            }
        }
        ll max1 = 0;
        for(int i = 0; i < q; i++){
            for(int j = 0; j < q; j++){
                //cout << g[i][j] << ' ';
                if(dist[i][j] <= q + 5){
                max1 = max(max1, dist[i][j]);}
            }
           // cout << endl;
        }
        //cout << dist[0][1] << endl;
        //cout << dist[14][4] << endl;
        cout << max1 << endl;
   }
}

Measured memory_bytes: 3456