import java.util.Scanner;
public class Test {
public static int n, m;//n行m列
public static int[][] map;//矩阵
public static int result = 0;//最大和
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//读取行
n = sc.nextInt();
//读取列
m = sc.nextInt();
//声明一个二维数组存储矩阵
map = new int[n][m];
//初始化二维数组元素
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
//输入数据
map[i][j] = sc.nextInt();
/*动态规划算法设计
* 1.计算start~end行的每一列元素和,放入col数组中,-->二维问题转为一维最大子段和问题
* 2.从第一行开始,col数组存储该列元素和,dp数组存储每个col的最大子段和,将最大值赋值给result
* 3.从第二行开始,重复2的步骤,更新result
* 4.最后返回result,即为最大志矩阵的子段和
*/
for (int start = 0; start < n; start++) { // 开始行
int[] col = new int[m];//存放列的和
int[] dp = new int[m];//动态规划数组,存放每一行的最大子段和
for (int end = start; end < n; end++) { // 结束行
for (int j = 0; j < m; j++) {// 计算start~end行的每一列元素和
col[j] += map[end][j];//逐行计算每列元素和
System.out.print(col[j]+" ");
}
System.out.println("");
result = Math.max(result, col[0]);//每行结束后判断第一列上到该行的和与上一次结果的大小
dp[0] = col[0];
//填写dp数组
for (int j = 1; j < m; j++) {
if (dp[j - 1] < 0)//如果前一次的和为负数,则不累加
dp[j] = col[j];
else//否则
dp[j] = dp[j - 1] + col[j];
result = Math.max(result, dp[j]);//更新result
}
}
}
//输出执行结果
System.out.println(result);
}
}