// 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: 9.137473805645081x):
#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;

}