#include <bits/stdc++.h>
using namespace std;
int N, M;
void printTable(vector<uint64_t>& data) {
  for (auto ele : data) {
    cout << ele << " ";
  }
  cout << endl;
}
uint64_t findMaxWithIndex(vector<uint64_t>& arr, uint32_t& index) {
  uint64_t max = 0;
  for (int j = 0; j < arr.size(); ++j) {
    if (arr[j] > max) {
      max = arr[j];
      index = j;
    }
  }
  return max;
}
uint64_t findMax(const uint64_t* arr, const size_t size) {
  uint64_t max = 0;
  for (int j = 0; j < size; ++j) {
    if (arr[j] > max) {
      max = arr[j];
    }
  }
}
uint32_t findMaxIndex(const uint64_t* arr, const size_t size) {
  uint64_t max = 0;
  uint32_t index;
  for (int j = 0; j < size; ++j) {
    if (arr[j] > max) {
      max = arr[j];
      index = j;
    }
  }
  return index;
}
uint64_t doOneStep(vector<uint64_t>& sumsX, vector<uint64_t>& sumsY,
                   vector<uint64_t>& field) {
  uint32_t idx;
  uint64_t maxX = findMaxWithIndex(sumsX, idx);
  uint32_t idy;
  uint64_t maxY = findMaxWithIndex(sumsY, idy);
  if (maxX >= maxY) {
    for (int i = 0; i < sumsY.size(); ++i) {
      if (sumsY[i] != 0) sumsY[i] -= field[idx * M + i];
      sumsX[idx] = 0;
    }
    return maxX;
  } else {
    for (int i = 0; i < sumsX.size(); ++i) {
      if (sumsX[i] != 0) sumsX[i] -= field[i * M + idy];
      sumsY[idy] = 0;
    }
    return maxY;
  }
}
uint64_t doOneStepDir(vector<uint64_t>& sumsX, vector<uint64_t>& sumsY,
                      vector<uint64_t>& field, bool inX) {
  if (inX) {
    uint32_t index;
    uint64_t max = findMaxWithIndex(sumsX, index);
    for (int i = 0; i < sumsY.size(); ++i) {
      if (sumsY[i] != 0) sumsY[i] -= field[index * M + i];
    }
    sumsX[index] = 0;
    return max;
  } else {
    uint32_t index;
    uint64_t max = findMaxWithIndex(sumsY, index);
    for (int i = 0; i < sumsX.size(); ++i) {
      if (sumsX[i] != 0) sumsX[i] -= field[i * M + index];
    }
    sumsY[index] = 0;
    return max;
  }
}
void harvest() {
  cin >> N >> M;
  vector<uint64_t> field;
  field.resize(N * M);
  vector<uint64_t> sumsX;
  sumsX.resize(N);
  vector<uint64_t> sumsY;
  sumsY.resize(M);
  memset(&sumsX[0], 0, sizeof(uint64_t) * N);
  memset(&sumsY[0], 0, sizeof(uint64_t) * M);
  const int limit = 4;
  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < M; ++j) {
      cin >> field[i * M + j];
      sumsX[i] += field[i * M + j];
      sumsY[j] += field[i * M + j];
    }
  }
  if (N <= limit) {
    uint64_t sum = 0;
    for (int i = 0; i < N; ++i) {
      sum += sumsX[i];
    }
    cout << sum << endl;
    return;
  }
  if (M <= limit) {
    uint64_t sum = 0;
    for (int i = 0; i < M; ++i) {
      sum += sumsY[i];
    }
    cout << sum << endl;
    return;
  }
  uint64_t totals[16];
  bool dir[64]{1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1,
               0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1,
               0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0};
  memset(&totals, 0, sizeof(totals));
  for (int p = 0; p < 16; ++p) {
    vector<uint64_t> myXs(sumsX);
    vector<uint64_t> myYs(sumsY);
    for (int i = 0; i < 4; ++i) {
      totals[p] += doOneStepDir(myXs, myYs, field, dir[p * 4 + i]);
    }
  }
  uint64_t total = 0;
  for (int i = 0; i < 16; ++i) {
    if (totals[i] > total) {
      total = totals[i];
    }
  }
  cout << total << endl;
}
int main() {
  cin.tie(nullptr);
  ios_base::sync_with_stdio(false);
  harvest();
  return 0;
}
