#include <bits/stdc++.h>
const int N = 42;
const int B = 20;
int Max[1 << (B + 1)];
bool G[N][N];
int Mid;
std::vector<int> S;
int M;
int cN;
int Res;
void Left(int x) {
  if (x >= Mid)
    Max[M] = std::max((int)S.size(), Max[M]);
  else {
    bool all = true;
    for (auto i : S) all &= G[i][x];
    if (all) {
      M |= 1 << x;
      S.push_back(x);
      Left(x + 1);
      M &= ~(1 << x);
      S.pop_back();
    }
    Left(x + 1);
  }
}
void MaxLeft(int n) {
  for (int i = 0; i < (1 << Mid); i++) {
    for (int x = 0; x < Mid; x++) {
      int mask = 1 << x;
      if (i & mask) Max[i] = std::max(Max[i], Max[i ^ mask]);
    }
  }
}
void Right(int x) {
  if (x >= cN) {
    int left = (1 << Mid) - 1;
    for (int l = 0; l < Mid; l++) {
      for (auto s : S)
        if (!G[s][l]) left &= ~(1 << l);
    }
    Res = std::max(Res, (int)(Max[left] + S.size()));
  } else {
    bool all = true;
    for (auto s : S) all &= G[s][x];
    if (all) {
      M |= 1 << x;
      S.push_back(x);
      Right(x + 1);
      M &= ~(1 << x);
      S.pop_back();
    }
    Right(x + 1);
  }
}
void QuickMaths(int n, double k) {
  double res = (k / Res) * (k / Res) * Res * (Res - 1) / 2;
  printf("%lf\n", res);
}
void Solve(int n, int k) {
  int t;
  cN = n;
  S.reserve(n);
  for (int x = 0; x < n; x++) {
    for (int y = 0; y < n; y++) scanf("%d", &t), G[x][y] = t == 1;
  }
  Mid = n / 2;
  Left(0);
  MaxLeft(0);
  S.clear();
  Right(Mid);
  QuickMaths(n, k);
}
int main() {
  int n, k;
  scanf("%d%d", &n, &k);
  Solve(n, k);
  return 0;
}
