void lookForRunsBelowTargetWeight(const KeccakFPropagation& DCorLC, ostream& out,  unsigned int targetWeight, bool verbose)
{
    ProgressMeter progress;
    progress.stack("Initial run starting point", 5);
    for(unsigned int tStart=0; tStart<5; tStart++) {
        progress.stack("Initial run length", DCorLC.laneSize*5-1);
        for(unsigned int length=1; length<=DCorLC.laneSize*5-1; length++) {
            ParityAsRuns parity;
            Run run;
            run.tStart = tStart;
            run.length = length;
            parity.runs.push_back(run);
            lookForRunsBelowTargetWeight(DCorLC, out, targetWeight, parity, progress, verbose);
            ++progress;
        }
        progress.unstack();
        ++progress;
    }
    progress.unstack();
}    
void lookForRunsBelowTargetWeight(const KeccakFPropagation& DCorLC, ostream& out,
    unsigned int targetWeight, ParityAsRuns& parity, ProgressMeter& progress, bool verbose)
{
    unsigned int lowerBound;
    unsigned int weightBoundBasedOnTotalHammingWeight = getBoundOfTotalWeightGivenTotalHammingWeight(DCorLC,
        parity.getLowerBoundTotalHammingWeight(DCorLC));
    if (weightBoundBasedOnTotalHammingWeight <= targetWeight) {
        unsigned int minActiveRows = parity.getLowerBoundTotalActiveRowsUsingOnlyAC(DCorLC);
        lowerBound = max(minActiveRows*2, weightBoundBasedOnTotalHammingWeight);
    }
    else
        lowerBound = weightBoundBasedOnTotalHammingWeight;
    if (lowerBound <= targetWeight) {
        unsigned int thisOneLowerBound = parity.getLowerBoundTotalActiveRows(DCorLC)*2;
        if (thisOneLowerBound <= targetWeight) {
            vector<RowValue> C, D;
            parity.toParityAndParityEffect(DCorLC, C, D);
            unsigned int thisOneLowerBoundAgain = getLowerBoundTotalActiveRows(DCorLC, C, D)*2;
            if (thisOneLowerBoundAgain <= targetWeight) {
                if (verbose) {
                    displayParity(cout, C, D);
                    cout << "Lower bound = " << dec << max(thisOneLowerBound, thisOneLowerBoundAgain) << endl;
                    cout << endl;
                }
                vector<RowValue> Cmin;
                getSymmetricMinimum(C, Cmin);
                writeParity(out, Cmin);
            }
        }
        progress.stack("Adding runs to "+parity.display());
        for(unsigned int tStart=parity.runs.back().tStart+parity.runs.back().length+1; 
                tStart<DCorLC.laneSize*5; tStart++) {
            unsigned int maxLength = DCorLC.laneSize*5-1-tStart+parity.runs[0].tStart;
            for(unsigned int length=1; length<=maxLength; length++) {
                Run run;
                run.tStart = tStart;
                run.length = length;
                parity.runs.push_back(run);
                lookForRunsBelowTargetWeight(DCorLC, out, targetWeight, parity, progress, verbose);
                parity.runs.pop_back();
                ++progress;
            }
        }
        progress.unstack();
    }
}