#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;
const int N = 3e5 + 10, M = 3e5 + 10;
int vcompNum, ecompNum, I, m;
int first[N], low[N], vis[N], ecomp[N];
int nxt[2 * M], ep[2 * M], vcomp[2 * M];
stack<int> edges, verts;
void init() {
  m = 0;
  memset(first, -1, sizeof(first));
}
void add_edge(int a, int b) {
  nxt[m] = first[ep[m] = a], first[ep[m]] = m, ++m;
  nxt[m] = first[ep[m] = b], first[ep[m]] = m;
  ++m;
}
void biconnected(const pair<int, int>& p) {
  int v, E;
  low[p.first] = vis[p.first] = ++I;
  verts.push(p.first);
  for (int e = first[p.first]; e != -1; e = nxt[e]) {
    v = ep[e ^ 1];
    if (!vis[v]) {
      edges.push(e);
      biconnected({v, e});
      low[p.first] = min(low[p.first], low[v]);
      if (vis[p.first] <= low[v]) {
        do {
          E = edges.top();
          edges.pop();
          vcomp[E] = vcomp[E ^ 1] = vcompNum;
        } while (e != E && e != (E ^ 1));
        ++vcompNum;
      }
    } else if (vis[v] < vis[p.first] && e != (p.second ^ 1)) {
      low[p.first] = min(low[p.first], vis[v]);
      edges.push(e);
    } else if (v == p.first)
      vcomp[e] = vcomp[e ^ 1] = vcompNum++;
  }
  if (vis[p.first] <= low[p.first]) {
    do {
      v = verts.top();
      verts.pop();
      ecomp[v] = ecompNum;
    } while (v != p.first);
    ++ecompNum;
  }
}
void get_bcc(int n) {
  memset(vis, 0, sizeof vis);
  vcompNum = ecompNum = I = 0;
  for (int i = 0; i < n; ++i)
    if (!vis[i]) biconnected({i, -1});
}
bool isCutVertex(int u) {
  for (int e = first[u]; e != -1; e = nxt[e])
    if (vcomp[e] != vcomp[first[u]]) return true;
  return false;
}
bool isCutEdge(int e) { return ecomp[ep[e]] != ecomp[ep[e ^ 1]]; }
vector<int> adj2[N];
set<int> adj[N];
int d[N];
void dfs(int cur, int par = -1) {
  for (int i : adj[cur]) {
    if (i != par) {
      d[i] = d[cur] + 1;
      dfs(i, cur);
    }
  }
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  init();
  int n, mm;
  cin >> n >> mm;
  for (int i = 0; i < mm; i++) {
    int x, y;
    cin >> x >> y;
    adj2[x - 1].push_back(y - 1);
    adj2[y - 1].push_back(x - 1);
    add_edge(x - 1, y - 1);
  }
  get_bcc(n);
  for (int i = 0; i < n; i++) {
    for (int j : adj2[i]) {
      if (ecomp[j] != ecomp[i]) {
        adj[ecomp[j]].insert(ecomp[i]);
        adj[ecomp[i]].insert(ecomp[j]);
      }
    }
  }
  d[0] = 0;
  dfs(0);
  int best = -1, bv;
  for (int i = 0; i < ecompNum; i++) {
    if (d[i] > best) {
      best = d[i];
      bv = i;
    }
  }
  memset(d, 0, sizeof d);
  d[bv] = 0;
  dfs(bv);
  for (int i = 0; i < ecompNum; i++) {
    if (d[i] > best) {
      best = d[i];
    }
  }
  cout << best << '\n';
  return 0;
}
