// Slower C++ solution:
#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);

    }

}

// Faster C++ solution for the same problem (measured speedup: 1.987071041001437x):
#include <stdio.h>

#include <string.h>

#include <iostream>

#include <cmath>

#define clr(a,b) memset(a,b,sizeof(a))

using namespace std;



const int N=105;

const double dinf=1e10;



int n,m,pre[N],vis[N],cnt,ced[N],i,j,k;

double g[105][105],len[105];

double gra[105][105];



void dfs(int s)//dfs蛻、譏ッ蜷ヲ譛芽ァ」

{

    vis[s]=1;cnt++;

    for(int i=1;i<=n;i++)

        if(gra[s][i]<dinf&&!vis[i])

            dfs(i);

}



double ZHULIU(int s)

{

	clr(vis,0);cnt=0;

	dfs(s);if(cnt!=n)return -1;

    clr(ced,0);double ans=0;

    int i,j,k;//霑咎?逧?豈碑セ?・?束?檎ョ。莉門造

    do

	{

	    for(i=1;i<=n;i++)//貂?勁閾ェ邇ッ?御サ・蜿頑アよッ丈クェ轤ケ逧??霎ケ

	    {

	        if(ced[i]||i==s)continue;

	        pre[i]=1;

	        for(j=1;j<=n;j++)

                if(j!=s&&j!=i&&!ced[j]&&gra[pre[i]][i]>gra[j][i])

                    pre[i]=j;

	    }

	    pre[s]=s;

        for(i=1;i<=n;i++)

        {

            if(ced[i]||i==s)continue;

            clr(vis,0);

            for(j=i;j!=s&&!vis[j];j=pre[j])vis[j]=1;//蟇サ謇セ邇ッ?瑚「ォvis譬?ョー逧?弍邇ッ蜀?噪轤ケ

            if(j==s)continue;

            ans+=gra[pre[j]][j];

            for(i=pre[j];i!=j;i=pre[i])//謚顔識驥檎噪譚??蜉?芦ans荳ュ蜴サ

                ans+=gra[pre[i]][i],ced[i]=1;

            for(k=1;k<=n;k++)//霑吩クェ蜥御ク矩擇驍」荳ェfor蝨ィ郛ゥ轤ケ

                if(!ced[k]&&gra[k][j]<dinf)

                    gra[k][j]-=gra[pre[j]][j];

            for(i=pre[j];i!=j;i=pre[i])

                for(k=1;k<=n;k++)

                {

                    if(ced[k])continue;

                    gra[j][k]=min(gra[j][k],gra[i][k]);

                    if(gra[k][i]<dinf)

                        gra[k][j]=min(gra[k][j],gra[k][i]-gra[pre[i]][i]);

                }

            break;

        }

	}while(i<=n);

	for(int i=1;i<=n;i++)//謚贋ク肴弍蜑ゥ荳狗噪蜈・霎ケ驛ス蜉?ク?

        if(!ced[i]&&i!=s)ans+=gra[pre[i]][i];

	return ans;

}





int main(){

//    freopen("in.txt","r",stdin);

//    freopen("/home/axorb/in","r",stdin);

    scanf("%d%d",&m,&n);n++;

    for(i=2;i<=n;i++){

        for(j=1;j<=m;j++){

            scanf("%lf",&g[i][j]);

            len[i]+=g[i][j]*g[i][j];

        }

        len[i]=sqrt(len[i]);

        gra[1][i]=len[i]*len[i];

        gra[i][1]=dinf;

    }

    for(i=2;i<=n;i++){

        for(j=2;j<=n;j++){

            double tmp=0;

            if(i==j) gra[i][j]=dinf;

            for(k=1;k<=m;k++){

                tmp+=g[i][k]*g[j][k];

            }

            double ang=tmp/len[i]/len[j];

            ang=sqrt(1-ang*ang);

            gra[i][j]=(len[j]*ang)*(len[j]*ang);

        }

    }

    printf("%.10lf\n",ZHULIU(1));

    return 0;

}