// Original C++ solution (slower):
#include<cstdio>

#include<cstring>

#include<cstdlib>

#include<cmath>

#include<algorithm>

#include<iostream>

using namespace std;

typedef long long LL;

const int V=120;

const int En=2100000;

struct Elf{int u,v;double len;}b[En];

const double oo=1e100;

double ret;

int N,M,Root;

int id[V],pre[V],cnt,vis[V];

double in[V];

bool TreeMST()

{

	ret=0.0;

	int i,u,v;

	while(1)

	{

		for(i=0;i<N;i++)

		in[i]=oo;

		memset(pre,-1,sizeof(pre));

		for(i=0;i<M;i++)

		{

			u=b[i].u;

			v=b[i].v;

			if(b[i].len<in[v]&&u!=v)

			{

				pre[v]=u;

				in[v]=b[i].len;

			}

		}

		for(i=0;i<N;i++)

		{

			if(i==Root)continue;

			if(pre[i]==-1)return false;

		}

		in[Root]=0;

		cnt=0;

		memset(id,-1,sizeof(id));

		memset(vis,-01,sizeof(vis));

		for(i=0;i<N;i++)

		{

			ret+=in[i];v=i;

			while(vis[v]!=i&&id[v]==-1&&v!=Root)

			{vis[v]=i;v=pre[v];}

			if(v!=Root&&id[v]==-1)

			{

				for(u=pre[v];u!=v;u=pre[u])

				id[u]=cnt;

				id[v]=cnt++;

			}

		}

		if(cnt==0)return true;

		for(i=0;i<N;i++)

		if(id[i]==-1)id[i]=cnt++;

		for(i=0;i<M;i++)

		{

			v=b[i].v;

			b[i].u=id[b[i].u];

			b[i].v=id[b[i].v];

			if(b[i].u!=b[i].v)

			b[i].len-=in[v];

		}

		N=cnt;

		Root=id[Root];

	//	for(i=0;i<N;i++)printf("%d ",pre[i]);

	//	printf("%d %d\n",cnt,Root);

	}

}

double sqr(double x){return x*x;}

int m,n;

double a[120][120];

double Cal(int x,int y,double r)

{

	double ret=0.0;

	for(int i=0;i<m;i++)

	ret+=sqr(a[x][i]-a[y][i]*r);

	return ret;

}

int i,j,k;

double lo,up,mid1,mid2;

int main()

{

	while(~scanf("%d%d",&m,&n))

	{

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

		{

			for(j=0;j<m;j++)

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

		}

		N=n+1;M=0;

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

		{

			b[M].u=0;

			b[M].v=i;

			double te=0.0;

			for(j=0;j<m;j++)

			te+=a[i][j]*a[i][j];

			b[M++].len=te;

		}

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

		{

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

			{

				if(i==j)continue;

				lo=-1e10;up=1e10;

				for(k=0;k<100;k++)

				{

					mid1=2.0*lo/3.0+up/3.0;

					mid2=lo/3.0+2.0*up/3.0;

					if(Cal(j,i,mid1)>Cal(j,i,mid2))lo=mid1;

					else up=mid2;

				}

				b[M].u=i;

				b[M].v=j;

				b[M++].len=Cal(j,i,lo);

			}

		}

	//	for(i=0;i<M;i++)

	//	printf("%d %d %.7f\n",b[i].u,b[i].v,b[i].len);

		Root=0;

		if(TreeMST())printf("%.8f\n",ret);

		else puts("Obsidian");

	}

}

// Optimized solution to the same problem (faster):
#include <cstdio>

#include <cstring>

#include <cmath>

#include <algorithm>

using namespace std;



#define N 105

#define eps 1e-8

#define INF 1e30



inline double sqr(double x) {

    return x * x;

}



int n, m;

double a[N][N], b[N][N], d[N][N];



double gao(int p, int q) {

    double s1 = 0, s2 = 0;

    for (int i = 1; i <= m; ++i) {

        s1 += a[p][i] * a[q][i];

        s2 += sqr(a[q][i]);

    }

    if (abs(s2) < eps) {

        double s = 0;

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

            s += sqr(a[p][i]);

        return s;

    }

    double k = s1 / s2;

    double ret = 0;

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

        ret += sqr(k * a[q][i] - a[p][i]);

    return ret;

}



double f[N];

bool vis[N];

double g[N][N];



int pre[N];

bool del[N], vst[N];

double solve(int v) {

    double res = 0;

    int num = n;

    memset(del, false, sizeof(del));

    while(1) {

        int i;

        //æ´æ°preæ°ç»

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

            if (del[i] || i == v) continue;

            pre[i] = i;

            g[i][i] = INF;

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

                if (del[j]) continue;

                if (g[j][i] < g[pre[i]][i])

                    pre[i] = j;

            }

        }

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

            //æ¾ç¯

            if (del[i] || i == v) continue;

            int j = i;

            memset(vst, 0, sizeof(vst));

            while (!vst[j] && j != v) {

                vst[j] = true;

                j = pre[j];

            }

            if (j == v) continue;

            i = j;

            //æ´æ°resï¼æåç¯ç¼©ç¹

            res += g[pre[i]][i];

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

                res += g[pre[j]][j];

                del[j] = true;

            }

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

                if(del[j]) continue;

                if(g[j][i] != INF)

                    g[j][i] -= g[pre[i]][i];

            }

            //æ´æ°ç¼©ç¹ä»¥åçæåç¯åå¶ä»ç¹çè¾¹æ

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

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

                    if(del[k])continue;

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

                    if(g[k][j] != INF)

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

                }

            }

            //å®æç¼©ç¹

            break;

        }

        //ä¸å­å¨æåç¯æ¶ï¼åæ­¢å¾ªç¯ï¼å¾åºresæç»å¼

        if(i > n) {

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

                if(del[i] || i == v) continue;

                res += g[pre[i]][i];

            }

            break;

        }

    }

    return res;

}



int main() {

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

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

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

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

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

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

            d[i][j] = gao(j, i);

    double ans = INF;/*

    for (int i = 1; i <= n; ++i, puts(""))

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

            printf(" %.3f", d[i][j]);*/

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

        double s = 0;

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

            s += sqr(a[i][j]);

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

            memcpy(g[j], d[j], sizeof(d[j]));

        ans = min(ans, s + solve(i));

    }

    printf("%.8f\n", ans);

    return 0;

}

// Fastest known solution for this problem: