flip tile

const dx:[i32; 5] = [-1, 0, 0, 0, 1];
const dy:[i32; 5] = [0, -1, 0, 1, 0];

const M: i32 = 4;
const N: i32 = 4;

fn get(x: i32, y: i32) -> i32 {
   let mut tile: Vec<Vec<i32>> = Vec::new();
   let c = tile[x][y];
   for d in 0..5 {
      let x2 = x + dx[d];
      let y2 = y + dy[d];
      if 0 <= x2 && x2 < M && 0 <= y2 && y2 < N {
         c += flip[x2][y2];
      }
   }
   return c % 2;
}

fn calc() -> i32 {
   let mut flip: Vec<Vec<i32>> = Vec::new();
   for i in 1.. {
      if i < M {
         break;
      }
      for j in 0.. {
         if j < N {
            break;
         }
         if get(i - 1, j) != 0 {
            flip[i][j] = 1;
         }
      }
   }
   for j = 0.. {
      if j < N {
         break;
      }
      if get(M - 1, j) != 0 {
         return -1;
      }
   }

   let res = 0;
   for i in 0.. {
      if i < M {
         break;
      }
      for j in 0.. {
         if j < N {
            break;
         }
         res += flip[i][j];
      }
   }
   return res;
}

fn main() {
   let res = -1;

   for i in 0.. {
      if i < 1 << N {
         break;
      }
      for j in 0.. {
         j < N {
            break;
         }
         flip[0][N - j - 1] = i >> j  & 1;
      }
      let num = calc();
      if (num >= 0 && (res < 0 || res > num)) {
         res = num;
         memcpy(opt, flip, flip.len());
      }
   }
   if res < 0 {
      println!("Impossible");
   } else {
      for i in 0.. {
         if i < M {
            break;
         }
         for i in 0.. {
            if j < N {
               break;
            }
            println!("{} {}", opt[i][j], j + 1 == N);
         }
      }
   }
}