#include <bits/stdc++.h>
using namespace std;
const long long INF = 1e18;
const int inf = 1e9;
const int mod = 1e9 + 7;
long long powmod(long long a, long long b) {
  long long res = 1;
  a %= mod;
  for (; b; b >>= 1) {
    if (b & 1) res = res * a % mod;
    a = a * a % mod;
  }
  return res;
}
int gcd(int a, int b) {
  while (b != 0) {
    int t = b;
    b = a % b;
    a = t;
  }
  return a;
}
void debug(int* a, int n) {
  for (int i = 0; i < n; i++) cout << a[i] << " ";
  cout << '\n';
}
void debug(vector<int> b, int n) {
  for (int i = 0; i < n; i++) cout << b[i] << " ";
  cout << '\n';
}
int tim = 0, grp = 1;
int u[300005], v[300005], comp[300005];
bool vis[300005], vis2[300005], isBridge[300005];
int tin[300005], tout[300005], minAncestor[300005];
queue<int> Q[300005];
vector<pair<int, int> > g[300005];
vector<int> tree[300005], vertices[300005];
void dfs(int k, int par) {
  vis[k] = 1;
  tin[k] = ++tim;
  minAncestor[k] = tin[k];
  for (auto it : g[k]) {
    if (it.first == par) continue;
    if (vis[it.first]) {
      minAncestor[k] = min(minAncestor[k], tin[it.first]);
      continue;
    }
    dfs(it.first, k);
    minAncestor[k] = min(minAncestor[k], minAncestor[it.first]);
    if (minAncestor[it.first] > tin[k]) isBridge[it.second] = 1;
  }
  tout[k] = tim;
}
void dfs2(int k) {
  int comp = grp;
  Q[comp].push(k);
  vis2[k] = 1;
  while (!Q[comp].empty()) {
    int u = Q[comp].front();
    Q[comp].pop();
    vertices[comp].push_back(u);
    for (auto it : g[u]) {
      int v = it.first;
      int edgeidx = it.second;
      if (vis2[v]) continue;
      if (isBridge[edgeidx]) {
        grp++;
        tree[comp].push_back(grp);
        tree[grp].push_back(comp);
        dfs2(v);
      } else {
        Q[comp].push(v);
        vis2[v] = 1;
      }
    }
  }
}
int vis11[300005], vis22[300005];
int level[300005];
int level1[300005];
int main() {
  int n, m, i, t1, t2, j;
  cin >> n >> m;
  for (i = 0; i < m; i++) {
    cin >> t1 >> t2;
    g[t1].push_back({t2, i});
    g[t2].push_back({t1, i});
  }
  dfs(1, -1);
  dfs2(1);
  int ans = 0;
  for (int i = 0; i < m; i++) {
    if (isBridge[i] != 0) {
      ans = 1;
    }
  }
  if (ans == 0) {
    cout << ans << endl;
    return 0;
  }
  queue<int> me;
  me.push(1);
  vis11[1] = 1;
  int maxi = 1;
  while (!me.empty()) {
    int t = me.front();
    me.pop();
    for (int i = 0; i < tree[t].size(); i++) {
      if (vis11[tree[t][i]] == 0) {
        vis11[tree[t][i]] = 1;
        level[tree[t][i]] = level[t] + 1;
        if (level[tree[t][i]] > level[maxi]) {
          maxi = tree[t][i];
        }
        me.push(tree[t][i]);
      }
    }
  }
  ans = 1;
  vis22[maxi] = 1;
  me.push(maxi);
  while (!me.empty()) {
    int t = me.front();
    me.pop();
    for (int i = 0; i < tree[t].size(); i++) {
      if (vis22[tree[t][i]] == 0) {
        vis22[tree[t][i]] = 1;
        level1[tree[t][i]] = level1[t] + 1;
        if (level1[tree[t][i]] > level1[maxi]) {
          maxi = tree[t][i];
        }
        me.push(tree[t][i]);
      }
    }
  }
  ans = level1[maxi];
  cout << ans << endl;
  return 0;
}
