#include <bits/stdc++.h>
using namespace std;
using P = pair<int, int>;
struct Diameter {
  int from, to, d;
};
P farthest(int u, int p, vector<vector<int>> &g) {
  P r(0, u);
  for (auto e : g[u]) {
    if (e == p) continue;
    P c = farthest(e, u, g);
    c.first++;
    r = max(r, c);
  }
  return r;
}
Diameter tree_diameter(vector<vector<int>> &g) {
  P p = farthest(0, -1, g);
  P q = farthest(p.second, -1, g);
  return Diameter{p.second, q.second, q.first};
}
struct Lowlink {
  const vector<vector<int>> &g;
  vector<int> ord, low;
  vector<int> articulation;
  vector<P> bridge;
  int k;
  Lowlink(const vector<vector<int>> &g) : g(g) {}
  virtual void dfs(int idx, int par) {
    ord[idx] = k++;
    low[idx] = ord[idx];
    bool is_articulation = false;
    int cnt = 0;
    for (auto to : g[idx]) {
      if (ord[to] < 0) {
        ++cnt;
        dfs(to, idx);
        low[idx] = min(low[idx], low[to]);
        if (par != -1 && low[to] >= ord[idx]) is_articulation = true;
        if (ord[idx] < low[to]) bridge.push_back(P(min(idx, to), max(idx, to)));
      } else if (to != par) {
        low[idx] = min(low[idx], ord[to]);
      }
    }
    if (par == -1 && cnt > 1) is_articulation = true;
    if (is_articulation) articulation.push_back(idx);
  }
  virtual void build() {
    ord.assign(g.size(), -1);
    low.assign(g.size(), 0);
    k = 0;
    for (int i = 0; i < (int)g.size(); i++) {
      if (ord[i] < 0) dfs(i, -1);
    }
  }
};
struct TwoEdgeConnectedComponents : Lowlink {
  vector<int> comp;
  TwoEdgeConnectedComponents(vector<vector<int>> &g) : Lowlink(g) {}
  void dfs(int idx, int par, int &k) {
    if (par != -1 && ord[par] >= low[idx])
      comp[idx] = comp[par];
    else
      comp[idx] = k++;
    for (auto &to : g[idx]) {
      if (comp[to] == -1) dfs(to, idx, k);
    }
  }
  void build(vector<vector<int>> &t) {
    Lowlink::build();
    comp.assign(g.size(), -1);
    int k = 0;
    for (int i = 0; i < (int)g.size(); i++) {
      if (comp[i] == -1) dfs(i, -1, k);
    }
    t.resize(k);
    for (auto &e : bridge) {
      int x = comp[e.first], y = comp[e.second];
      t[x].push_back(y);
      t[y].push_back(x);
    }
  }
  int operator[](const int &k) { return comp[k]; }
};
int main() {
  int n, m, u, v;
  cin >> n >> m;
  vector<vector<int>> g(n);
  for (int i = 0; i < (int)m; i++) {
    cin >> u >> v;
    u--;
    v--;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  TwoEdgeConnectedComponents tecc(g);
  vector<vector<int>> t;
  tecc.build(t);
  cout << tree_diameter(t).d << endl;
}
