#include <bits/stdc++.h>
using namespace std;
long long int m, t, y, z, j, i, r, m1, m2, n, l, d, blocks, x, k, c, h, q;
long long int tin[500008], low[500008], timer, vis[500008], parent[500008],
    sz[500008], currht, root;
vector<long long int> g[500008];
long long int find(long long int x) {
  return parent[x] == x ? x : parent[x] = find(parent[x]);
}
void merge(long long int x, long long int y) {
  x = find(x);
  y = find(y);
  if (x != y) {
    if (sz[x] > sz[y]) swap(x, y);
    parent[x] = y;
    sz[y] += sz[x];
  }
}
void dfs(long long int node = 1, long long int par = -1) {
  vis[node]++;
  tin[node] = low[node] = ++timer;
  for (auto x : g[node]) {
    if (x == par) continue;
    if (vis[x]) {
      low[node] = min(low[node], tin[x]);
    } else {
      dfs(x, node);
      low[node] = min(low[node], low[x]);
      if (low[x] <= tin[node]) {
        merge(x, node);
      }
    }
  }
}
void dfs2(long long int node, long long int par = -1, long long int d = 0) {
  if (currht < d) {
    currht = d;
    root = node;
  }
  vis[node]++;
  for (auto x : g[node]) {
    if (!vis[x]) dfs2(x, node, d + 1);
  }
}
int main() {
  cin >> n >> m;
  vector<pair<long long int, long long int> > edges;
  while (m--) {
    cin >> x >> y;
    edges.push_back({x, y});
    g[x].push_back(y);
    g[y].push_back(x);
  }
  for (long long int i = 1; i < n + 1; i++) parent[i] = i, sz[i] = 1;
  dfs();
  for (long long int i = 1; i < n + 1; i++) g[i].clear();
  for (auto x : edges) {
    long long int yy = find(x.first), zz = find(x.second);
    if (yy != zz) {
      g[yy].push_back(zz);
      g[zz].push_back(yy);
    }
  }
  currht = -1;
  memset(vis, 0, sizeof(vis));
  dfs2(find(1));
  currht = -1;
  memset(vis, 0, sizeof(vis));
  dfs2(root);
  cout << currht;
}
