void CobwebGraph::setCountingNumbers( bool debugging ) {
    // should handle the case when one region in the msg-region graph is subset of another or even to top regions are the same
    _cn.reserve( nrCWs() );
    for( size_t R = 0; R < _INRs.size(); R++ ) {
        vector<VarSet> topR;
        // finding the intersection of messages
        SmallSet<VarSet> betas;
        for( size_t m1 = 0; m1 < M(R).size(); m1++ ) {
            topR.push_back( M(R,m1).msg.vars() );
            for( size_t m2 = 0; m2 < M(R).size(); m2++ ) {
                if( m1 == m2 )
                    continue;
                VarSet b = M(R,m1).msg.vars() & M(R,m2).msg.vars();
                if( b.size() == 0 )
                    continue;
                betas.insert( b );
            }
        }
        if( debugging )
            cerr << "topR: " << topR << endl;

        // finding the intersections of intersections
        bool somechange = true;
        while( somechange ) {
            SmallSet<VarSet> newbetas;
            somechange = false;
            bforeach( const VarSet &b1, betas ) {
                bforeach( const VarSet &b2, betas ) {
                    if( b1 == b2 )
                        continue;
                    VarSet b3 = b1 & b2;
                    if( betas.contains(b3) || b3.size() == 0 )
                        continue;
                    newbetas |= b3;
                    somechange = true;
                }
            }
            betas |= newbetas;
        }
        if( debugging )
            cerr << "betas: " << betas << endl;

        // set the counting number
        _cn.push_back( map<VarSet, pair<int, vector<size_t> > >() );
        // adding sub-regions of every message
        for( size_t i = 0; i < topR.size(); i++ ) {
            M(R,i).subregions.clear();
            bforeach( const VarSet& b, betas )
                if( b << topR[i] )
                    M(R,i).subregions.push_back( b );
        }
        SmallSet<VarSet> subVisited;
        SmallSet<VarSet> topRSet( topR.begin(), topR.end(), topR.size() );
        // looks to see if all parents of a sub-region got their counting number
        while( !betas.empty() ) {
            bforeach( const VarSet &beta, betas ) {
                bool allparentsset = true;
                bforeach( const VarSet &beta2, betas )
                    if( beta2 >> beta && beta2 != beta ) {
                        allparentsset = false;
                        break;
                    }
                if( allparentsset ) {
                    // the first in the pair is cn and the second the index of top regions containing it
                    _cn[R][beta] = make_pair( 1, vector<size_t>() );
                    for( size_t TR = 0; TR < topR.size(); TR++ ) {
                        if( topR[TR] >> beta ) {
                            _cn[R][beta].first--;
                            _cn[R][beta].second.push_back( TR );
                        }
                    }
                    bforeach( const VarSet& possibleparent, subVisited )
                        if( possibleparent >> beta )
                            _cn[R][beta].first -= _cn[R][possibleparent].first;

                    if( debugging )
                        cerr << "cn[" << R << "][" << beta << "] <- " << _cn[R][beta] << endl;
                    subVisited.insert( beta );
                    betas /= beta;
                    break; // since betas has changed we need to enter the loop again
                }
            }
        }