#include <bits/stdc++.h>
using namespace std;
#define FOR(i,k,n) for(int i = (int)(k); i < (int)(n); i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(a) a.begin(), a.end()
#define MS(m,v) memset(m,v,sizeof(m))
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-12;
template<class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template<class T> T &chmax(T &a, const T &b) { return a = max(a, b); }

/*--------------------template--------------------*/

typedef ld Weight;
struct Edge {
	int src, dst;
	Weight weight;
	Edge(int src, int dst, Weight weight) :
		src(src), dst(dst), weight(weight) { }
};
bool operator < (const Edge &e, const Edge &f) {
	return e.weight != f.weight ? e.weight > f.weight : // !!INVERSE!!
	e.src != f.src ? e.src < f.src : e.dst < f.dst;
}
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;

typedef vector<Weight> Array;
typedef vector<Array> Matrix;

void backward_traverse(int v, int s, int r,
	Graph &gg,
	vector<int> &no, vector< vector<int> > &comp,
	vector<int> &prev, vector< vector<int> > &next, vector<Weight> &mcost,
	vector<int> &mark, Weight &cost, bool &found) {
	const int n = gg.size();
	if (mark[v]) {
		vector<int> temp = no;
		found = true;
		do {
			cost += mcost[v];
			v = prev[v];
			if (v != s) {
				while (comp[v].size() > 0) {
					no[comp[v].back()] = s;
					comp[s].push_back(comp[v].back());
					comp[v].pop_back();
				}
			}
		} while (v != s);

		for (int k = 0; k < comp[s].size(); ++k) {
			int j = comp[s][k];
			if (j != r)
				for (int l = 0; l < gg[j].size(); ++l)
					if (no[gg[j][l].src] != s)
						gg[j][l].weight -= mcost[temp[j]];
		}
	}
	mark[v] = true;
	for (int k = 0; k < next[v].size(); ++k) {
		int i = next[v][k];
		if (no[i] != no[v] && prev[no[i]] == v)
			if (!mark[no[i]] || i == s)
				backward_traverse(i, s, r, gg,
					no, comp, prev, next, mcost, mark, cost, found);
	}
}

Weight minimum_spanning_arborescence(int r, Graph &g) {
	const int n = g.size();
	Graph gg(n);
	for (int i = 0; i < g.size(); ++i)
		for (int j = 0; j < g[i].size(); ++j)
			gg[g[i][j].dst].push_back(g[i][j]);

	vector<int> no(n);
	vector< vector<int> > comp(n);
	for (int i = 0; i < n; ++i) {
		no[i] = i;
		comp[i].push_back(i);
	}
	Weight cost = 0;
	while (1) {
		vector<int> prev(n, -1);
		vector<Weight> mcost(n, INF);

		for (int j = 0; j < n; ++j) {
			if (j == r) continue;
			for (int k = 0; k < gg[j].size(); ++k) {
				int i = gg[j][k].src;
				if (no[i] != no[j]) {
					if (gg[j][k].weight < mcost[no[j]]) {
						mcost[no[j]] = gg[j][k].weight;
						prev[no[j]] = no[i];
					}
				}
			}
		}
		vector< vector<int> > next(n);
		for (int i = 0; i < n; ++i)
			if (prev[i] >= 0)
				next[prev[i]].push_back(i);

		bool stop = true;
		vector<int> mark(n);
		for (int i = 0; i < n; ++i) {
			if (i == r || mark[i] || comp[i].size() == 0) continue;
			bool found = false;
			backward_traverse(i, i, r, gg,
				no, comp, prev, next, mcost, mark, cost, found);
			if (found) stop = false;
		}
		if (stop) {
			for (int i = 0; i < n; ++i)
				if (prev[i] >= 0)
					cost += mcost[i];
			return cost;
		}
	}
}

int n, m;
ld calc(vector<ld> v1, vector<ld> v2)
{
	ld lb = -INF, ub = INF;
	REP(rp, 100)
	{
		ld d1 = (lb * 2 + ub) / 3, d2 = (lb + ub * 2) / 3;
		ld sum1 = 0, sum2 = 0;
		REP(i, n)
		{
			sum1 += pow(v2[i] - d1 * v1[i], 2);
			sum2 += pow(v2[i] - d2 * v1[i], 2);
		}
		if (sum1 < sum2) ub = d2;
		else lb = d1;
	}
	ld res = 0;
	REP(i, n)
	{
		res += pow(v2[i] - lb * v1[i], 2);
	}
	return res;
}

int main()
{
	cin.sync_with_stdio(false); cout << fixed << setprecision(10);
	cin >> n >> m;
	vector<vector<ld>> v(m + 1, vector<ld>(n));
	REP(i, m)REP(j, n) cin >> v[i + 1][j];
	Graph g(m + 1);
	REP(i, m + 1)REP(j, m + 1)
	{
		if (i == j) continue;
		g[i].push_back(Edge{ i,j,calc(v[i], v[j]) });
	}
	cout << minimum_spanning_arborescence(0, g) << endl;
	return 0;
}

Measured memory_bytes: 4068