@Override
 public void execute(int i) throws ContradictionException {
   int from = i / n - 1;
   int to = i % n;
   int x = sccOf[from].get();
   if (x == sccOf[to].get()) {
     if (!sccComputed.get(x)) {
       restriction.clear();
       int k = sccFirst[x].get();
       while (k != -1) {
         restriction.set(k);
         k = sccNext[k].get();
       }
       // piste1 algo faux
       ArrayList<TIntArrayList> newSCC =
           StrongConnectivityFinder.findAllSCCOf(G.getEnvelopGraph(), restriction);
       sccComputed.set(x);
       int ns = newSCC.size();
       if (ns > 1) {
         int first = G_R.getPredecessorsOf(x).getFirstElement();
         int last = G_R.getSuccessorsOf(x).getFirstElement();
         // SCC broken
         sccFirst[x].set(-1);
         mates[x].clear();
         G_R.removeArc(first, x);
         G_R.removeArc(x, last);
         // first scc
         for (int e = 0; e < newSCC.get(0).size(); e++) {
           addNode(x, newSCC.get(0).get(e));
         }
         // others
         int idx = n_R.get();
         int elem;
         for (int scc = 1; scc < ns; scc++) {
           sccFirst[idx].set(-1);
           mates[idx].clear();
           G_R.getActiveNodes().activate(idx);
           for (int e = 0; e < newSCC.get(scc).size(); e++) {
             elem = newSCC.get(scc).get(e);
             addNode(idx, elem);
             sccOf[elem].set(idx);
           }
           idx++;
         }
         n_R.set(idx);
         // link arcs
         int e, sccE;
         INeighbors nei;
         for (int scc = 0; scc < ns; scc++) {
           sccE = sccOf[newSCC.get(scc).get(0)].get();
           for (k = newSCC.get(scc).size() - 1; k >= 0; k--) {
             e = newSCC.get(scc).get(k);
             nei = G.getEnvelopGraph().getSuccessorsOf(e);
             for (int next = nei.getFirstElement(); next >= 0; next = nei.getNextElement()) {
               if (sccE != sccOf[next].get()) {
                 G_R.addArc(sccE, sccOf[next].get());
                 mates[sccE].add((e + 1) * n + next);
               }
             }
           }
         }
         for (int arc = mates[first].getFirstElement();
             arc >= 0;
             arc = mates[first].getNextElement()) {
           G_R.addArc(first, sccOf[arc % n].get());
         }
         // filter
         if (visit(first, last) != ns + 2) {
           p.contradiction(G, "no Hamiltonian path");
         }
       }
     }
   } else {
     mates[x].remove(i);
     if (mates[x].neighborhoodSize() == 0) {
       p.contradiction(G, "G_R disconnected");
     }
   }
 }
 @Override
 public void propagate(int evtmask) throws ContradictionException {
   for (int i = 0; i < n; i++) {
     sccFirst[i].set(-1);
     sccNext[i].set(-1);
     mates[i].clear();
     G_R.getActiveNodes().desactivate(i);
   }
   ArrayList<TIntArrayList> allSCC = StrongConnectivityFinder.findAllSCCOf(G.getEnvelopGraph());
   int s = allSCC.size();
   n_R.set(s);
   int elem;
   TIntArrayList list;
   for (int i = 0; i < s; i++) {
     list = allSCC.get(i);
     G_R.getActiveNodes().activate(i);
     for (int j = list.size() - 1; j >= 0; j--) {
       elem = list.get(j);
       sccOf[elem].set(i);
       addNode(i, elem);
     }
   }
   INeighbors succs;
   int x;
   for (int i = 0; i < n; i++) {
     x = sccOf[i].get();
     succs = G.getEnvelopGraph().getSuccessorsOf(i);
     for (int j = succs.getFirstElement(); j >= 0; j = succs.getNextElement()) {
       if (x != sccOf[j].get()) {
         G_R.addArc(x, sccOf[j].get());
         mates[x].add((i + 1) * n + j);
       }
     }
   }
   int first = -1;
   int last = -1;
   for (int i = 0; i < s; i++) {
     if (G_R.getPredecessorsOf(i).isEmpty()) {
       first = i;
     }
     if (G_R.getSuccessorsOf(i).isEmpty()) {
       last = i;
     }
   }
   if (first == -1 || last == -1 || first == last) {
     contradiction(G, "");
   }
   if (visit(first, last) != n_R.get()) {
     contradiction(G, "");
   }
   int to, arc;
   for (int i = 0; i < n; i++) {
     to = G.getKernelGraph().getSuccessorsOf(i).getFirstElement();
     x = sccOf[i].get();
     if (to != -1 && sccOf[to].get() != x && mates[x].neighborhoodSize() > 1) {
       arc = (i + 1) * n + to;
       for (int a = mates[x].getFirstElement(); a >= 0; a = mates[x].getNextElement()) {
         if (a != arc) {
           G.removeArc(a / n - 1, a % n, this);
         }
       }
       mates[x].clear();
       mates[x].add(arc);
     }
   }
 }