#include <bits/stdc++.h>
using namespace std;
int disc[300005], low[300005], lng, bsr, cnt, dis[300005], tim, n, m,
    par[300005], st;
vector<int> adj[300005], vec[300005];
bool vis[300005];
vector<pair<int, int> > br;
int root(int a) {
  if (par[a] == a) return a;
  return par[a] = root(par[a]);
}
void merge(int a, int b) { par[root(a)] = root(b); }
void dfs(int u, int p) {
  disc[u] = low[u] = tim++;
  for (auto v : adj[u]) {
    if (disc[v] == -1) {
      dfs(v, u);
      if (low[v] <= disc[u]) {
        merge(v, u);
      } else {
        br.push_back({u, v});
      }
      low[u] = min(low[u], low[v]);
    } else if (v != p) {
      low[u] = min(low[u], disc[v]);
    }
  }
}
void dfs1(int u, int p) {
  dis[u] = dis[p] + 1;
  for (auto nxt : vec[u]) {
    if (nxt != p) {
      dfs1(nxt, u);
    }
  }
}
int main() {
  cin >> n >> m;
  for (int i = 1; i <= n; i++) par[i] = i;
  memset(disc, -1, sizeof(disc));
  for (int i = 1; i <= m; i++) {
    int a, b;
    cin >> a >> b;
    adj[a].push_back(b);
    adj[b].push_back(a);
  }
  dfs(1, 0);
  for (auto v : br) {
    vec[root(v.first)].push_back(root(v.second));
    vec[root(v.second)].push_back(root(v.first));
  }
  dfs1(root(1), 0);
  for (int i = 1; i <= n; i++) {
    if (dis[i] > lng) {
      st = i;
      lng = dis[i];
    }
  }
  memset(dis, 0, sizeof(dis));
  dfs1(st, 0);
  for (int i = 1; i <= n; i++) lng = max(lng, dis[i]);
  cout << lng - 1 << endl;
}
