/*
* Author:heroming
* File:heroming.cpp
* Time:2020/10/16 11:45:42
*/
#include <vector>
#include <list>
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <string>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <unordered_map>
using namespace std;
typedef long long lint;
const int maxd = 5;
const int maxn = 200010;
const int maxm = 1 << maxd;
int d, n;
int u[maxn][maxd]; // origin points
int v[maxn][maxm]; // points info for each mask
int s[maxm]; // max value for each mask in visited set A
set<pair<int, int>> t[maxm]; // all value for each mask of every node in unvisited set B
int main() {
scanf("%d%d", &d, &n);
for (int k = 0; k < n; ++ k) {
for (int i = 0; i < d; ++ i) {
scanf("%d", &u[k][i]);
}
}
const int m = 1 << d;
for (int e = 0; e < m; ++ e) {
for (int k = 0; k < n; ++ k) {
for (int i = 0; i < d; ++ i) {
if (e & (1 << i)) {
v[k][e] += u[k][i];
} else {
v[k][e] -= u[k][i];
}
}
// visited set initially has point 0
if (k == 0) {
s[e] = v[k][e];
} else {
t[e].insert({v[k][e], k});
}
}
}
lint ans = 0;
// prim algorithm, each time pick a point with max distance
for (int k = 1; k < n; ++ k) {
int w = -1, p = -1;
// pick the max distance point
for (int e = 0; e < m; ++ e) {
auto l = *t[e].begin();
if (w < s[e] - l.first) {
p = l.second;
w = s[e] - l.first;
}
}
ans += w;
// update max value of each mask in A
// and erase picked point info from B
for (int e = 0; e < m; ++ e) {
t[e].erase({v[p][e], p});
s[e] = max(s[e], v[p][e]);
}
}
printf("%lld\n", ans);
return 0;
}