#include <bits/stdc++.h>
using std::cin;
using std::cout;
using std::endl;
const int MAXN = 300000 + 5;
struct edge {
  int v, nxt;
} ed[MAXN * 2], ED2[MAXN * 2];
int n, m, en, EN2, hd[MAXN], HD2[MAXN];
int bcc_tot, bcc_belong[MAXN], sz, dfn[MAXN], low[MAXN];
std::stack<int> s;
void ins(int x, int y) { ed[++en] = (edge){y, hd[x]}, hd[x] = en; }
void INS2(int x, int y) { ED2[++EN2] = (edge){y, HD2[x]}, HD2[x] = EN2; }
void tarjan(int u, int fa) {
  dfn[u] = low[u] = ++sz, s.push(u);
  for (int i = hd[u]; i > 0; i = ed[i].nxt) {
    edge &e = ed[i];
    if (e.v == fa) continue;
    if (!dfn[e.v])
      tarjan(e.v, u), low[u] = std::min(low[u], low[e.v]);
    else if (dfn[e.v] < dfn[u])
      low[u] = std::min(low[u], dfn[e.v]);
  }
  if (low[u] == dfn[u]) {
    int e;
    bcc_tot++;
    do {
      e = s.top();
      s.pop();
      bcc_belong[e] = bcc_tot;
    } while (e != u);
  }
}
int dis[MAXN];
void dfs(int u, int fa) {
  dis[u] = dis[fa] + 1;
  for (int i = HD2[u]; i > 0; i = ED2[i].nxt) {
    edge &e = ED2[i];
    if (e.v != fa) dfs(e.v, u);
  }
}
void clean() {
  en = EN2 = 0;
  memset(hd, 0, sizeof hd), memset(HD2, 0, sizeof HD2);
  bcc_tot = sz = 0, memset(dfn, 0, sizeof dfn);
}
int solve() {
  clean();
  for (int x, y, i = 1; i <= m; i++)
    scanf("%d%d", &x, &y), ins(x, y), ins(y, x);
  for (int i = 1; i <= n; i++)
    if (!dfn[i]) tarjan(i, 0);
  for (int u = 1; u <= n; u++) {
    for (int i = hd[u]; i > 0; i = ed[i].nxt) {
      edge &e = ed[i];
      if (bcc_belong[u] != bcc_belong[e.v])
        INS2(bcc_belong[u], bcc_belong[e.v]);
    }
  }
  memset(dis, 0, sizeof dis);
  dfs(1, 0);
  int S = 1;
  for (int i = 2; i <= bcc_tot; i++)
    if (dis[i] > dis[S]) S = i;
  dfs(S, 0);
  int T = 1;
  for (int i = 2; i <= bcc_tot; i++)
    if (dis[i] > dis[T]) T = i;
  printf("%d\n", dis[T] - 1);
  return 0;
}
int main() {
  scanf("%d%d", &n, &m), solve();
  return 0;
}
