#include <bits/stdc++.h>
using namespace std;
template <class T>
inline bool uin(T& a, T b) {
  return a > b ? (a = b, true) : false;
}
template <class T>
inline bool uax(T& a, T b) {
  return a < b ? (a = b, true) : false;
}
struct dsu {
  vector<int> p;
  dsu(int n) : p(n, -1) {}
  inline int size(int x) { return -p[get(x)]; }
  inline bool same_set(int a, int b) { return get(a) == get(b); }
  int get(int x) { return p[x] < 0 ? x : p[x] = get(p[x]); }
  inline bool unite(int a, int b) {
    a = get(a);
    b = get(b);
    if (a == b) return false;
    if (p[a] > p[b]) swap(a, b);
    p[a] += p[b];
    p[b] = a;
    return true;
  }
};
const int MAX_N = 3e5 + 10;
int tin[MAX_N], low[MAX_N], bcc[MAX_N];
vector<int> g[MAX_N], cg[MAX_N];
bool visited[MAX_N];
int timer, sz, N, M;
stack<int> st;
void dfs1(int v, int p) {
  tin[v] = low[v] = ++timer;
  st.push(v);
  for (int ch : g[v]) {
    if (ch == p) continue;
    if (tin[ch]) {
      uin(low[v], tin[ch]);
      continue;
    }
    dfs1(ch, v);
    uin(low[v], low[ch]);
  }
  if (low[v] != tin[v]) return;
  while (true) {
    int x = st.top();
    st.pop();
    bcc[x] = sz;
    if (x == v) break;
  }
  ++sz;
}
int dist[MAX_N], max_dist = -1, farthest = -1;
void dfs2(int v, int p) {
  if (uax(max_dist, dist[v])) farthest = v;
  for (int ch : cg[v]) {
    if (ch == p) continue;
    dist[ch] = dist[v] + 1;
    dfs2(ch, v);
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> N >> M;
  for (int u, v, i = 0; i < M; ++i) {
    cin >> u >> v;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  dfs1(1, 0);
  dsu uf(sz);
  for (int v = 1; v <= N; ++v) {
    for (int ch : g[v]) {
      if (!uf.unite(bcc[v], bcc[ch])) continue;
      cg[bcc[v]].push_back(bcc[ch]);
      cg[bcc[ch]].push_back(bcc[v]);
    }
  }
  dfs2(1, 1);
  max_dist = -1;
  dist[farthest] = 0;
  dfs2(farthest, farthest);
  cout << max_dist << '\n';
}
