#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
typedef int mat;
typedef unsigned int uint;
mat **get_empty(mat rows, mat cols);
mat **read_matrix(mat rows, mat cols, FILE *from);
void free_matrix(mat **matrix, mat rows);
void tipar(mat **matrix, mat rows, mat cols, FILE *where);
int64_t sum(int **matrix, int n, int m);
void flip_row(int **matrix, int k, int m);
void flip_col(int **matrix, int n, int k);
void submultimi_backtrack_row(uint *stiva, uint nivel, uint n, int **matrix, int r, int c);
void submultimi_backtrack_col(uint *stiva, uint nivel, uint n, int **matrix, int r, int c);
void tipar_s(uint *stiva, uint nivel);
bool valid(uint *stiva, uint nivel, uint last);
int64_t max = 0;
int main(void)
{
FILE *in = fopen("flip.in", "r");
FILE *out = fopen("flip.out", "w");
if(in != NULL && out != NULL)
{
int n, m;
fscanf(in, "%d%*c%d%*c", &n, &m);
int **matrix = read_matrix(n, m, in);
uint stiva[20];
submultimi_backtrack_row(stiva, 0, n, matrix, n, m);
submultimi_backtrack_col(stiva, 0, n, matrix, n, m);
fprintf(out, "%lld\n", max);
free_matrix(matrix, n);
fclose(in);
fclose(out);
}
else
{
printf("Error\n");
}
return 0;
}
void tipar_s(uint *stiva, uint nivel)
{
uint i = 0;
for(; i <= nivel; i++)
{
printf("%u ", stiva[i]);
}
printf("\n");
}
bool valid(uint *stiva, uint nivel, uint last)
{
uint i = 0;
for(; i < nivel; i++)
{
if(stiva[i] == last || stiva[i] > stiva[i + 1])
{
return false;
}
}
return true;
}
void submultimi_backtrack_row(uint *stiva, uint nivel, uint n, int **matrix, int r, int c)
{
uint i = 0;
for(; i < n; i++)
{
stiva[nivel] = i;
if(valid(stiva, nivel, i))
{
int j = 0;
for(; j <= nivel; j++)
{
flip_row(matrix, stiva[j], c);
}
int64_t s = sum(matrix, r, c);
if(s > max)
{
max = s;
}
j = 0;
for(; j <= nivel; j++)
{
flip_row(matrix, stiva[j], c);
}
if((nivel + 1) < n)
{
submultimi_backtrack_row(stiva, nivel + 1, n, matrix, r, c);
}
}
}
}
void submultimi_backtrack_col(uint *stiva, uint nivel, uint n, int **matrix, int r, int c)
{
uint i = 0;
for(; i < n; i++)
{
stiva[nivel] = i;
if(valid(stiva, nivel, i))
{
int j = 0;
for(; j <= nivel; j++)
{
flip_col(matrix, r, stiva[j]);
}
int64_t s = sum(matrix, r, c);
if(s > max)
{
max = s;
}
j = 0;
for(; j <= nivel; j++)
{
flip_col(matrix, r, stiva[j]);
}
if((nivel + 1) < n)
{
submultimi_backtrack_col(stiva, nivel + 1, n, matrix, r, c);
}
}
}
}
void flip_row(int **matrix, int k, int m)
{
int i = 0;
for(; i < m; i++)
{
matrix[k][i] = -matrix[k][i];
}
}
void flip_col(int **matrix, int n, int k)
{
int i = 0;
for(; i < n; i++)
{
matrix[i][k] = -matrix[i][k];
}
}
int64_t sum(int **matrix, int n, int m)
{
int64_t s = 0;
int i = 0;
for(; i < n; i++)
{
int j = 0;
for(; j < m; j++)
{
s += matrix[i][j];
}
}
return s;
}
mat **read_matrix(mat rows, mat cols, FILE *from)
{
mat **matrix = malloc(sizeof(mat *) * rows);
if(matrix != NULL)
{
mat i = 0;
for(; i < rows; i++)
{
mat *line = malloc(sizeof(mat) * cols);
if(line != NULL)
{
mat j = 0;
for(; j < cols; j++)
{
mat t = 0;
fscanf(from, "%d%*c", &t);
line[j] = t;
}
matrix[i] = line;
}
else
{
printf("Failed init line: %u\n", i);
}
}
return matrix;
}
else
{
printf("matrix init error\n");
}
}
void tipar(mat **matrix, mat rows, mat cols, FILE *where)
{
mat i = 0;
for(; i < rows; i++)
{
mat j = 0;
for(; j < cols; j++)
{
fprintf(where, "%u ", matrix[i][j]);
}
fprintf(where, "\n");
}
}
void free_matrix(mat **matrix, mat rows)
{
mat i = 0;
for(; i < rows; i++)
{
free(matrix[i]);
}
free(matrix);
}
mat **get_empty(mat rows, mat cols)
{
mat **matrix = malloc(sizeof(mat *) * rows);
if(matrix != NULL)
{
mat i = 0;
for(; i < rows; i++)
{
mat *line = calloc(cols, sizeof(mat));
if(line != NULL)
{
matrix[i] = line;
}
else
{
printf("Failed init line: %u\n", i);
}
}
return matrix;
}
else
{
printf("matrix init error\n");
}
}