diff --git a/components.c b/components.c
index 9e549ba36b9a2d8698952f508815929e8c49b0ff..3f019baa3e1d435882d8cb6a5c45e747886bcfbe 100644
--- a/components.c
+++ b/components.c
@@ -39,7 +39,25 @@ void allocSearchConnectedComponents(Graph g) {
 
 // Search connected components of the subgraph delimited by V
 // verif is just used to verify for each vertex that it is in the current set (useless for greedy search)
-int searchConnectedComponents(SET V, int S[], int n, Graph g) {
+
+
+void compExploreBFSOrderedNeighbors(int num, int nbNiS[],Graph g) {
+    while (last != first) {
+        int e = *first;
+        first = first+1;
+        if (first == queue+g->n) first = queue;
+        for (int *p = g->lists[e]; p < g->lists[e]+nbNiS[e]; p ++) {
+            if (iComp[*p] == NONE) {
+                iComp[*p] = num;
+                compSizes[num]++;
+                *last++ = *p;
+                if (last == queue + g->n) last = queue;
+            }
+        }
+    }
+}
+
+int searchConnectedComponents(int S[], int n, int nbNiS[], Graph g) {
 
     int nbComp = 0;
     int nbNodes = 0;
@@ -56,7 +74,7 @@ int searchConnectedComponents(SET V, int S[], int n, Graph g) {
             //firstOfComp[nbComp] = S[i];
             first = last = queue;
             *last++ = S[i];
-            compExploreBFS(nbComp, V, S, n, g, 1);
+            compExploreBFSOrderedNeighbors(nbComp, nbNiS, g);
             if (compSizes[nbComp] > sizeCompMax) sizeCompMax = compSizes[nbComp];
             nbNodes += compSizes[nbComp];
             nbComp++;
@@ -66,7 +84,33 @@ int searchConnectedComponents(SET V, int S[], int n, Graph g) {
     return nbComp;
 }
 
+#ifdef NOTDEF
+int searchConnectedComponents(SET V, int S[], int n, Graph g) {
+
+    int nbComp = 0;
+    int nbNodes = 0;
+    sizeCompMax = 0;
 
+    for (int i = 0; i < n; i++)
+        iComp[S[i]] = NONE;
+
+    // Call BFS exploration from each node of S[]
+    for (int i = 0; i < n; i++) {
+        if (iComp[S[i]] == NONE) {
+            iComp[S[i]] = nbComp;
+            compSizes[nbComp] = 1;
+            //firstOfComp[nbComp] = S[i];
+            first = last = queue;
+            *last++ = S[i];
+            compExploreBFS(nbComp, V, S, n, g, 1);
+            if (compSizes[nbComp] > sizeCompMax) sizeCompMax = compSizes[nbComp];
+            nbNodes += compSizes[nbComp];
+            nbComp++;
+            if (nbNodes == n) break;
+        }
+    }
+    return nbComp;
+}
 
 void compExploreBFS(int num, SET V, int S[], int n, Graph g, int verif) {
     while (last != first) {
@@ -86,7 +130,7 @@ void compExploreBFS(int num, SET V, int S[], int n, Graph g, int verif) {
         }
     }
 }
-
+#endif
 
 
 // Special version for separators: the neighbors of each vertex are ordered so as that those in S
@@ -228,29 +272,6 @@ int searchConnectedComponentsGreedy(SET V, Heap heap, Graph g, int removedVertex
 
 
 
-int nbCCE = 0;
-
-void compExplore(int u, int num, SET V, int S[], int n, Graph g, int depth) {
-    LIST q = g->adj[u];
-    int nbNeighbors = 0;
-    nbCCE ++;
-
-    //if (nbCCE >= 2011872) printf("depth=%d n=%d  u=%d size=%d\n", depth, n, u, compSizes[num]);
-
-    while (q != NULL) {
-        nbNeighbors ++;
-        if (nbNeighbors > g->nadj[u]) {printf("too many neighbors !\n"); exit(0);}
-        if ((isInSet(q->val, V, S, n)) && (iComp[q->val] == NONE)) { //((IN(q->val, V)) && (iComp[q->val] == NONE)) {
-            iComp[q->val] = num;
-            compSizes[num] ++;
-            compExplore(q->val, num, V, S, n, g, depth+1);
-        }
-        q = q->suiv;
-    }
-}
-
-
-
 //
 // utils
 //
diff --git a/components.h b/components.h
index 75c9307bebb3c14c0521432b2a9b6067338f380b..0b13d52ed63c212af7d41147ffd9e03b46240923 100644
--- a/components.h
+++ b/components.h
@@ -20,9 +20,9 @@ extern int sizeCompMax;
 
 
 void allocSearchConnectedComponents(Graph g);
-int searchConnectedComponents(SET V, int S[], int n, Graph g);
+//int searchConnectedComponents(SET V, int S[], int n, Graph g);
+int searchConnectedComponents(int S[], int n, int nbNiS[], Graph g);
 int searchConnectedComponentsGreedy(SET V, Heap heap, Graph g, int removedVertex);
-void compExplore(int u, int num, SET V, int S[], int n, Graph g, int depth);
 void compExploreBFS(int num, SET V, int S[], int n, Graph g, int verif);
 int searchConnectedComponentsInHeap(Heap H, int nbNiS[], Graph g);
 void sortListByComponent(int S[], int n, int nbComp, int sizes[]);
diff --git a/decompose.c b/decompose.c
index 556d28fd7abd30a1186d760642a0c72d5d98a7a7..9a768bc5abee2beac568167cb7530c1e5ffbe630 100644
--- a/decompose.c
+++ b/decompose.c
@@ -261,8 +261,6 @@ Node decompose(int *S, int n, int pos[], int depth, Graph g, int hmax, int conne
 
     if (trace) printf("[%d] call %d  n=%d   \n", depth, nbCallsDecompose, n);
 
-    assert(depth <= g->n);
-
     if (stopSearch) return NULL;
     if (n == 0) return NULL;
     if (hmax <= 0) return NULL;
@@ -276,17 +274,27 @@ Node decompose(int *S, int n, int pos[], int depth, Graph g, int hmax, int conne
         return greedyDecompose(conHeap, depth, g, hmax, 1);
     }
 
-    SET set = NULL;
-    if (n > 105) {
-        if (theSets[depth] == NULL) reAllocSets(100, g);
-        set = makeSet(S, n, theSets[depth]);
+    if (0) {
+        SET set = NULL;
+        if (n > 105) {
+            if (theSets[depth] == NULL) reAllocSets(100, g);
+            set = makeSet(S, n, theSets[depth]);
+        } else
+            Introsort(S, S, S + n - 1);
+    }
+
+    int nbEdges = initializeNbNeighbors(S, n, pos, g); // place S neighbors first in lists
+
+    if (2*nbEdges == n*(n-1)) {
+        markRemoved(S, n, pos);
+        return makeSingleBranch(S, n, NULL, g);
     }
-    else
-        Introsort(S, S, S + n - 1);
 
     // Search connected components
-    if (depth > 0) {
-        int nbComp = searchConnectedComponents(set, S, n, g);
+    if ( ! connected) { //(depth > 0)
+        //int nbComp = searchConnectedComponents(set, S, n, g);
+        int nbComp = searchConnectedComponents(S, n, nbNeighborsInS, g);
+
         if (stopSearch) return NULL;
         if (nbComp > 1) {
             if (trace) printf("components: %d   ", nbComp);
@@ -294,23 +302,10 @@ Node decompose(int *S, int n, int pos[], int depth, Graph g, int hmax, int conne
         }
     }
 
-    int nbEdges = initializeNbNeighbors(set, S, n, pos, g); // for searchSeparator()
-
-    if (2*nbEdges == n*(n-1)) {
-        markRemoved(S, n, pos);
-        return makeSingleBranch(S, n, NULL, g);
-    }
-
-    //searchSeparator(S, n, set, g, separator, (n < 20) ? 1 : nbRunsSeparation, (n < 20) ? 1 : nbFlushes, NULL, 0);
-    searchSeparator(S, n, set, g, separator, nbRunsSeparation, nbFlushes, depth);
+    searchSeparator(S, n, g, separator, nbRunsSeparation, nbFlushes, depth);
 
     if (stopSearch) return NULL;
 
-    if (0) {
-        improveSeparation(separator, g, 0); // Seg fault with 100 runs "./treedepth -file ../public/heur_007.gr "
-        printf("improve :: %d %d %d\n", separator->B->n, separator->C->n, separator->A->n);
-    }
-
     //root = makeSingleBranchWithDisconnectedVertices(separator->C->val, separator->C->n, separator->nbABDV, g);
     Node root = makeSingleBranch(separator->C->val, separator->C->n, nbNInABCopy, g);
 
@@ -322,11 +317,6 @@ Node decompose(int *S, int n, int pos[], int depth, Graph g, int hmax, int conne
     int nC = separator->C->n;
     Node A, B;
 
-    if (0) { for (int i = 0; i < depth; i ++) printf(" "); printf("%d %d     %d\n", 1000*nA/n, 1000*nB/n, 1000*nC/n); }
-
-    assert(nC > 0); // Indeed, the subgraph is connected here.
-
-
     int *listA = S;
     int *listB = S+nA; // no need for S after here
 
diff --git a/graph.c b/graph.c
index 88fd461dcae597698b40ceccc88f449d5f9bc373..ba06d94f97bc905878bbc859d640737ec03806ee 100644
--- a/graph.c
+++ b/graph.c
@@ -142,19 +142,6 @@ int nbNeighborsInHeap(int u, Heap F, Graph g) {
 }
 
 
-int nbNeighborsInList(int u, SET V, int *S, int n, Graph g) {
-    LIST p = g->adj[u];
-    int nbN = 0;
-
-    while (p != NULL) {
-        if (isInSet(p->val, V, S, n)) {
-            nbN ++;
-        }
-        p = p->suiv;
-    }
-    return nbN;
-}
-
 int hasNoNeighborInSet(int vertex, SET V, Graph g) {
     for (int *p = g->lists[vertex]; *p != NONE; p ++)
         if (IN(*p, V)) return 0;
diff --git a/graph.h b/graph.h
index a425598cdb1ef3a9cad2203d29512cc36496064e..9cc785cde8f9793c29a047a42ca9b7eb08869ba5 100644
--- a/graph.h
+++ b/graph.h
@@ -53,7 +53,6 @@ int areNeighbours(int u, int v, Graph g);
 void printGraph(Graph g);
 int nbNeighborsInHeap(int u, Heap F, Graph g);
 int nbVerticeInHeap(int list[], int n, Heap F, Graph g);
-int nbNeighborsInList(int u, SET V, int *S, int n, Graph g);
 int hasNoNeighborInSet(int vertex, SET V, Graph g);
 int hasNeighborsInSubtree(int vertex, SET V, Graph g);
 int haveSameNeighbors(int u, int v, Graph g);
diff --git a/separator.c b/separator.c
index 835fba6ce6dad1fb763db0018b28fda536cc8877..74a7751ee04afc294c6028f235c943d040ea598e 100644
--- a/separator.c
+++ b/separator.c
@@ -73,6 +73,9 @@ int sizeMax;
 // Connected components
 int *component;
 
+int computeComponents = 0; // to detect components during separation and use it for evaluation
+Components AComp, BComp;
+
 
 //
 // Warning: the preliminary call to initializeNbNeighbors() place first in the lists of neighbors
@@ -85,7 +88,7 @@ int *nbSearches;
 int *sumSizes;
 #endif
 
-int searchSeparator(int *S, int n, SET V, Graph g, Separator theSeparator, int nTries, int nFlushes, int depth) {
+int searchSeparator(int *S, int n, Graph g, Separator theSeparator, int nTries, int nFlushes, int depth) {
 
 #ifdef STATS_SEPARATION
     if (timesSep == NULL) {
@@ -130,9 +133,9 @@ int searchSeparator(int *S, int n, SET V, Graph g, Separator theSeparator, int n
 
         randomizePriorities(S, n, g);
 
-        initSeparator(V, S, n, g, sep);
+        initSeparator(S, n, g, sep);
 
-        separe(S, n, V, g, sep, nFlushes, modeEvalSeparator);
+        separe(S, n, g, sep, nFlushes, modeEvalSeparator);
 
         if ((stopSearch) || ((clock()-start)/CLOCKS_PER_SEC > maxTimeSeparation/(depth+1))) break;
     }
@@ -207,7 +210,7 @@ int chooseFirstVertex(int *S, int n, Graph g) {
 
 
 
-int separe(int *S, int n, SET V, Graph g, Separator s, int nbFlushs, int mode) {
+int separe(int *S, int n, Graph g, Separator s, int nbFlushs, int mode) {
 
     int firstVertex;
 
@@ -232,10 +235,15 @@ int separe(int *S, int n, SET V, Graph g, Separator s, int nbFlushs, int mode) {
             firstVertex = (i > 0) ? NONE : chooseFirstVertex(S, n, g);
         }
 
+        if (computeComponents) {
+            if (i == 0) AComp->size = AComp->maxsize = 0;
+            else initializeComponents(AComp, A, g);
+        }
+
         heapSetCompare(C, compareCVerticesFlushBtoA);
         makeHeap(C);
 
-        flushBtoA(A, B, C, V, S, n, mode, firstVertex, g);
+        flushBtoA(A, B, C, S, n, mode, firstVertex, g);
 
         if (stopSearch) break;
 
@@ -248,10 +256,12 @@ int separe(int *S, int n, SET V, Graph g, Separator s, int nbFlushs, int mode) {
         else
             makeHeap(A);
 
+        if (computeComponents) initializeComponents(BComp, B, g);
+
         heapSetCompare(C, compareCVerticesFlushAtoB);
         makeHeap(C);
 
-        flushAtoB(A, B, C, V, S, n, mode, g);
+        flushAtoB(A, B, C, S, n, mode, g);
 
         if (stopSearch) break;
     }
@@ -269,6 +279,9 @@ double evalSep(int nA, int nB, int nC, int mA, int mB, int mode, int direction)
     // Should consider here the particular cases (B->n=0, C->n=0,...)
 
     int min = (nA > nB) ? nB : nA;
+
+    if (mode == EVAL_CARD) return ((double) (min) / (nC+1)); // modified 1/05
+
     int max = (nA > nB) ? nA : nB;
     int delta = max-min;
     int maxE = (mA > mB) ? mA : mB;
@@ -297,8 +310,6 @@ double evalSep(int nA, int nB, int nC, int mA, int mB, int mode, int direction)
         return ((rab - deltaSqrt) / (1+nC));
     }
 
-    if (mode == EVAL_CARD) return ((double) (min) / (nC+1)); // modified 1/05
-
     if (mode == EVAL_LEVEL_DENSITY) {
         // evaluate the cost to place vertices of C and the smallest among A and B
         // evaluating the number of vertices of these sets per level
@@ -413,7 +424,7 @@ int chooseEltInA(Heap A) {
 int testSourceConnected = 0;
 int thresholdConComponents = 13;
 
-void flushBtoA(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, int seed, Graph g) {
+void flushBtoA(Heap A, Heap B, Heap C, int S[], int n, int mode, int seed, Graph g) {
     int e = NONE;
     int bestASize = NONE;
 
@@ -444,15 +455,16 @@ void flushBtoA(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, int seed
             else if (useMinPartitions == 2) minheapJustRemove(e, B, nbNeighborsInB);
             else heapRemove(e, B);
             nbEdgesInB = nbEdgesInB-nbNeighborsInB[e];
-            decreaseNbNeighborsInB(e, B, C, V, S, n, g);
+            decreaseNbNeighborsInB(e, B, C, g);
         }
 
         // insert e in A
+        if (computeComponents) createNewAComponent(e, AComp);
         heapJustAdd(e, A);
-        increaseNbNeighborsInA(e, C, V, S, n, g);
+        increaseNbNeighborsInA(e, C, A, g);
 
         // move e neighbors which are in B to C
-        removeNeighborsFromB(e, A, B, C, V, S, n, g);
+        removeNeighborsFromB(e, A, B, C, g);
 
         if (A->n >= sizeMax) break;
 
@@ -470,7 +482,7 @@ void flushBtoA(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, int seed
                 }
             }
 
-            double e = evalSep(A->n, nB, C->n, nbEdgesInA, nEB, mode, FLUSH_B_A);
+            double e = evalSep(computeComponents ? AComp->maxsize : A->n, nB, C->n, nbEdgesInA, nEB, mode, FLUSH_B_A);
 
             if ((bestIsUninitialized) || (e > bestEval)) {
                 // There can be vertices in C with no neighbor in B
@@ -485,7 +497,8 @@ void flushBtoA(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, int seed
         }
     }
     if ((bestIsUninitialized) && (A->n < n)) {
-        if (1) pourCintoA(A, nbNeighborsInB, nbNeighborsInA, &nbEdgesInA, C, g, 1);
+        if (computeComponents) pourCintoPart(A, AComp, nbNeighborsInB, nbNeighborsInA, &nbEdgesInA, C, g, 1);
+        else pourCintoA(A, nbNeighborsInB, nbNeighborsInA, &nbEdgesInA, C, g, 1);
         bestIsUninitialized = 0;
         bestEval = e;
         copySeparator(sep, bestSep);
@@ -500,7 +513,7 @@ void flushBtoA(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, int seed
 
 
 
-void flushAtoB(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, Graph g) {
+void flushAtoB(Heap A, Heap B, Heap C, int S[], int n, int mode, Graph g) {
     int e = NONE;
     int bestBSize = NONE;
 
@@ -525,15 +538,16 @@ void flushAtoB(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, Graph g)
             else if (useMinPartitions == 2) minheapJustRemove(e, A, nbNeighborsInA);
             else heapRemove(e, A);
             nbEdgesInA -= nbNeighborsInA[e];
-            decreaseNbNeighborsInA(e, A, C, V, S, n, g);
+            decreaseNbNeighborsInA(e, A, C, g);
         }
 
         // insert e in B
         heapJustAdd(e, B);
-        increaseNbNeighborsInB(e, C, V, S, n, g);
+        if (computeComponents) createNewAComponent(e, BComp);
+        increaseNbNeighborsInB(e, C, B, g);
 
         // move e neighbors which are in A to C
-        removeNeighborsFromA(e, A, B, C, V, S, n, g);
+        removeNeighborsFromA(e, A, B, C, g);
 
         if (B->n >= sizeMax) break;
 
@@ -551,10 +565,11 @@ void flushAtoB(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, Graph g)
                 }
             }
 
-            double e = evalSep(nA, B->n, C->n, nEA, nbEdgesInB, mode, FLUSH_A_B);
+            double e = evalSep(nA, computeComponents ? BComp->maxsize : B->n, C->n, nEA, nbEdgesInB, mode, FLUSH_A_B);
 
             if ((bestIsUninitialized) || (e > bestEval)) {
-                if (1) pourCintoA(B, nbNeighborsInA, nbNeighborsInB, &nbEdgesInB, C, g, 1);
+                if (computeComponents) pourCintoPart(B, BComp, nbNeighborsInA, nbNeighborsInB, &nbEdgesInB, C, g, 1);
+                else pourCintoA(B, nbNeighborsInA, nbNeighborsInB, &nbEdgesInB, C, g, 1);
                 bestIsUninitialized = 0;
                 bestEval = e;
                 if (separatorJustMemorizeReceptorSize && (g->n >= separatorJustMemoSizeMin)) {
@@ -566,7 +581,6 @@ void flushAtoB(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, Graph g)
         }
     }
     if ((separatorJustMemorizeReceptorSize) && (bestBSize != NONE)) {
-        int nB = B->n;
         copySeparator(sep, bestSep);
         builtBestSeparator(bestSep->B, bestSep->A, bestSep->C, nbNeighborsInB, nbNeighborsInA, bestBSize, g);
     }
@@ -616,7 +630,7 @@ void builtBestSeparator(Heap dest, Heap src, Heap C, int nbNdest[], int nbNsrc[]
 
 
 // FlushBtoA() :: e has been moved to A. e neighbors which are in B must be moved to C.
-void removeNeighborsFromB(int e, Heap A, Heap B, Heap C, SET V, int *S, int n, Graph g) {
+void removeNeighborsFromB(int e, Heap A, Heap B, Heap C, Graph g) {
     int nbToThrow = 0;
 
     for (int *p = g->lists[e]; p-g->lists[e] < nbNeighborsInS[e]; p ++) { //(*p != NONE) : useless, first neighbors are in S
@@ -634,7 +648,7 @@ void removeNeighborsFromB(int e, Heap A, Heap B, Heap C, SET V, int *S, int n, G
             heapInsert(*p, C);
             nbEdgesInB -= nbNeighborsInB[*p];
 
-            decreaseNbNeighborsInB(*p, B, C, V, S, n, g);
+            decreaseNbNeighborsInB(*p, B, C, g);
         }
     }
 
@@ -646,15 +660,16 @@ void removeNeighborsFromB(int e, Heap A, Heap B, Heap C, SET V, int *S, int n, G
         if ((C->ind[*p] != NONE) && (nbNeighborsInB[*p] == 0)) {
             heapRemove(*p, C);
             heapJustAdd(*p, A);
+            if (computeComponents) createNewAComponent(*p, AComp);
             nbEdgesInA += nbNeighborsInA[*p];
-            increaseNbNeighborsInA(*p, C, V, S, n, g);
+            increaseNbNeighborsInA(*p, C, A, g);
         }
     }
 }
 
 
 
-void removeNeighborsFromA(int e, Heap A, Heap B, Heap C, SET V, int *S, int n, Graph g) {
+void removeNeighborsFromA(int e, Heap A, Heap B, Heap C, Graph g) {
     int movesToB = 0;
     for (int *p = g->lists[e]; p-g->lists[e] < nbNeighborsInS[e]; p ++) {
         if (A->ind[*p] != NONE) {
@@ -671,7 +686,7 @@ void removeNeighborsFromA(int e, Heap A, Heap B, Heap C, SET V, int *S, int n, G
             heapInsert(*p, C);
             nbEdgesInA -= nbNeighborsInA[*p];
 
-            decreaseNbNeighborsInA(*p, A, C, V, S, n, g);
+            decreaseNbNeighborsInA(*p, A, C, g);
         }
     }
 
@@ -682,8 +697,9 @@ void removeNeighborsFromA(int e, Heap A, Heap B, Heap C, SET V, int *S, int n, G
         if ((C->ind[*p] != NONE) && (nbNeighborsInA[*p] == 0)) {
             heapRemove(*p, C);
             heapJustAdd(*p, B);
+            if (computeComponents) createNewAComponent(*p, BComp);
             nbEdgesInB += nbNeighborsInB[*p];
-            increaseNbNeighborsInB(*p, C, V, S, n, g);
+            increaseNbNeighborsInB(*p, C, B, g);
         }
     }
 }
@@ -853,6 +869,29 @@ int compareCVerticesFlushAtoB(int a, int b) {
 // Dust separator: for vertices of C that have no neighbor in A or B
 //
 
+void pourCintoPart(Heap dest, Components ABC, int *nbNFrom, int *nbNTo, int *nbEdges, Heap C, Graph g, int justAdd) {
+    // move isolated vertices from C to A or B
+    for (int i = 0; i < C->n; i++) {
+        int e = C->val[i];
+        if (nbNFrom[e] == 0) {
+            heapRemove(e, C);
+            if (justAdd)
+                heapJustAdd(e, dest);
+            else
+                heapInsert(e, dest);
+
+            if (computeComponents) createNewAComponent(e, ABC);
+
+            *nbEdges = *nbEdges + nbNTo[e];
+            for (int *p = g->lists[e]; p < g->lists[e]+nbNeighborsInS[e]; p ++) {
+                nbNTo[*p]++;
+                if (computeComponents) if (dest->ind[*p] != NONE)
+                        updateComponents(e, *p, ABC, g);
+            }
+        }
+    }
+}
+
 void pourCintoA(Heap A, int nbNFrom[], int nbNTo[], int *nbEdges, Heap C, Graph g, int justAdd) {
     for (int i = 0; i < C->n; i++) {
         int e = C->val[i];
@@ -1100,6 +1139,22 @@ void allocSeparation(Graph g) {
     priorities = malloc(g->n * sizeof(int));
 
     verticesToThrow = malloc(g->n * sizeof(int));
+
+    if (computeComponents) {
+        AComp = malloc(sizeof(struct components));
+        BComp = malloc(sizeof(struct components));
+
+        AComp->fathers = malloc(g->n * sizeof(int));
+        AComp->sizes = malloc(g->n * sizeof(int));
+        AComp->edges = malloc(g->n * sizeof(int));
+        AComp->roots = malloc(g->n * sizeof(int));
+        AComp->comp = malloc(g->n * sizeof(int));
+        BComp->fathers = malloc(g->n * sizeof(int));
+        BComp->sizes = malloc(g->n * sizeof(int));
+        BComp->edges = malloc(g->n * sizeof(int));
+        BComp->roots = malloc(g->n * sizeof(int));
+        BComp->comp = malloc(g->n * sizeof(int));
+    }
 }
 
 
@@ -1130,7 +1185,7 @@ void recoverNbNeighbors(int S[], int n) {
 
 
 
-int initializeNbNeighbors(SET V, int S[], int n, int pos[], Graph g) {
+int initializeNbNeighbors(int S[], int n, int pos[], Graph g) {
     nbEdgesInS = 0;
     minDegree = n+1;
     maxDegree = -1;
@@ -1159,7 +1214,7 @@ int initializeNbNeighbors(SET V, int S[], int n, int pos[], Graph g) {
 
 
 
-void initSeparator(SET V, int *S, int n, Graph g, Separator s) {
+void initSeparator(int *S, int n, Graph g, Separator s) {
 
     resetHeap(s->A);
     resetHeap(s->B);
@@ -1177,6 +1232,11 @@ void initSeparator(SET V, int *S, int n, Graph g, Separator s) {
     }
 
     recoverNbNeighbors(S, n);
+
+    if (computeComponents) {
+        AComp->size = 0;
+        BComp->size = 0;
+    }
 }
 
 
@@ -1228,7 +1288,7 @@ void printSeparator(Separator s) {
 int nbCallsdecreaseNbNeighborsInB = 0;
 // Only for flushBtoA stage. u has been removed from B => decrease the number of neighbors in B for all B neighbors,
 // Neighbors have been ordered so that those in S[] occur first in the list
-void decreaseNbNeighborsInB(int u, Heap B, Heap C, SET V, int S[], int n, Graph g) {
+void decreaseNbNeighborsInB(int u, Heap B, Heap C, Graph g) {
     int nb = 0;
 
         for (int * p = g->lists[u]; *p != NONE; p ++) {
@@ -1248,12 +1308,15 @@ void decreaseNbNeighborsInB(int u, Heap B, Heap C, SET V, int S[], int n, Graph
 
 
 // Only for flushAtoB(). u has been inserted in B (for flushAtoB)
-void increaseNbNeighborsInB(int u, Heap C, SET V, int S[], int n, Graph g) {
+void increaseNbNeighborsInB(int u, Heap C, Heap B, Graph g) {
     int nb = 0;
     for (int *pp = g->lists[u]; *pp != NONE; pp ++) {
         nbNeighborsInB[*pp] ++;
         if (C->ind[*pp] != NONE)
             heapBubbleUp(C->ind[*pp], C);
+        else if ((computeComponents) && (B->ind[*pp] != NONE)) {
+            updateComponents(u, *pp, BComp, g);
+        }
         if ( ++ nb == nbNeighborsInS[u]) break;
     }
 }
@@ -1261,7 +1324,7 @@ void increaseNbNeighborsInB(int u, Heap C, SET V, int S[], int n, Graph g) {
 
 
 // for flushAtoB
-void decreaseNbNeighborsInA(int u, Heap A, Heap C, SET V, int S[], int n, Graph g) {
+void decreaseNbNeighborsInA(int u, Heap A, Heap C, Graph g) {
     int nb = 0;
     for (int *p = g->lists[u]; *p != NONE; p ++) {
         nbNeighborsInA[*p] --;
@@ -1275,22 +1338,23 @@ void decreaseNbNeighborsInA(int u, Heap A, Heap C, SET V, int S[], int n, Graph
             heapBubbleUp(C->ind[*p], C);
         if ( ++ nb == nbNeighborsInS[u]) break;
     }
-    return;
 }
 
 
 
 // for flushBtoA
-void increaseNbNeighborsInA(int u, Heap C, SET V, int S[], int n, Graph g) {
+void increaseNbNeighborsInA(int u, Heap C, Heap A, Graph g) {
     int nb = 0;
     for (int *pp = g->lists[u]; *pp != NONE; pp ++) {
         nbNeighborsInA[*pp] ++;
         if (C->ind[*pp] != NONE)
             heapBubbleUp(C->ind[*pp], C);
+        else if (computeComponents) if (A->ind[*pp] != NONE) {
+                updateComponents(u, *pp, AComp, g);
+            }
         // It is useless to consider u neighbors which are in B, there is none
         if ( ++ nb == nbNeighborsInS[u]) break; // first neighbors are those in S[]
     }
-    return;
 }
 
 
@@ -1327,5 +1391,142 @@ void randomizePriorities(int S[], int n, Graph g) {
 
 
 
+//
+// A and B components during separation, utilies.
+//
+
+int verifyHeapComponents(Heap H, Components C, Graph g) {
+    int *father = C->fathers;
+    int *component = C->comp;
+    int *size = C->sizes;
+    int *root = C->roots;
+    int nbComp = C->size;
+    int nb[nbComp], nbC = 0;
+    for (int i = 0; i < nbComp; i ++) {
+        nb[i] = 0;
+        if (father[root[i]] != NONE) printf("father of root %d is not NONE\n", root[i]);
+    }
+    for (int i = 0; i < H->n; i ++) {
+        int e = H->val[i];
+        if (father[e] == NONE) nbC ++;
+        if ((father[e] == NONE) && ((component[e] >= nbComp) || (root[component[e]] != e)))
+            printf("problem %d should be root of comp %d\n", e, component[e]);
+    }
+    if (nbC != nbComp) printf("find %d components, %d given\n", nbC, nbComp);
+    return 1;
+}
+
+
+
+// Initialize ABComponents given components calculated with a BFS
+int initializeComponents(Components C, Heap H, Graph g) {
+
+    C->size = searchConnectedComponentsInHeap(H, nbNeighborsInS, g);
+
+    for (int i = 0; i < C->size; i ++)
+        C->sizes[i] = 0;
+
+    C->maxedges = 0;
+    for (int i = 0; i < H->n; i ++) {
+        int comp = iComp[H->val[i]];
+        C->comp[H->val[i]] = comp; // useless, only the root needs its component
+        C->sizes[comp] ++;
+        if (C->sizes[comp] == 1) {
+            C->roots[comp] = H->val[i];
+            C->fathers[H->val[i]] = NONE;
+            C->edges[comp] = compNbEdges[comp];
+            if (compNbEdges[comp] > C->maxedges) C->maxedges = compNbEdges[comp];
+        }
+        else
+            C->fathers[H->val[i]] = C->roots[comp];
+    }
+
+    C->maxsize = 0;
+    for (int i = 0; i < C->size; i ++)
+        if (C->sizes[i] > C->maxsize)
+            C->maxsize = C->sizes[i];
+
+    //verifyHeapComponents(H, C, g);
+    return C->size;
+}
+
+
+
+int getABComponent(int u, int *father) {
+    int uu = u, tmp;
+    while (father[u] != NONE) u = father[u];
+    while (uu != u) { tmp = father[uu]; father[uu] = u; uu = tmp; }
+    return u;
+}
+
+int callUC = 0;
+int updateComponents(int u, int v, Components C, Graph g) {
+//        int *father, int *component, int *size, int *root, int nbComp, Graph g) {
+// Add edge (u,v), merge components if different.
+
+    callUC++;
+    if ((v == 109) && (C->fathers[v] == 109))
+        printf("OUYE %d\n", callUC);
+
+    int ru = getABComponent(u, C->fathers);
+    int rv = getABComponent(v, C->fathers);
+
+    if (ru != rv) {
+        // merge components
+        int compu = C->comp[ru];
+        int compv = C->comp[rv];
+        if (C->sizes[compu] > C->sizes[compv]) {
+            C->sizes[compu] += C->sizes[compv];
+            C->edges[compu] += C->edges[compv]+1;
+            if (C->edges[compu] > C->maxedges) C->maxedges = C->edges[compu];
+            C->fathers[rv] = ru;
+            if (C->sizes[compu] > C->maxsize) C->maxsize = C->sizes[compu];
+            C->size --;
+            if (compv != C->size) {
+                // must swap last component and compv
+                int lastroot = C->roots[C->size];
+                C->roots[compv] = lastroot;
+                C->sizes[compv] = C->sizes[C->size];
+                C->comp[lastroot] = compv;
+            }
+        }
+        else {
+            C->sizes[compv] += C->sizes[compu];
+            C->edges[compv] += C->edges[compu]+1;
+            if (C->edges[compv] > C->maxedges) C->maxedges = C->edges[compv];
+            C->fathers[ru] = rv;
+            if (C->sizes[compv] > C->maxsize) C->maxsize = C->sizes[compv];
+            C->size --;
+            if (compu != C->size) {
+                // must swap last component and compu
+                int lastroot = C->roots[C->size];
+                C->roots[compu] = lastroot;
+                C->sizes[compu] = C->sizes[C->size];
+                C->comp[lastroot] = compu;
+            }
+        }
+    }
+    else {
+        C->edges[C->comp[ru]] ++;
+        if (C->edges[C->comp[ru]] > C->maxedges) C->maxedges = C->edges[C->comp[ru]];
+    }
+    return C->size;
+}
+
+
+void createNewAComponent(int e, Components C) {
+    C->fathers[e] = NONE;
+    C->sizes[C->size] = 1;
+    C->edges[C->size] = 0;
+    if (C->maxsize == 0) C->maxsize = 1;
+    C->comp[e] = C->size;
+    C->roots[C->size] = e;
+    C->size ++;
+}
+
+
+
+
+
 
 
diff --git a/separator.h b/separator.h
index 4127677d016d9dbffc920136b9a332fbf2c955ec..b5ef327861156c3ba8a9cd80ef685229ce5be0ff 100644
--- a/separator.h
+++ b/separator.h
@@ -45,8 +45,24 @@ struct separator {
 
 
 
+typedef struct components * Components;
+struct components {
+    int *fathers;
+    int *sizes;
+    int *edges;
+    int *roots;
+    int *comp;
+    int size;
+    int maxsize;
+    int maxedges;
+};
+
+
+
 extern int *nbNeighborsInA;
 extern int *nbNeighborsInB;
+extern int * nbNeighborsInS;
+
 extern int nbEdgesInA, nbEdgesInB;
 
 extern int * nbNInABCopy;
@@ -58,21 +74,22 @@ extern int nbCallsSepare;
 
 double evalSep(int nA, int nB, int nC, int mA, int mB, int mode, int direction);
 
-int searchSeparator(int *S, int n, SET V, Graph g, Separator theSeparator, int nTries, int nFlushes, int depth);
-int separe(int *S, int n, SET V, Graph g, Separator s, int nbFlushs, int mode);
-void flushBtoA(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, int seed, Graph g);
-void flushAtoB(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, Graph g);
+int searchSeparator(int *S, int n, Graph g, Separator theSeparator, int nTries, int nFlushes, int depth);
+int separe(int *S, int n, Graph g, Separator s, int nbFlushs, int mode);
+void flushBtoA(Heap A, Heap B, Heap C, int S[], int n, int mode, int seed, Graph g);
+void flushAtoB(Heap A, Heap B, Heap C, int S[], int n, int mode, Graph g);
 
 void builtBestSeparator(Heap dest, Heap src, Heap C, int nbNdest[], int nbNsrc[], int size, Graph g);
 
-void removeNeighborsFromA(int e, Heap A, Heap B, Heap C, SET V, int *S, int n, Graph g);
-void removeNeighborsFromB(int e, Heap A, Heap B, Heap C, SET V, int *S, int n, Graph g);
+void removeNeighborsFromA(int e, Heap A, Heap B, Heap C, Graph g);
+void removeNeighborsFromB(int e, Heap A, Heap B, Heap C, Graph g);
 
 int isSmallerNeighborsInB(int a, int b);
 int isSmallerNeighborsInA(int a, int b);
 int compareCVerticesFlushBtoA(int a, int b);
 int compareCVerticesFlushAtoB(int a, int b);
 
+void pourCintoPart(Heap dest, Components ABC, int *nbNFrom, int *nbNTo, int *nbEdges, Heap C, Graph g, int justAdd);
 void pourCintoA(Heap A, int nbNFrom[], int nbNTo[], int *nbEdges, Heap C, Graph g, int justAdd);
 
 void allocSeparation(Graph g);
@@ -88,23 +105,31 @@ int searchMoveBC(Separator s, Graph g, int movesCA[], int *the);
 void makeMove(int v, Heap source, Heap dest);
 
 Separator newSeparator(int size, Graph g);
-int initializeNbNeighbors(SET V, int S[], int n, int pos[], Graph g);
+int initializeNbNeighbors(int S[], int n, int pos[], Graph g);
 void recoverNbNeighbors(int S[], int n);
-void initSeparator(SET V, int *S, int n, Graph g, Separator s);
+void initSeparator(int *S, int n, Graph g, Separator s);
 //void removeFromB(int v, Separator s);
 //void removeFromC(int v, Separator s);
 //void addInC(int v, Separator s);
 void printSeparator(Separator s);
 int verifySeparator(int *S, int n, Separator s);
 
-void decreaseNbNeighborsInB(int u, Heap B, Heap C, SET V, int S[], int n, Graph g);
-void decreaseNbNeighborsInA(int u, Heap A, Heap C, SET V, int S[], int n, Graph g);
-void increaseNbNeighborsInA(int u, Heap C, SET V, int S[], int n, Graph g);
-void increaseNbNeighborsInB(int u, Heap C, SET V, int S[], int n, Graph g);
+void decreaseNbNeighborsInB(int u, Heap B, Heap C, Graph g);
+void decreaseNbNeighborsInA(int u, Heap A, Heap C, Graph g);
+void increaseNbNeighborsInA(int u, Heap C, Heap A, Graph g);
+void increaseNbNeighborsInB(int u, Heap C, Heap B, Graph g);
 int verifyNbNeighbors(Heap A, Heap B, Heap C, SET V, int S[], int n, Graph g);
 
 void initializePriorities(Graph g);
 void randomizePriorities(int S[], int n, Graph g);
 
 
+// A/B components
+int verifyHeapComponents(Heap H, Components C, Graph g);
+int initializeComponents(Components C, Heap H, Graph g);
+
+int updateComponents(int u, int v, Components C, Graph g);
+
+void createNewAComponent(int e, Components C);
+
 #endif //SRC_SEPARATOR_H
diff --git a/tree.c b/tree.c
index 0e5752ac703746d232f5f38b4f7a6d9f4a4dd14d..5921b611843eb346c083cde8c66aefe372718467 100644
--- a/tree.c
+++ b/tree.c
@@ -120,7 +120,8 @@ int nbNeighborsAbove(Node node, Graph g) {
 
     Node p = node->father;
     while (p != NULL) {
-        if (isInSet(p->vertex, NULL, N, nN))
+        //if (isInSet(p->vertex, NULL, N, nN))
+        if (isInList(p->vertex, N, nN))
             nb ++;
         p = p->father;
     }
diff --git a/utils.c b/utils.c
index d1af18499a29c153e57f1b21ad205034bd3e1a94..45939a125022b00454f8e4d3abe3b68e8ba87b44 100644
--- a/utils.c
+++ b/utils.c
@@ -113,30 +113,6 @@ int nbInListWithThisValue(int val, int *S, int n, int *values) {
 
 
 
-// search in set, either a SET of a sorted list
-int isInSet(int v, SET S, int T[], int n) {
-
-    if (S != NULL) {
-        return IN(v, S);
-    }
-
-    if (n == 0) return 0;
-
-    int l = 0;
-    int r = n;
-    // l <= pos < r
-    while (l+1 < r) {
-        int m = (l+r)/2;
-        if (v >= T[m])
-            l = m;
-        else
-            r = m;
-    }
-    // l+1=r and l <= pos < r
-    return (v == T[l]);
-}
-
-
 
 // search v in the list,
 int isInList(int v, int T[], int n) {
diff --git a/utils.h b/utils.h
index ce264fced94fc1fed6081fd00cacc0023ac32a61..d6401b117efbd036505ec538c3ab28a1df82f65c 100644
--- a/utils.h
+++ b/utils.h
@@ -21,7 +21,6 @@ int packListLeft(int num, int S[], int n, int C[]);
 void copyListLeft(int S[], int start, int size);
 int nbInListWithThisValue(int num, int *S, int n, int *values);
 
-int isInSet(int v, SET S, int T[], int n);
 int isInList(int v, int T[], int n);
 
 void swap(int arr[], int i, int j);