#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const ll INF = 1010000000000000017LL;
const ll MOD = 1000000007LL;

#define REP(i, n) for(ll i = 0 ; i < n; i++)

#define DEBUG(fmt, ...)
//#define DEBUG(fmt, ...) fprintf(stderr, fmt "\n", ##__VA_ARGS__)

int main(){
    std::cout<<std::fixed<<std::setprecision(10);

    ll H, W;

    cin >> H >> W;
    vector<vector<char>> table(H+2, vector<char>(W+2));

    REP(i, H+2){
        table[i][0] = '#';
        table[i][W+1] = '#';
    }

    REP(i, W+2){
        table[0][i] = '#';
        table[H+1][i] = '#';
    }

    REP(i, H){
        REP(j, W){
            cin >> table[i+1][j+1];
        }
    }

    ll maximum = 0;
    pair<ll,ll> null = make_pair(-1,-1);
    REP(i, H){ REP(j, W){
        pair<ll,ll> start = make_pair(i+1, j+1);
        if( table[i+1][j+1] == '#' ) continue;

        REP(k, H){ REP(l, W){
            pair<ll,ll> end = make_pair(k+1, l+1);
            if( table[k+1][l+1] == '#' ) continue;

            DEBUG("Start [%lld, %lld]", i+1, j+1);
            DEBUG("End   [%lld, %lld]", k+1, l+1);

            ll depth = 0;
            queue<pair<ll,ll>> q;
            vector<vector<bool>> visited(H+2, vector<bool>(W+2, false));
            q.push(start);
            visited[start.first][start.second] = true;
            q.push(null);
            while( !q.empty() ){
                pair<ll,ll> cur = q.front();
                q.pop();
                if ( cur == null ){
                    depth++;
                    if( !q.empty() ){
                        q.push(null);
                    }
                }else if ( cur == end ){
                    q.push(end);
                    break;
                }else{
                    DEBUG("visiting [%lld, %lld]", cur.first, cur.second);
                    pair<ll,ll> left  = make_pair(cur.first,   cur.second-1);
                    pair<ll,ll> right = make_pair(cur.first,   cur.second+1);
                    pair<ll,ll> up    = make_pair(cur.first-1, cur.second);
                    pair<ll,ll> down  = make_pair(cur.first+1, cur.second);
                    if( !visited[left.first][left.second] ){
                        if( table[left.first][left.second] == '.' ){
                            visited[left.first][left.second] = true;
                            q.push(left);
                        }
                    }
                    if( !visited[right.first][right.second] ){
                        if( table[right.first][right.second] == '.' ){
                            visited[right.first][right.second] = true;
                            q.push(right);
                        }
                    }
                    if( !visited[up.first][up.second] ){
                        if( table[up.first][up.second] == '.' ){
                            visited[up.first][up.second] = true;
                            q.push(up);
                        }
                    }
                    if( !visited[down.first][down.second] ){
                        if( table[down.first][down.second] == '.' ){
                            visited[down.first][down.second] = true;
                            q.push(down);
                        }
                    }
                }
            }

            if( !q.empty() ){
                DEBUG("DEPTH:%lld", depth);
                maximum = max( maximum, depth);
            }
        }}
   }}

    cout << maximum << endl;

    /*
    REP(i, H+2){
        REP(j, W+2){
            cout <<  table[i][j];
        }
        cout << endl;
    }
    */
}


Measured memory_bytes: 256