#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <ctime>
using namespace std;
typedef long long ll;
#define clr(x,a) memset(x,a,sizeof(x))
#define sz(x) (int)x.size()
#define see(x) cerr<<#x<<" "<<x<<endl
#define se(x) cerr<<" "<<x 
#define pb push_back
#define mk make_pair
#define X first
#define Y second
#define maxn 205
#define maxm 11005
#define type double 
double sqr(double x)
{
	return x*x;
}
const int inf = ~0u >> 1;
struct edge
{
    int u,v;
    type cost;
    int oldu,oldv;
    edge(){}
    edge(int a,int b,type c,int d,int e):u(a),v(b),cost(c),oldu(d),oldv(e){}
}e[maxm];
int pre[maxn],id[maxn],vis[maxn];
int mark;
type in[maxn];
type dirmst(int root,int nv,int ne)
{
    type ret = 0;
    int cnt = 0;
    int oldroot = root;
    while(1)
    {
        cnt++;
        fill(in,in + nv,inf);
        for(int i = 0;i < ne;i++)
        {
            int u = e[i].u;
            int v = e[i].v;
            if(e[i].cost < in[v] && u != v)
            {
                if(e[i].oldu == oldroot)
                    mark = e[i].oldv;
                pre[v] = u;
                in[v] = e[i].cost;
            }
        }
        for(int i = 0;i <nv;i++)
        {
            if(i == root)
                continue;
            if(in[i] == inf)
                return -1;
        }
        int cntnode = 0;
        fill(id,id + nv,-1);
        fill(vis,vis + nv,-1);
        in[root] = 0;
        for(int i = 0;i < nv;i++)
        {
            ret += in[i];
            int v = i;
            while(vis[v] != i && id[v] == -1 && v != root)
            {
                vis[v] = i;
                v = pre[v];
            }
            if(v != root && id[v] == -1)
            {
                for(int u = pre[v];u != v;u = pre[u])
                    id[u] = cntnode;
                id[v] = cntnode++;
            }
        }
        if(cntnode == 0)
            break;
        for(int i = 0;i < nv;i++)
            if(id[i] == -1)
                id[i] = cntnode++;
        for(int i = 0;i < ne;i++)
        {
            int v = e[i].v;
            e[i].u = id[e[i].u];
            e[i].v = id[e[i].v];
            if(e[i].u != e[i].v)
                e[i].cost -= in[v];
        }
        nv = cntnode;
        root = id[root];
    }
    return ret;
}

int n,m;
double dv[maxn],db[maxn][maxn];
double g[maxn][maxn],f[maxn][maxn];
void init()
{
	int i,j,k;
	clr(g,0);
	clr(dv,0);
	clr(db,0);
	for(i=1; i<=n;i++)
	{
		for(j=1; j<=m; j++)
		{
			scanf("%lf",&g[i][j]);
			dv[i]+=sqr(g[i][j]);
		}
	}
	for(i=1; i<=n ;i++)
	for(j=1; j<=n ;j++)
	{
		for(k=1; k<=m; k++)
		{
			db[i][j]+=g[i][k]*g[j][k];
		}
	}
}

int main()
{
	//freopen("in","r",stdin);
	int i,j,k;
    while(scanf("%d %d",&m,&n) == 2)
    {
    	init();
        int sum = 0;
        mark = -1;
        int el=0;
        clr(f,0);
        for(i=1; i<=n; i++)
        {
        	j=0;
        	f[j][i]=dv[i];
        	e[el++] = edge(j,i,f[j][i],j,i);
        	for(j=1; j<=n; j++)
        	if(i!=j)
        	{
        		f[j][i]=(dv[j]*dv[i]-db[i][j]*db[i][j])/dv[j];
        		e[el++] = edge(j,i,f[j][i],j,i);
        	}
        }
		
        double ans = dirmst(0,n + 1,el);
        printf("%.6f\n",ans);
    }
}

Measured memory_bytes: 0