#include <bits/stdc++.h>
using namespace std;
template <class T>
bool umin(T& a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
bool umax(T& a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
int tin[300009], fup[300009], TIM, S, comp[300009];
stack<int> st;
pair<int, int> arr[300009];
vector<int> adj[300009];
void dfs(int nd, int pr) {
  tin[nd] = fup[nd] = ++TIM;
  st.push(nd);
  for (int i = 0; i < int(adj[nd].size()); i++) {
    int to = adj[nd][i];
    if (to == pr) continue;
    if (!tin[to]) {
      dfs(to, nd);
      umin(fup[nd], fup[to]);
    } else
      umin(fup[nd], tin[to]);
  }
  if (fup[nd] == tin[nd]) {
    int aux;
    S++;
    do {
      aux = st.top();
      st.pop();
      comp[aux] = S;
    } while (aux != nd);
  }
}
int mx, who;
void dfs(int nd, int pr, int lvl) {
  if (umax(mx, lvl)) who = nd;
  for (int i = 0; i < int(adj[nd].size()); i++) {
    int to = adj[nd][i];
    if (to == pr) continue;
    dfs(to, nd, lvl + 1);
  }
}
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    arr[i] = make_pair(u, v);
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  dfs(1, -1);
  for (int i = 1; i <= n; i++) adj[i].clear();
  for (int i = 1; i <= m; i++) {
    int u = arr[i].first, v = arr[i].second;
    if (comp[u] != comp[v]) {
      adj[comp[u]].push_back(comp[v]);
      adj[comp[v]].push_back(comp[u]);
    }
  }
  mx = -1;
  dfs(1, -1, 0);
  mx = -1;
  dfs(who, -1, 0);
  printf("%d\n", mx);
  return 0;
}
