#include <bits/stdc++.h>
using namespace std;
template <typename T>
using Matrix = vector<vector<T>>;
template <typename T>
Matrix<T> matrix(int R, int C, T x = T()) {
  return Matrix<T>(R, vector<T>(C, x));
}
using Graph = vector<vector<int>>;
struct BCD {
  int n;
  Graph graph;
  Matrix<int> distances;
  BCD(int n, Graph graph) : n(n), graph(graph) {
    distances = matrix<int>(n, n, n);
    for (int i = 0; i < n; i++) {
      distances[i][i] = 0;
      for (auto j : graph[i]) distances[i][j] = 1;
    }
    for (int k = 0; k < n; k++)
      for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
          distances[i][j] =
              min(distances[i][j], distances[i][k] + distances[k][j]);
  }
  double win_probability(int v1) {
    auto by_distance = vector<vector<int>>(n);
    for (int w1 = 0; w1 < n; w1++) by_distance[distances[v1][w1]].push_back(w1);
    auto result = 0.0;
    for (auto w1_candidates : by_distance)
      if (!w1_candidates.empty()) {
        auto size = static_cast<double>(w1_candidates.size());
        auto p_distance = size / n;
        result += max(1.0 / size, win_probability(w1_candidates)) * p_distance;
      }
    return result;
  }
  double win_probability(vector<int> w1_candidates) {
    auto w2_possible = vector<bool>(n);
    for (auto w1 : w1_candidates)
      for (auto w2 : graph[w1]) w2_possible[w2] = true;
    auto w2_candidates = vector<int>();
    for (int w2 = 0; w2 < n; w2++)
      if (w2_possible[w2]) w2_candidates.push_back(w2);
    auto w2_probabilities = vector<double>(n);
    auto p = 1.0 / static_cast<double>(w1_candidates.size());
    for (auto w1 : w1_candidates) {
      auto q = 1.0 / static_cast<double>(graph[w1].size());
      for (auto w2 : graph[w1]) w2_probabilities[w2] += p * q;
    }
    auto result = 0.0;
    auto maxes = vector<double>(n);
    for (int v2 = 0; v2 < n; v2++) {
      for (auto w2 : w2_candidates) {
        auto color = distances[v2][w2];
        maxes[color] = max(maxes[color], w2_probabilities[w2]);
      }
      auto option = 0.0;
      for (auto w2 : w2_candidates) {
        auto color = distances[v2][w2];
        option += maxes[color];
        maxes[color] = 0;
      }
      result = max(result, option);
    }
    return result;
  }
};
double solve(int n, Graph graph) {
  auto bcd = BCD(n, graph);
  auto result = 0.0;
  for (int v1 = 0; v1 < n; v1++) result = max(result, bcd.win_probability(v1));
  return result;
}
int main() {
  int n, m;
  cin >> n >> m;
  auto graph = Graph(n);
  for (int i = 0; i < m; i++) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    graph[a].push_back(b);
    graph[b].push_back(a);
  }
  cout << solve(n, graph) << endl;
}
