#include <bits/stdc++.h>
using namespace std;
struct Node {
  long long num;
  int id;
};
Node c[100005], d[100005];
int *a[100005];
bool cmp(Node x, Node y) { return x.num > y.num; }
bool cmp2(Node x, Node y) { return x.id < y.id; }
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) a[i] = (int *)malloc(sizeof(int) * (m + 1));
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) scanf("%d", &a[i][j]);
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) {
      c[i].num += a[i][j];
      d[j].num += a[i][j];
      c[i].id = i;
      d[j].id = j;
    }
  sort(c + 1, c + n + 1, cmp);
  sort(d + 1, d + m + 1, cmp);
  long long ans = c[1].num + c[2].num + c[3].num + c[4].num;
  ans = max(ans, d[1].num + d[2].num + d[3].num + d[4].num);
  sort(c + 1, c + n + 1, cmp2);
  sort(d + 1, d + m + 1, cmp2);
  for (int i = 1; i <= n; i++) {
    long long Max = 0, Max2 = 0, Max3 = 0;
    for (int j = 1; j <= m; j++) {
      d[j].num -= a[i][j];
      if (d[j].num >= Max) {
        Max3 = Max2;
        Max2 = Max;
        Max = d[j].num;
      } else if (d[j].num >= Max2) {
        Max3 = Max2;
        Max2 = d[j].num;
      } else if (d[j].num >= Max3) {
        Max3 = d[j].num;
      }
    }
    ans = max(ans, c[i].num + Max + Max2 + Max3);
    for (int j = 1; j <= m; j++) d[j].num += a[i][j];
  }
  for (int j = 1; j <= m; j++) {
    long long Max = 0, Max2 = 0, Max3 = 0;
    for (int i = 1; i <= n; i++) {
      c[i].num -= a[i][j];
      if (c[i].num >= Max) {
        Max3 = Max2;
        Max2 = Max;
        Max = c[i].num;
      } else if (c[i].num >= Max2) {
        Max3 = Max2;
        Max2 = c[i].num;
      } else if (c[i].num >= Max3) {
        Max3 = c[i].num;
      }
    }
    ans = max(ans, d[j].num + Max + Max2 + Max3);
    for (int i = 1; i <= n; i++) c[i].num += a[i][j];
  }
  if (n < m) {
    for (int i = 1; i <= n; i++)
      for (int j = i + 1; j <= n; j++) {
        long long Max = 0, Max2 = 0, Max3 = 0;
        for (int k = 1; k <= m; k++) {
          d[k].num -= a[i][k] + a[j][k];
          if (d[k].num >= Max) {
            Max2 = Max;
            Max = d[k].num;
          } else if (d[k].num >= Max2) {
            Max2 = d[k].num;
          }
        }
        ans = max(ans, c[i].num + c[j].num + Max + Max2);
        for (int k = 1; k <= m; k++) d[k].num += a[i][k] + a[j][k];
      }
  } else {
    for (int i = 1; i <= m; i++)
      for (int j = i + 1; j <= m; j++) {
        long long Max = 0, Max2 = 0, Max3 = 0;
        for (int k = 1; k <= n; k++) {
          c[k].num -= a[k][i] + a[k][j];
          if (c[k].num >= Max) {
            Max2 = Max;
            Max = c[k].num;
          } else if (c[k].num >= Max2) {
            Max2 = c[k].num;
          }
        }
        ans = max(ans, d[i].num + d[j].num + Max + Max2);
        for (int k = 1; k <= n; k++) c[k].num += a[k][i] + a[k][j];
      }
  }
  printf("%lld\n", ans);
}
