// Slower C++ solution:
#include <iostream>

#include <cstdio>

#include <string.h>

#include <algorithm>

#include <string>

#include <math.h>

using namespace std;



struct edge{

	int d,k,od,ok;

	double data;

}e[100000];

int pre[1000],id[1000],vis[1000];

double in[1000],tmp;

double a[120][120];

double d[120];

int n,m,nn,root;

double ans2;



double cal2(int p,int q,double k){

	for (int i=1;i<=m;++i) d[i]=a[p][i]-a[q][i]*k;

	double tmp = 0;

	for (int i=1;i<=m;++i) tmp+=d[i]*d[i];

	return tmp;

}



double cal(int p,int q){

	double l = -10000,r = 10000,mid1,mid2;

	while (r-l>1e-6){

		double tmp = (r-l)/3;

		mid1=l+tmp;

		mid2=mid1+tmp;

		if (cal2(p,q,mid1)<cal2(p,q,mid2)) r=mid2;

		else l=mid1;

	}

//	printf("%d %d %.2f\n",p,q,cal2(p,q,mid1));

	return cal2(p,q,mid1);

}



void addedge(int p,int q,double k,int od,int ok){

	e[++nn].k=q;

	e[nn].d=p;

	e[nn].od=od;

	e[nn].ok=ok;

	e[nn].data=k;

}



double work(int root){

	int sum=n;

	ans2=1e50;

	int oldroot=root;

	double res=0;

	while (1){

		for (int i=1;i<=sum;++i) in[i]=1e50;

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

			int u=e[i].d,v=e[i].k;

			if (e[i].data<in[v] && u!=v){

				if (e[i].od == oldroot) ans2=e[i].ok;

				pre[v]=u;

				in[v]=e[i].data;

			}

		}

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

			if (i==root) continue;

			if (in[i]>1e40) return -1;

		}

		int cntnode = 0;

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

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

		in[root] = 0;

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

			res+=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+1;

				id[v]=++cntnode;

			}

		}

		if (!cntnode) break;

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

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

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

			int v=e[i].k;

			e[i].d=id[e[i].d];

			e[i].k=id[e[i].k];

			if (e[i].d!=e[i].k) e[i].data-=in[v];

		}

		sum=cntnode;

		root = id[root];

	}

	return res;

}

			

double cal3(int k){

	double tmp = 0;

	for (int i=1;i<=m;++i) tmp+=a[k][i]*a[k][i];

	return tmp;

}

			

int main(){

	while (scanf("%d%d",&m,&n)==2){

		nn=0;

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

			for (int j=1;j<=m;++j) scanf("%lf",&a[i][j]);

		double tt = 0;

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

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

				addedge(i,j,cal(j,i),i,j);

//				printf("%d %d %.2f\n",i,j,e[nn].data);

			}

		++n;

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

			addedge(n,i,cal3(i),n,i);

//			printf("%d: %.2f\n",i,cal3(i));

		}

		root = n;

		printf("%.12f\n",work(root));

	}

	return 0;

}

			

// Faster C++ solution for the same problem (measured speedup: 4.98238331516306x):
#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;

}