#include <bits/stdc++.h>
using namespace std;
bool vis[300005];
vector<int> graph[300005], t[300005];
int sz[300005], par[300005], in[300005], rep[300005], t1 = 0;
vector<pair<int, int>> bridges;
int root(int a) {
  while (a != par[a]) a = par[par[a]];
  return a;
}
void unite(int a, int b) {
  int x = root(a), y = root(b);
  if (x != y) {
    if (sz[x] > sz[y]) swap(x, y);
    sz[y] += sz[x];
    par[x] = y;
  }
}
int dfs(int u, int p = -1) {
  vis[u] = true;
  t1++;
  in[u] = t1;
  rep[u] = t1;
  for (int j = 0; j < graph[u].size(); j++) {
    int v = graph[u][j];
    if (v == p) continue;
    if (vis[v])
      rep[u] = min(rep[u], in[v]);
    else {
      dfs(v, u);
      rep[u] = min(rep[u], rep[v]);
      if (rep[v] > in[u]) {
        bridges.push_back(make_pair(u, v));
      } else
        unite(u, v);
    }
  }
  return rep[u];
}
void dfs2(int u, int l, int &M, int &z) {
  vis[u] = true;
  if (l > M) {
    M = l;
    z = u;
  }
  for (int j = 0; j < t[u].size(); j++) {
    int v = t[u][j];
    if (!vis[v]) dfs2(v, l + 1, M, z);
  }
}
int main() {
  ios_base::sync_with_stdio(false), cin.tie(0);
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= n; i++) {
    sz[i] = 1;
    par[i] = i;
  }
  for (int i = 0; i < m; i++) {
    int a, b;
    cin >> a >> b;
    graph[a].push_back(b);
    graph[b].push_back(a);
  }
  dfs(1);
  int res;
  for (int j = 0; j < (int)bridges.size(); j++) {
    int a = bridges[j].first, b = bridges[j].second;
    a = root(a), b = root(b);
    res = a;
    t[a].push_back(b);
    t[b].push_back(a);
  }
  int M = 0, z = res;
  memset(vis, 0, sizeof(vis));
  dfs2(res, 0, M, z);
  M = 0;
  int y = z;
  memset(vis, 0, sizeof(vis));
  dfs2(z, 0, M, y);
  cout << M;
  return 0;
}
