#include <bits/stdc++.h>
     
using namespace std;
typedef long long ll;
const int dinf=1000;
const int nmax=30; 
const int kmax=410; 


int DP[kmax][kmax];
char S[nmax][nmax];
 
int H,W,K;

char v(int i,int j){
    if (i < 1 || H < i || j < 1 || W < j){
        cout << "Error Line:" << __LINE__ << endl;
        exit(-1);
    }
    return S[i-1][j-1];
}

void print_v(){
    cout << H << endl;
    for(int i=1;i<=H; i++){
        for(int j=1; j<=W; j++){
            cout << v(i,j);
        }
        cout << endl;
    }
}

int index(int i,int j){
    if (i < 1 || H < i || j < 1 || W < j){
        cout << "Error Line:" << __LINE__ << endl;
        cout << i << "," << j << endl;
        exit(-1);
    }
    return (i-1)* W + j - 1;    
}

void print_DP(void){
    for(int i=0;i<K; i++){
        for(int j=0; j<K; j++){
            if(j!=0){ cout << ",";}
            if(DP[i][j] != dinf){
                cout << DP[i][j];
            } else {
                cout << ".";
            }
        }   
        cout << endl;
        if(i % W == W-1){
            cout << endl;
        }
    }
}

void init_DP(void){
    for(int k1=0; k1<K; k1++){
        for(int k2=0; k2<K; k2++){
            DP[k1][k2]=dinf;
        }
    }
    for(int i=1; i<=H; i++){
        for(int j=1; j<=W; j++){
            int k,l;
            int cost;
            k = index(i,j);
            DP[k][k] = 0; 
            if (i!= 1){ 
                l = index(i-1,j);
                if (v(i,j) != '#' && v(i-1,j)!= '#'){
                    cost = 1;
                    DP[k][l] = cost;
                }
                
            }

            if (i!= H){
                l = index(i+1,j);
                if (v(i,j) != '#' && v(i+1,j)!= '#'){
                    cost = 1;
                    DP[k][l] = cost;
                }
            }

            if (j!= 1){
                l = index(i,j-1);
                if (v(i,j) != '#' && v(i,j-1)!= '#'){
                    cost = 1;
                    DP[k][l] = cost;
                }
            }

            if (j!= W){
                l = index(i,j+1);
                /* if ( i == 2){
                    cout << i << "," << j << "," <<  k << endl; 
                    cout << i << "," << j+1 << "," << l << endl;
                } */ 
                if (v(i,j) != '#' && v(i,j+1)!= '#'){
                    cost = 1;
                    DP[k][l] = cost;
                } 
            }
            
        }
    }
}

void print_maxd(){
    int max=0;
    for(int i=0;i<K; i++){
        for(int j=0; j<K; j++){
            if (DP[i][j] != dinf && max < DP[i][j]){
                max = DP[i][j];
            }
        }
    }
    cout << max << endl;
}

void do_DP(){
    for(int k=0;k<K;k++){
        for(int i=0;i<K; i++){
            for(int j=0; j<K; j++){
                DP[i][j] = min(DP[i][j],DP[i][k]+DP[k][j]);
            }
        }
    }
}

int main() {
    int i,j; 
    ios_base::sync_with_stdio(0); cin.tie(0);
    cin >> H >> W;
    K = H * W;
    // cout << H << "," << W << "," << K << endl; 
    i=0; 
    for(i=0; i< H; i++){
        int p,q;
        char s[30];
        cin >> s;
        strcpy(S[i],s);
        // cout << S[i] << endl; 
    }

    //print_v();
    init_DP();
    //print_DP();
    do_DP();
    // print_DP();
    print_maxd();
}



Measured memory_bytes: 896