#include <bits/stdc++.h>
using namespace std;
bool vis[500005];
int low[500005], d[500005], par[500005], rnk[500005], level[500005], timer,
    root;
vector<int> adj[500005], tree[500005];
vector<pair<int, int>> bridges;
int get(int x) { return (par[x] == x ? x : par[x] = get(par[x])); }
void link(int x, int y) {
  x = get(x);
  y = get(y);
  if (x == y) return;
  if (rnk[x] > rnk[y]) swap(x, y);
  par[x] = y;
  rnk[y] += rnk[x];
}
void bridge_find(int u, int par) {
  vis[u] = 1;
  timer++;
  d[u] = low[u] = timer;
  for (auto x : adj[u]) {
    if (x == par) continue;
    if (vis[x])
      low[u] = min(low[u], d[x]);
    else {
      bridge_find(x, u);
      low[u] = min(low[u], low[x]);
      if (d[u] < low[x])
        bridges.push_back({u, x});
      else
        link(u, x);
    }
  }
}
void build() {
  for (auto z : bridges) {
    int x = get(z.first);
    int y = get(z.second);
    root = x;
    tree[x].push_back(y);
    tree[y].push_back(x);
  }
}
void dfs(int child, int par) {
  for (auto x : tree[child]) {
    if (x == par) continue;
    level[x] = level[child] + 1;
    dfs(x, child);
  }
}
int main() {
  int n, m;
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= n; i++) rnk[i] = 1, par[i] = i;
  for (int i = 0; i < m; i++) {
    int x, y;
    scanf("%d %d", &x, &y);
    adj[x].push_back(y);
    adj[y].push_back(x);
  }
  bridge_find(1, -1);
  build();
  dfs(root, -1);
  int ans = 0, mx = 0, cur;
  for (int i = 1; i <= n; i++) {
    if (mx < level[i]) {
      mx = level[i], cur = i;
    }
    level[i] = 0;
  }
  dfs(cur, -1);
  mx = 0;
  for (int i = 1; i <= n; i++) {
    mx = max(mx, level[i]);
  }
  cout << mx << endl;
}
