extern crate core;
 
use std::fmt;
use std::cmp::Ordering;
use std::collections::BinaryHeap;
use ::State::{NotVisit, Confirmed, Pending};
use std::mem::swap;
use std::fmt::{Display, Error, Formatter};
macro_rules! read_line{
    () => {{
        let mut line = String::new();
        std::io::stdin().read_line(&mut line).ok();
        line
    }};
    (delimiter: ' ') => {
        read_line!().split_whitespace().map(|x|x.to_string()).collect::<Vec<_>>()
    };
    (delimiter: $p:expr) => {
        read_line!().split($p).map(|x|x.to_string()).collect::<Vec<_>>()
    };
    (' ') => {
        read_line!(delimiter: ' ')
    };
    ($delimiter:expr) => {
        read_line!(delimiter: $delimiter)
    };
    (' '; $ty:ty) => {
        read_line!().split_whitespace().map(|x|x.parse::<$ty>().ok().unwrap()).collect::<Vec<$ty>>()
    };
    ($delimiter:expr; $ty:ty) => {
        read_line!($delimiter).into_iter().map(|x|x.parse::<$ty>().ok().unwrap()).collect::<Vec<$ty>>()
    };
}
macro_rules! let_all {
    ($($n:ident:$t:ty),*) => {
        let line = read_line!(delimiter: ' ');
        let mut iter = line.iter();
        $(let $n:$t = iter.next().unwrap().parse().ok().unwrap();)*
    };
}
struct Vector {
    factors: Vec<f64>,
    norm: f64,
    sum: f64,
}
impl Vector {
    fn new(vec: Vec<f64>) -> Vector {
        let mut norm = 0_f64;
        let mut sum = 0_f64;
        for &v in &vec {
            norm += v * v;
            sum += v;
        }
        Vector{factors: vec, norm: norm, sum: sum}
    }
    fn distance(&self, other: &Self) -> f64 {
        if other.norm == 0_f64 {
            self.norm
        } else {
            let mut dot = 0_f64;
            for i in 0..self.factors.len() {
                dot += self.factors[i] * other.factors[i];
            }
            -dot * dot / other.norm + self.norm
        }
    }
}
#[derive(Clone)]
pub struct UnionFind {
    pub size: usize,
    array: Vec<i32>,
}
 
impl UnionFind {
    fn new(size: usize) -> UnionFind {
        UnionFind{size: size, array: vec![-1; size]}
    }
    fn find(&mut self, a: usize) -> usize {
        if self.array[a] < 0 {
            a
        }else {
            let parent = self.array[a] as usize;
            let p = self.find(parent);
            self.array[a] = p as i32;
            p
        }
    }
    fn check_is_same(&mut self, a: usize, b: usize) -> bool {
        let ap = self.find(a);
        let bp = self.find(b);
        ap == bp
    }
    fn merge(&mut self, a: usize, b: usize) {
        let ap = self.find(a);
        let bp = self.find(b);
        if ap != bp {
            if self.array[ap] < self.array[bp] {
                self.array[ap] = self.array[bp];
                self.array[bp] = ap as i32;
            }else {
                self.array[bp] = self.array[ap];
                self.array[ap] = bp as i32;
            }
        }
    }
}
fn main(){
    let_all!(n: usize, m: usize);
    let mut vectors = Vec::with_capacity(m + 1);
    for _ in 0 .. m {
        vectors.push(Vector::new(read_line!(' '; f64)));
    }
    vectors.push(Vector::new(vec![0_f64; n]));
    let mut nodes = Vec::with_capacity(m + 1);
    for i in 0 .. vectors.len() {
        let mut edges = Vec::with_capacity(m);
        for j in 0 .. vectors.len() {
            if i != j {
                edges.push(Edge{from: j, cost: vectors[i].distance(&vectors[j])});
            }
        }
        nodes.push(Node::new(edges));
    }
    println!("{:.*}", 10, solve(nodes, m));
}
struct Edge {
    from: usize, cost: f64
}
impl Display for Edge {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        write!(f, "Edge(from: {}, cost: {})", self.from, self.cost)
    }
}
impl Ord for Edge {
    fn cmp(&self, other: &Self) -> Ordering {
        self.cost.partial_cmp(&other.cost).unwrap()
    }
}
impl PartialOrd for Edge {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.cost.partial_cmp(&other.cost)
    }
}
impl PartialEq for Edge {
    fn eq(&self, other: &Self) -> bool {
        self.cost == other.cost
    }
}
impl Eq for Edge {}
struct Node {
    in_edges: Vec<Edge>,
}
fn show<T:Display>(vec:&Vec<T>) {
    if vec.is_empty() {
        println!("[]");
    }else{
        print!("[{}", vec[0]);
        for i in 1 .. vec.len() {
            print!(", {}", vec[i]);
        }
        print!("]\n");
    }
}
impl Node {
    fn new(mut vec:Vec<Edge>) -> Node {
        vec.sort_by(|a, b| a.cmp(b).reverse());
        Node{in_edges: vec}
    }
    fn pop_min_in_edge(&mut self) -> Option<Edge> {
        self.in_edges.pop()
    }
    fn pop_all_edges(&mut self) -> Vec<Edge> {
        let mut ret = Vec::new();
        swap(&mut self.in_edges, &mut ret);
        ret
    }
}
#[derive(Copy, Clone, Eq, PartialEq)]
enum State {
    Confirmed, Pending, NotVisit
}
fn solve(mut nodes: Vec<Node>, root: usize) -> f64 {
    let mut node_state = vec![NotVisit; nodes.len()];
    node_state[root] = Confirmed;
    let mut union = UnionFind::new(nodes.len());
    let mut result = 0_f64;
    let mut from_node = vec![0; nodes.len()];
    let mut from_cost = vec![0_f64; nodes.len()];
    for start in 0 .. nodes.len() {
        if node_state[start] == NotVisit {
            let mut searching = Vec::new();
            let mut current = start;
            while node_state[current] != Confirmed {
                match node_state[current] {
                    Pending => {
                        let mut in_cycle = union.find(from_node[current]);
                        let mut edges = Vec::new();
                        for e in nodes[current].pop_all_edges() {
                            edges.push(Edge{from: e.from, cost: e.cost - from_cost[current]});
                        }
                        while !union.check_is_same(in_cycle, current) {
                            for e in nodes[in_cycle].pop_all_edges() {
                                edges.push(Edge{from: e.from, cost: e.cost - from_cost[in_cycle]});
                            }
                            union.merge(in_cycle, current);
                            in_cycle = union.find(from_node[in_cycle]);
                        }
                        let parent = union.find(current);
                        nodes[parent] = Node::new(edges);
                        if let Some(e) = nodes[parent].pop_min_in_edge() {
                            result += e.cost;
                            current = union.find(e.from);
                            from_node[parent] = current;
                            from_cost[parent] = e.cost;
                        }else {
                            unreachable!()
                        }
                    }
                    NotVisit => {
                        searching.push(current);
                        node_state[current] = Pending;
                        if let Some(e) = nodes[current].pop_min_in_edge() {
                            result += e.cost;
                            let parent = current;
                            current = union.find(e.from);
                            from_node[parent] = current;
                            from_cost[parent] = e.cost;
                        }else {
                            unreachable!()
                        }
                    }
                    Confirmed => unreachable!()
                }
            }
            for s in searching {
                node_state[s] = Confirmed;
            }
        }
    }
    result
}


Measured memory_bytes: 7136