#include using namespace std; struct UnionFind { vector par, rank, size; UnionFind(int n) : par(n), rank(n, 0), size(n, 1) { iota(par.begin(), par.end(), 0); } int find(int i) { return (par[i] == i ? i : (par[i] = find(par[i]))); } bool same(int i, int j) { return find(i) == find(j); } void merge(int i, int j) { if((i = find(i)) == (j = find(j))) return; if(rank[i] > rank[j]) swap(i, j); par[i] = j; size[j] += size[i]; if(rank[i] == rank[j]) rank[j]++; } }; struct E { int u, v, weight; }; bool operator<(const E &l, const E &r) { return l.weight < r.weight; } int main() { int n, k; cin >> n >> k; vector dna(n); for(auto &x : dna) cin >> x; int cost = 0; UnionFind uf(n); vector ans; for(int i = 0; i < n-1; ++i){ vector edges; edges.reserve(n*(n-1)/2); for(int i = 0; i < n; ++i) for(int j = i+1; j < n; ++j) { edges.push_back({i, j, 0}); for(int l = 0; l < k; ++l) edges.back().weight += dna[i][l] != dna[j][l]; } sort(edges.begin(), edges.end()); for(auto &e : edges) { if(!uf.same(e.u, e.v)) { cost += e.weight; uf.merge(e.u, e.v); ans.push_back(e); break; } } } cout << cost << '\n'; for(auto e : ans) cout << e.u << ' ' << e.v << '\n'; return 0; }