#include <bits/stdc++.h>
using namespace std;
int f[300005];
int tin[300005];
int timer = 0;
vector<int> g[300005];
vector<int> ch[300005];
int ans = 0;
int dfs(int v, int from = -1) {
  timer++;
  tin[v] = timer;
  f[v] = tin[v];
  for (int i = 0; i < (int)g[v].size(); i++) {
    int to = g[v][i];
    if (to == from) continue;
    if (tin[to] == 0) {
      f[v] = min(f[v], dfs(to, v));
    } else {
      f[v] = min(f[v], tin[to]);
    }
    if (f[to] > tin[v]) {
      ans++;
      ch[v][i] = 1;
    }
  }
  return f[v];
}
int T = 1;
int id[300005];
vector<int> tree[300005];
void dfs2(int v, int cur = 1) {
  id[v] = cur;
  for (int i = 0; i < (int)g[v].size(); i++) {
    int to = g[v][i];
    if (id[to] == 0) {
      if (ch[v][i] == 1) {
        T++;
        tree[cur].push_back(T);
        tree[T].push_back(cur);
        dfs2(to, T);
      } else
        dfs2(to, cur);
    }
  }
}
queue<pair<int, int> > q;
int was[300005];
pair<int, int> bfs(int s, int n) {
  pair<int, int> res;
  fill(was, was + n + 1, 0);
  q.push({s, 1});
  was[s] = 1;
  while (!q.empty()) {
    pair<int, int> ve = q.front();
    res = ve;
    q.pop();
    for (auto to : tree[ve.first]) {
      if (was[to] == 0) {
        was[to] = ve.second + 1;
        q.push({to, was[to]});
      }
    }
  }
  return res;
}
int main() {
  int n, m;
  cin >> n >> m;
  for (int i = 0, a, b; i < m; i++) {
    cin >> a >> b;
    g[a].push_back(b);
    g[b].push_back(a);
    ch[a].push_back(0);
    ch[b].push_back(0);
  }
  dfs(1);
  dfs2(1);
  pair<int, int> ve = bfs(1, n);
  ve = bfs(ve.first, n);
  cout << ve.second - 1;
}
