private static void gaussJordan(int matrix[][], int[] board) {
    int length = matrix.length;
    
    /* Iteratively constructs the row reduced form for the given matrix.
     * Invariant: The matrix to the top and left of (row, row) is in RREF form.
     */
    for (int row = 0; row < length; row++) {
      // Search for an entry in the matrix with a '1', searching down each column from (row, row).
      int nextrow = row;
      int col = row;
      while (col < length && matrix[nextrow][col] != 1) {
        nextrow++;
        if (nextrow == length) {
          // No entry is this column, check next one.
          col++;
          nextrow = row;
        }
      }
      if (col == length) {
        return;
      }

      // Swap our rows.
      swapRow(matrix, row, nextrow);
      swapElem(board, row, nextrow);

      // Set every element below row in col to be 0.
      for (int i = row + 1; i < length; i++) {
        if (matrix[i][col] != 0) {
          matrix[i][col] = 0;
          for (int j = col + 1; j < length; j++)
            matrix[i][j] = (matrix[i][j] + matrix[row][j]) % 2;
          board[i] = (board[i] + board[row]) % 2;
        }
      }
    }
  }