#include <bits/stdc++.h>
using namespace std;
const int maxn = 600010;
int cnt;
int low[maxn], dfn[maxn], times, q[maxn], head[maxn], scc_cnt, scc[maxn], top;
vector<int> G[maxn];
int dis[maxn], S, T, ans;
struct edge {
  int from;
  int to;
  int next;
} e[maxn];
void add(int u, int v) {
  ++cnt;
  e[cnt].from = u;
  e[cnt].next = head[u];
  e[cnt].to = v;
  head[u] = cnt;
}
void tarjan(int u, int fa) {
  dfn[u] = low[u] = ++times;
  q[++top] = u;
  for (int i = head[u]; i; i = e[i].next) {
    int v = e[i].to;
    if (v == fa) continue;
    if (!dfn[v]) {
      tarjan(v, u);
      low[u] = min(low[u], low[v]);
    } else
      low[u] = min(low[u], dfn[v]);
  }
  if (low[u] == dfn[u]) {
    scc_cnt++;
    while (true) {
      int x = q[top--];
      scc[x] = scc_cnt;
      if (x == u) break;
    }
  }
}
void dfs(int u, int f) {
  dis[u] = dis[f] + 1;
  for (int i = 0; i < G[u].size(); i++) {
    if (G[u][i] != f) dfs(G[u][i], u);
  }
}
int main() {
  int N, M, u, v, i, j;
  scanf("%d%d", &N, &M);
  for (i = 1; i <= M; i++) {
    scanf("%d%d", &u, &v);
    add(u, v);
    add(v, u);
  }
  tarjan(1, 0);
  for (i = 1; i <= N; i++) {
    for (j = head[i]; j; j = e[j].next) {
      int v = e[j].to;
      if (scc[i] != scc[v]) G[scc[i]].push_back(scc[v]);
    }
  }
  dfs(1, 0);
  for (i = 1; i <= scc_cnt; i++)
    if (dis[i] > dis[S]) S = i;
  dfs(S, 0);
  for (i = 1; i <= scc_cnt; i++) ans = max(ans, dis[i] - 1);
  printf("%d\n", ans);
  return 0;
}
