Problem:
Vector Compression

You are recording a result of a secret experiment, which consists of a large set of N-dimensional vectors.
Since the result may become very large, you are thinking of
compressing it. Fortunately you already have a good compression method
for vectors with small absolute values, all you have to do is to
preprocess the vectors and make them small.

You can record the set of vectors in any order you like.
Let's assume you process them in the order v_1, v_2,..., v_M.
Each vector v_i is recorded either as is, or as a difference vector.
When it is recorded as a difference,
you can arbitrarily pick up an already chosen vector v_j (j<i) and a real value r.
Then the actual vector value recorded is (v_i - r v_j).
The values of r and j do not affect the compression ratio so much, so you don't have to care about them.

Given a set of vectors,
your task is to write a program that calculates the minimum sum of the squared length of the recorded vectors.

Input

The input is like the following style.

N M

v_{1,1} v_{1,2} ... v_{1,N}

...

v_{M,1} v_{M,2} ... v_{M,N}

The first line contains two integers N and M (1 \leq N, M \leq 100),
where N is the dimension of each vector,
and M is the number of the vectors.
Each of the following M lines contains N floating point values v_{i,j} (-1.0 \leq v_{i,j} \leq 1.0)
which represents the j-th element value of the i-th vector.

Output

Output the minimum sum of the squared length of the recorded vectors.
The output should not contain an absolute error greater than 10^{-6}.

Sample Input 1

2 3
1.0 1.0
-1.0 0.0
0.5 0.5

Output for the Sample Input 1

1.0

Sample Input 2

1 1
1.0

Output for the Sample Input 2

1.0

Sample Input 3

4 3
1.0 1.0 0.0 0.0
-1.0 0.0 -1.0 0.0
0.5 0.5 0.5 0.5

Output for the Sample Input 3

3.0

Solution in Rust (judge verdict: Accepted)

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
}