#include <bits/stdc++.h>
using namespace std;
int cont;
vector<vector<int> > adj, adj2;
vector<int> vis, dfsnum, dfslow, dualdfsnum, comp;
vector<pair<int, int> > bridgeslist;
queue<pair<int, int> > qu;
set<pair<int, int> > st;
int bridges(int cur, int pater) {
  vis[cur] = 1;
  dfsnum[cur] = dfslow[cur] = ++cont;
  dualdfsnum[cont] = cur;
  for (int i = 0; i < adj[cur].size(); i++) {
    if (adj[cur][i] == pater) continue;
    if (!vis[adj[cur][i]]) {
      dfslow[cur] = min(dfslow[cur], bridges(adj[cur][i], cur));
      if (dfslow[adj[cur][i]] > dfsnum[cur])
        bridgeslist.push_back(pair<int, int>(adj[cur][i], cur));
    } else
      dfslow[cur] = min(dfslow[cur], dfsnum[adj[cur][i]]);
  }
  return dfslow[cur];
}
int main() {
  if (fopen("input.txt", "r")) freopen("input.txt", "r", stdin);
  int n, m, x, y;
  scanf("%d %d ", &n, &m);
  adj.assign(n + 1, vector<int>());
  for (int i = 0; i < m; i++) {
    scanf("%d %d ", &x, &y);
    adj[x].push_back(y);
    adj[y].push_back(x);
  }
  vis.assign(n + 1, 0);
  dfsnum.assign(n + 1, 0);
  dfslow.assign(n + 1, 0);
  dualdfsnum.assign(n + 1, 0);
  cont = 0;
  bridges(1, -1);
  for (int i = 0; i < bridgeslist.size(); i++) {
    st.insert(pair<int, int>(bridgeslist[i].first, bridgeslist[i].second));
    st.insert(pair<int, int>(bridgeslist[i].second, bridgeslist[i].first));
  }
  comp.assign(n + 1, 0);
  vis.assign(n + 1, 0);
  for (int i = 1; i < n + 1; i++) {
    if (comp[i]) continue;
    qu.push(pair<int, int>(i, i));
    while (!qu.empty()) {
      pair<int, int> u = qu.front();
      qu.pop();
      if (vis[u.first]) continue;
      vis[u.first] = 1;
      comp[u.first] = u.second;
      for (int j = 0; j < adj[u.first].size(); j++)
        if (!vis[adj[u.first][j]] &&
            st.find(pair<int, int>(u.first, adj[u.first][j])) == st.end())
          qu.push(pair<int, int>(adj[u.first][j], u.second));
    }
  }
  adj2.assign(n + 1, vector<int>());
  for (int i = 0; i < bridgeslist.size(); i++) {
    x = comp[bridgeslist[i].first];
    y = comp[bridgeslist[i].second];
    adj2[x].push_back(y);
    adj2[y].push_back(x);
  }
  int last = 1;
  qu.push(pair<int, int>(1, 0));
  vis.assign(n + 1, 0);
  while (!qu.empty()) {
    pair<int, int> u = qu.front();
    qu.pop();
    if (vis[u.first]) continue;
    vis[u.first] = 1;
    last = u.first;
    for (int i = 0; i < adj2[u.first].size(); i++)
      if (!vis[adj2[u.first][i]]) qu.push(pair<int, int>(adj2[u.first][i], 0));
  }
  qu.push(pair<int, int>(last, 0));
  vis.assign(n + 1, -1);
  while (!qu.empty()) {
    pair<int, int> u = qu.front();
    qu.pop();
    if (vis[u.first] != -1) continue;
    vis[u.first] = u.second;
    last = u.first;
    for (int i = 0; i < adj2[u.first].size(); i++)
      if (vis[adj2[u.first][i]] == -1)
        qu.push(pair<int, int>(adj2[u.first][i], u.second + 1));
  }
  printf("%d", vis[last]);
  return 0;
}
