#include <stdlib.h>
#include <stdio.h>
#include <math.h>
struct nod{
int data;
struct nod* next;
};
typedef struct nod Node;
void alocaNod(Node** head)
{
Node* temp = (Node*)calloc(1, sizeof(Node));
temp -> next = NULL;
temp -> data = 0;
if(*head == NULL){
(*head) = temp;
return;
}
temp -> next = (*head);
*head = temp;
return;
}
int** doBackup(int** tabla, int n, int m)
{
int** backup = (int**)calloc(n, sizeof(int*));
int i;
for(i = 0; i < n; i++){
backup[i] = (int*)calloc(m, sizeof(int));
}
int j;
for(i = 0; i < n; i++){
for(j = 0; j < m; j++){
backup[i][j] = tabla[i][j];
}
}
return backup;
}
void freeBackup(int** backup, int n)
{
int i;
for(i = 0; i < n; i++){
free(backup[i]);
}
free(backup);
}
int calculeaza(int** tabla, int n, int m)
{
int s = 0;
int i,j;
for( i = 0; i < n; i++){
for(j = 0; j < m; j++){
s += tabla[i][j];
}
}
return s;
}
void apasaButoane(int** backup, Node* head, int n, int m)
{
int indexParcurgere = 0;
int j;
while(head != NULL){
if(head -> data != 0){
if(indexParcurgere < n){
for(j = 0; j < m; j++){
backup[indexParcurgere][j] *= (-1);
}
}
else{
for(j = 0; j < n; j++){
backup[j][indexParcurgere - n] *= (-1);
}
}
}
head = head -> next;
indexParcurgere++;
}
}
int cmp(const void* a, const void* b)
{
return *(int*)a - *(int*)b;
}
void eliberare(Node* head)
{
if(head -> next == NULL) return;
eliberare(head -> next);
free(head -> next);
}
void findMax(int** tabla, int n, int m)
{
int* sume = (int*)calloc( pow(2,(n+m)), sizeof(int));
int index = 0; // contor vector sume;
Node* head = NULL;
int i;
for( i = 0; i < n + m; i++){
alocaNod(&head);
}
int nrButoane = n + m;
int** backup = doBackup(tabla, n, m);
sume[index] = calculeaza(backup, n ,m);
freeBackup(backup, n);
index = 1;
int nrCaz = pow(2, nrButoane);
while( index != nrCaz){
Node* parcurgere = head;
while(parcurgere -> data == 1){
parcurgere -> data = 0;
parcurgere = parcurgere -> next;
}
parcurgere -> data = 1;
//aici incepe treaba
backup = doBackup(tabla, n , m);
apasaButoane(backup, head, n, m);
sume[index] = calculeaza(backup, n, m);
freeBackup(backup, n);
//aici se terminas
index++;
}
/*for(i = 0; i < nrCaz; i++){
printf("\n%i", sume[i]);
}*/
qsort(sume, nrCaz, sizeof(int), cmp);
FILE* output = fopen("flip.out", "a");
fprintf(output, "%i", sume[nrCaz - 1]);
eliberare(head);
free(head);
fclose(output);
free(sume);
//tre sa eliberez si lista
}
int main()
{
int n, m;
FILE* input;
input = fopen("flip.in", "r");
int i, j;
fscanf(input, "%i", &n);
fscanf(input, "%i", &m);
int** tabla;
tabla = (int**)calloc(n, sizeof(int*));
for(i = 0; i < n; i++){
tabla[i] = (int*)calloc(m, sizeof(int));
}
for(i = 0; i < n; i++){
for(j = 0; j < m; j++){
fscanf(input, "%i", &(tabla[i][j]) );
}
}
findMax(tabla, n, m);
freeBackup(tabla, n);
fclose(input);
return 0;
}