
#include "factor_star_dfs.h"

static DEFAULTOPTIONS(options);

extern int timeval_subtract(struct timeval *result, struct timeval *t2, struct timeval *t1);

FACTOR_STAR_DFS::FACTOR_STAR_DFS(int a,int b, int c, int d, int e, int f, int g, int h, int n) {

    int i, j;

    struct timeval tvBegin, tvEnd, tvDiff;

    perm_pole_2_fak = 2;
    perm_pole_3_fak = 6;
    perm_pole_4_fak = 24;
    perm_pole_5_fak = 120;
    perm_pole_6_fak = 720;
    perm_pole_tmp = 0;

    faktorizacia_pocet = 0;

    option.SEMI_CHECK = a; 
    option.SEMI_POZICIA_FARBA_POCAS = b; 
    option.SEMI_POZICIA_FARBA_KONIEC = c; 
    option.SEMI_POZICIA_OFARBENIE_KONIEC = d; 
    option.VYPIS = e; 
    option.NAUTY = f; 
    option.NAUTY_POZICIA_FARBA_KONIEC = g; 
    option.NAUTY_POZICIA_OFARBENIE_KONIEC = h;
    option.NAUTY_D_TABULKA = n;

    zapis_iba_do_labu = 0;

    NaplnDefault();

    for (i = 0; i < 2 * POCET_VRCHOLOV_FARBA - 1; i++) {
        cesta_global[i] = -1;
    }

    cesta_global[0] = 0;
    cesta_global[1] = default_susedia[0][0];

    gettimeofday(&tvBegin, NULL);
    najdi_faktorizaciu(cesta_global, su_ofarbene, ofarbenie, farby_level, pocet_farieb_level);
    gettimeofday(&tvEnd, NULL);
    timeval_subtract(&tvDiff, &tvEnd, &tvBegin);

    

    if (option.VYPIS == 1) {
        for (j = 0; j < faktorizacia_pocet; j++) {
            for (i = 0; i < POCET_VRCHOLOV; i++) {
                printf("%d ", faktorizacia[j]->ofarbenie[i]);
            }
            printf("\n");
        }
    }

    printf("Pocet vysledkov: %d\n", faktorizacia_pocet);
    printf("Doba trvania: %ld.%06ld (sekund)\n", tvDiff.tv_sec, tvDiff.tv_usec);
}

FACTOR_STAR_DFS::~FACTOR_STAR_DFS() {
}

void FACTOR_STAR_DFS::najdi_faktorizaciu(int cesta[2 * POCET_VRCHOLOV_FARBA - 1], int su_ofarbene_lokal[POCET_VRCHOLOV], int ofarbenie_lokal[POCET_VRCHOLOV], int farby_level_lokal[DIMENSION - 1][MAX_FARIEB][POCET_VRCHOLOV_FARBA], int pocet_farieb_level_lokal[DIMENSION - 1]) {


    int susedia_new[POCET_SUSEDOV][POCET_SUSEDOV + 1];
    int lokal_cesta[2 * POCET_VRCHOLOV_FARBA - 1];

    unsigned int farba[POCET_VRCHOLOV_FARBA];
    unsigned int ok, tmp_farba;
    unsigned int level;
    unsigned int last;
    unsigned int last_back;
    unsigned int level_back;
    unsigned int vrchol_back;

    unsigned int i, j, k, l, n;
    
    for (i = 0; i < POCET_FARIEB - 1; ++i) {
        if (ofarbenie_lokal[i * POCET_VRCHOLOV_FARBA + POCET_VRCHOLOV_FARBA - 1] == -1) {
            break;
        }
    }
    level = i;

    if (level == POCET_FARIEB - 1) {
        i = 1;
        for (j = POCET_VRCHOLOV; j != 0;) {
            --j;
            if (su_ofarbene_lokal[j] == -1) {
                ofarbenie_lokal[level * POCET_VRCHOLOV_FARBA + i] = j;
                su_ofarbene_lokal[j] = level;
                i++;
            }
        }
        if ((level != 0) && (option.SEMI_CHECK != 0) && (option.SEMI_POZICIA_FARBA_POCAS != 0) && (check_P1F(ofarbenie_lokal[level * POCET_VRCHOLOV_FARBA + POCET_VRCHOLOV_FARBA - 1], level, ofarbenie_lokal) == -1)) {
            for (i = POCET_VRCHOLOV_FARBA - 1; i > 0; --i) {
                su_ofarbene_lokal[ofarbenie_lokal[level * POCET_VRCHOLOV_FARBA + i]] = -1;
                ofarbenie_lokal[level * POCET_VRCHOLOV_FARBA + i] = -1;
            }
            return;
        }
        if ((option.SEMI_CHECK != 0) && (option.SEMI_POZICIA_FARBA_KONIEC != 0)) {
            if (check_P1F(ofarbenie_lokal[level * POCET_VRCHOLOV_FARBA + POCET_VRCHOLOV_FARBA - 1], level, ofarbenie_lokal) == -1) {
                for (i = POCET_VRCHOLOV_FARBA - 1; i > 0; --i) {
                    su_ofarbene_lokal[ofarbenie_lokal[level * POCET_VRCHOLOV_FARBA + i]] = -1;
                    ofarbenie_lokal[level * POCET_VRCHOLOV_FARBA + i] = -1;
                }
                return;
            }
        }
        if ((option.SEMI_CHECK != 0) && (option.SEMI_POZICIA_OFARBENIE_KONIEC != 0)) {
            if (check_P1F_koniec(ofarbenie_lokal[level * POCET_VRCHOLOV_FARBA + POCET_VRCHOLOV_FARBA - 1], level, ofarbenie_lokal) == -1) {
                for (i = POCET_VRCHOLOV_FARBA - 1; i > 0; --i) {
                    su_ofarbene_lokal[ofarbenie_lokal[level * POCET_VRCHOLOV_FARBA + i]] = -1;
                    ofarbenie_lokal[level * POCET_VRCHOLOV_FARBA + i] = -1;
                }
                return;
            }
        }

        faktorizacia[faktorizacia_pocet] = (item_faktorizacia *) malloc(sizeof (item_faktorizacia));
        for (j = 0; j < POCET_VRCHOLOV; j++) {
            faktorizacia[faktorizacia_pocet]->ofarbenie[j] = ofarbenie_lokal[j];
        }

        if (option.NAUTY_D_TABULKA == 1) {
            vyrataj_D_tabulku(faktorizacia_pocet);
            if (faktorizacia_pocet == 0) {
                zapis_iba_do_labu = 1;
                RunNautyKoniec(su_ofarbene_lokal, level);
                zapis_iba_do_labu = 0;
            }

            for (j = 0; j < faktorizacia_pocet; j++) {
                k = 0;
                i = 0;
                while (faktorizacia[faktorizacia_pocet]->D_tabulka[i] != 0) {
                    if (faktorizacia[j]->D_tabulka[i] != faktorizacia[faktorizacia_pocet]->D_tabulka[i]) {
                        k = 1;
                        break;
                    }
                    i++;
                }
                if (k == 0) {
                    if ((option.NAUTY == 1) && (option.NAUTY_POZICIA_OFARBENIE_KONIEC == 1)) {
                        if (RunNautyKoniec(su_ofarbene_lokal, level) == -1) {
                            faktorizacia[faktorizacia_pocet] = NULL;
                            for (i = POCET_VRCHOLOV_FARBA - 1; i > 0; --i) {
                                su_ofarbene_lokal[ofarbenie_lokal[level * POCET_VRCHOLOV_FARBA + i]] = -1;
                                ofarbenie_lokal[level * POCET_VRCHOLOV_FARBA + i] = -1;
                            }
                            return;
                        }
                    }
                    break;
                }
            }
            if (k == 1) {
                zapis_iba_do_labu = 1;
                RunNautyKoniec(su_ofarbene_lokal, level);
                zapis_iba_do_labu = 0;
            }
        } else {
            if ((option.NAUTY == 1) && (option.NAUTY_POZICIA_OFARBENIE_KONIEC == 1)) {
                if (RunNautyKoniec(su_ofarbene_lokal, level) == -1) {
                    faktorizacia[faktorizacia_pocet] = NULL;
                    for (i = POCET_VRCHOLOV_FARBA - 1; i > 0; --i) {
                        su_ofarbene_lokal[ofarbenie_lokal[level * POCET_VRCHOLOV_FARBA + i]] = -1;
                        ofarbenie_lokal[level * POCET_VRCHOLOV_FARBA + i] = -1;
                    }
                    return;
                }
            }
        }
       
        faktorizacia_pocet++;

        for (i = POCET_VRCHOLOV_FARBA - 1; i > 0; --i) {
            su_ofarbene_lokal[ofarbenie_lokal[level * POCET_VRCHOLOV_FARBA + i]] = -1;
            ofarbenie_lokal[level * POCET_VRCHOLOV_FARBA + i] = -1;
        }
    } else { //  FARBA KOMPLETNA, VYBERA POSLEDNY VRCHOL
        if (cesta[2 * (POCET_VRCHOLOV_FARBA - 1) - 1] != -1) { //farba je kompletna az na posl. vrchol
            last = 2 * (POCET_VRCHOLOV_FARBA - 1) - 1;
            for (i = POCET_SUSEDOV; i != 0;) {
                --i;
                susedia_new[i][0] = default_susedia[cesta[last]][i];
                if ((su_ofarbene_lokal[susedia_new[i][0]] != -1) || (su_ofarbene_lokal[default_susedia[susedia_new[i][0]][i]] == level) || (cesta[1] == default_susedia[susedia_new[i][0]][i])) {
                } else {
                    for (k = POCET_SUSEDOV; k != 0; --k) {
                        susedia_new[i][k] = default_susedia[susedia_new[i][0]][k - 1];
                        if (susedia_new[i][k] == cesta[last]) { //ak bol sused kandidata v ceste, tiez by nemal byt vhodny ako dalsi skok
                            goto end16;
                        }
                        if ((su_ofarbene_lokal[susedia_new[i][k]] == level) || (cesta[1] == susedia_new[i][k])) { //ak niektori kandidatov sused bol v ceste, zrus kandidata
                            goto end2; // lasta zrus len ako moznost dalsieho skoku, cize susedia2
                        }
                        for (j = (last - 1) / 2; j > 0; --j) {
                            if (cesta[(j * 2) + 1] == susedia_new[i][k]) { //ak niektori kandidatov sused bol v ceste, zrus kandidata
                                goto end2; // lasta zrus len ako moznost dalsieho skoku, cize susedia2
                            }
                        }
end16:
                        ;
                    }
                    cesta[last + 1] = susedia_new[i][0];
                    for (j = 0; j < POCET_VRCHOLOV_FARBA; ++j) {
                        farba[j] = cesta[2 * j];
                        for (k = 0; k < j; k++) {
                            if (farba[k] > farba[j]) {
                                tmp_farba = farba[j];
                                farba[j] = farba[k];
                                farba[k] = tmp_farba;
                            }
                        }
                    }
                    for (n = 0; n < pocet_farieb_level_lokal[level]; ++n) {
                        ok = 0;
                        for (j = POCET_VRCHOLOV_FARBA; j != 0;) { //uz taka farba bola
                            --j;
                            if (farby_level_lokal[level][n][j] == farba[j]) {
                                ok++;
                            }
                            if (ok == POCET_VRCHOLOV_FARBA) { ////uz taka farba bola, cela vetva najdi_farbu konci -> goto end?
                                return;
                            }
                        }
                    }
                    if ((level != 0) && (option.SEMI_CHECK != 0) && (option.SEMI_POZICIA_FARBA_KONIEC != 0) && (check_P1F(susedia_new[i][0], level, ofarbenie_lokal) == -1)) {
                        susedia_new[i][0] = -1;
                        return;
                    }

                    su_ofarbene_lokal[susedia_new[i][0]] = level;
                    ofarbenie_lokal[level * POCET_VRCHOLOV_FARBA + POCET_VRCHOLOV_FARBA - 1] = susedia_new[i][0];

                    if ((option.NAUTY != 0) && (option.NAUTY_POZICIA_FARBA_KONIEC != 0) && (RunNautyPocas(level, su_ofarbene_lokal, ofarbenie_lokal, g, cg, cgi) == -1)) {
                        ofarbenie_lokal[level * POCET_VRCHOLOV_FARBA + POCET_VRCHOLOV_FARBA - 1] = -1;
                        su_ofarbene_lokal[susedia_new[i][0]] = -1;
                        return;
                    }

                    for (j = POCET_VRCHOLOV_FARBA; j != 0;) {
                        --j;
                        farby_level[level][pocet_farieb_level_lokal[level]][j] = farba[j];
                    }

                    pocet_farieb_level_lokal[level]++;
                    level_back = level;
                    vrchol_back = susedia_new[i][0];
                    level++;
                    pocet_farieb_level_lokal[level] = 0; // ide o level nizsie, a moze vybrat setky moznosti
                    cesta[0] = default_ofarbenie[level * POCET_VRCHOLOV_FARBA + 0];

                    for (j = 2; j < 2 * POCET_VRCHOLOV_FARBA; ++j) { //do cesty prida default farbu o level nizsie
                        cesta[j] = -1;
                    }

                    if (level != POCET_FARIEB - 1) {
                        for (j = 0; j < 1; j++) { /////////////////////////////////////////////////////////POCET_SUSEDOV
                            cesta[1] = default_susedia[cesta[0]][j];
                            najdi_faktorizaciu(cesta, su_ofarbene_lokal, ofarbenie_lokal, farby_level_lokal, pocet_farieb_level_lokal);
                        }
                    } else {
                        cesta[1] = default_susedia[cesta[0]][0];
                        najdi_faktorizaciu(cesta, su_ofarbene_lokal, ofarbenie_lokal, farby_level_lokal, pocet_farieb_level_lokal);
                    }
                    ofarbenie_lokal[level_back * POCET_VRCHOLOV_FARBA + POCET_VRCHOLOV_FARBA - 1] = -1;
                    su_ofarbene_lokal[vrchol_back] = -1;
                    return;
                }
end2:
                ;
            }
        } else { //  HLADAM CELU FARBU
            for (i = 1; i < POCET_VRCHOLOV_FARBA - 1; i++) {
                if (cesta[2 * i] == -1) {
                    last = 2 * i - 1;
                    break;
                }
            }
            for (i = POCET_SUSEDOV; i != 0;) {
                --i;
                susedia_new[i][0] = default_susedia[cesta[last]][i];
                if ((su_ofarbene_lokal[susedia_new[i][0]] != -1) || (su_ofarbene_lokal[default_susedia[susedia_new[i][0]][i]] == level)) {
                    susedia_new[i][0] = -1;
                } else {
                    for (k = POCET_SUSEDOV; k != 0; --k) {
                        susedia_new[i][k] = default_susedia[susedia_new[i][0]][k - 1];
                        if (susedia_new[i][k] == cesta[last]) { //ak bol sused kandidata v ceste, tiez by nemal byt vhodny ako dalsi skok
                            susedia_new[i][k] = -1;
                            goto end15;
                        }
                        if ((su_ofarbene_lokal[susedia_new[i][k]] == level) || (cesta[1] == susedia_new[i][k])) { //ak niektori kandidatov sused bol v ceste, zrus kandidata
                            susedia_new[i][0] = -1;
                            goto end10;
                        }
                        for (j = (last - 1) / 2; j > 0; --j) {
                            if (cesta[(j * 2) + 1] == susedia_new[i][k]) { //ak niektori kandidatov sused bol v ceste, zrus kandidata
                                susedia_new[i][0] = -1;
                                goto end10;
                            }
                        }
end15:
                        ;
                    }
                    if ((level != 0) && (option.SEMI_CHECK != 0) && (option.SEMI_POZICIA_FARBA_POCAS != 0) && (check_P1F(susedia_new[i][0], level, ofarbenie_lokal) == -1)) {
                        susedia_new[i][0] = -1;
                        goto end10;
                    }
                    for (k = POCET_SUSEDOV; k != 0; --k) {
                        if (susedia_new[i][k] != -1) {
                            for (l = 0; l < POCET_SUSEDOV; ++l) {
                                if ((su_ofarbene_lokal[default_susedia[susedia_new[i][k]][l]] == level) || (default_susedia[susedia_new[i][k]][l] == cesta[1])) {
                                    susedia_new[i][k] = -1;
                                    goto end17;
                                }
                                for (j = (last - 1) / 2; j > 0; --j) {
                                    if (default_susedia[susedia_new[i][k]][l] == cesta[(j * 2) - 1]) {
                                        susedia_new[i][k] = -1;
                                        goto end17;
                                    }
                                }
                            }
                            for (j = 2 * POCET_VRCHOLOV_FARBA - 1; j != 0;) {
                                --j;
                                lokal_cesta[j] = cesta[j];
                            }
                            last_back = last;
                            ofarbenie_lokal[level * POCET_VRCHOLOV_FARBA + (last + 1) / 2] = susedia_new[i][0]; //upravim su_ofarbene a ofarbenie a po volani nadji_farbu vymazem
                            su_ofarbene_lokal[susedia_new[i][0]] = level;
                            cesta[last + 1] = susedia_new[i][0];
                            cesta[last + 2] = susedia_new[i][k];
                            najdi_faktorizaciu(cesta, su_ofarbene_lokal, ofarbenie_lokal, farby_level_lokal, pocet_farieb_level_lokal);
                            for (j = 2 * POCET_VRCHOLOV_FARBA - 1; j != 0;) {
                                --j;
                                cesta[j] = lokal_cesta[j];
                            }
                            last = last_back;
                            su_ofarbene_lokal[ofarbenie_lokal[level * POCET_VRCHOLOV_FARBA + (last + 1) / 2]] = -1;
                            ofarbenie_lokal[level * POCET_VRCHOLOV_FARBA + (last + 1) / 2] = -1; //upravim su_ofarbene a ofarbenie a po volani nadji_farbu vymazem
                        }
end17:
                        ;
                    }
                }
end10:
                ;
            }
        }
    }
}

int FACTOR_STAR_DFS::check_P1F(int vrchol, unsigned int level_lokal, int ofarbenie_lokal[POCET_VRCHOLOV]) {

    int i;

    if (option.SEMI_CHECK == 1) {
        for (i = 0; i < level_lokal; ++i) {
            vrchol = check_level_P1F(vrchol, i, level_lokal, ofarbenie_lokal);
            if (vrchol == -1) {
                return vrchol;
            }
            return vrchol;
        }
    } else if (option.SEMI_CHECK == 2) {
        for (i = 0; i < level_lokal; ++i) {
            vrchol = check_level_P1F(vrchol, i, level_lokal, ofarbenie_lokal);
            if (vrchol == -1) {
                return vrchol;
            }

        }
        return vrchol;
    } else {
        return vrchol;
    }
}

int FACTOR_STAR_DFS::check_P1F_koniec(int vrchol, unsigned int level_lokal, int ofarbenie_lokal[POCET_VRCHOLOV]) {

    int i, j;

    if (option.SEMI_CHECK == 1) {
        for (i = 0; i < level_lokal; ++i) {
            vrchol = check_level_P1F(vrchol, i, level_lokal, ofarbenie_lokal);
            if (vrchol == -1) {
                return vrchol;
            }
        }
        return vrchol;
    } else if (option.SEMI_CHECK == 2) {
        for (i = 0; i < level_lokal; ++i) {
            for (j = i + 1; j <= level_lokal; j++) {
                vrchol = check_level_P1F(ofarbenie_lokal[j * POCET_VRCHOLOV_FARBA + POCET_VRCHOLOV_FARBA - 1], i, j, ofarbenie_lokal);
                if (vrchol == -1) {
                    return vrchol;
                }
            }
        }
        return vrchol;
    } else {
        return vrchol;
    }
}

int FACTOR_STAR_DFS::check_level_P1F(unsigned int vrchol, unsigned int level_lokal_first, unsigned int level_lokal_akt, int ofarbenie_lokal[POCET_VRCHOLOV]) {

    int prva_farba[POCET_VRCHOLOV_FARBA], aktual_farba[POCET_VRCHOLOV_FARBA];
    int A, S, dlzka_cyklu;
    unsigned int i, j, k;

    for (i = POCET_VRCHOLOV_FARBA; i != 0;) {
        --i;
        prva_farba[i] = ofarbenie_lokal[level_lokal_first * POCET_VRCHOLOV_FARBA + i];
        aktual_farba[i] = ofarbenie_lokal[level_lokal_akt * POCET_VRCHOLOV_FARBA + i];
    }

    aktual_farba[POCET_VRCHOLOV_FARBA - 1] = vrchol;
    A = vrchol;
    dlzka_cyklu = 2;
    for (i = POCET_SUSEDOV; i != 0;) {
        --i;
        for (j = POCET_VRCHOLOV_FARBA; j != 0;) {
            --j;
            if (default_susedia[A][i] == prva_farba[j]) {
                S = default_susedia[A][i];
                prva_farba[j] = -1;
                goto end11;
            }
        }
    }
end11:
    ;

    for (i = POCET_SUSEDOV; i != 0;) {
        --i;
        for (j = POCET_VRCHOLOV_FARBA; j != 0;) {
            --j;
            if ((default_susedia[S][i] == aktual_farba[j]) && (default_susedia[S][i] != A)) {
                A = default_susedia[S][i];
                goto end12;
            }
        }
    }
    if (A == vrchol) {
        return vrchol;
    }

end12:
    ;

    do {
        for (i = 0; i < POCET_SUSEDOV; i++) {
            for (j = 0; j < POCET_VRCHOLOV_FARBA; j++) {
                if (default_susedia[A][i] == prva_farba[j]) {
                    S = default_susedia[A][i];
                    prva_farba[j] = -1;
                    goto end13;
                }
            }
        }
end13:
        ;

        for (i = 0; i < POCET_SUSEDOV; i++) {
            for (j = 0; j < POCET_VRCHOLOV_FARBA; j++) {
                if (default_susedia[S][i] == aktual_farba[j]) {
                    A = default_susedia[S][i];
                    aktual_farba[j] = -1;
                    goto end14;
                }
            }
        }
        dlzka_cyklu = POCET_PERM_VRCHOLOV;
        break;
end14:
        ;

        dlzka_cyklu++;
        dlzka_cyklu++;

    } while (A != vrchol);

    if (dlzka_cyklu < POCET_PERM_VRCHOLOV) {
        return -1;
    } else {
        return vrchol;
    }
}

int FACTOR_STAR_DFS::RunNautyPocas(int level_nauty, int su_ofarbene_lokal[POCET_VRCHOLOV], int ofarbenie_lokal[POCET_VRCHOLOV], graph g_lokal[MAXN*MAXN], graph cg_lokal[MAXN*MAXN], graph cgi_lokal[MAXN*MAXN]) {
    int i, j, k, l, o, pom;
    nvector ptn_lokal[POCET_VRCHOLOV];
    nvector ptn_tmp[POCET_VRCHOLOV];
    nvector lab_lokal[POCET_VRCHOLOV];
    unsigned int lab_tmp[POCET_VRCHOLOV];
    permutation lab_lokal_upd[POCET_VRCHOLOV];

    unsigned int perm_nauty[POCET_FARIEB][POCET_VRCHOLOV_FARBA];

    if (option.NAUTY == 1) {

        for (i = POCET_VRCHOLOV; i != 0;) {
            --i;
            ptn_lokal[i] = 1;
            ptn_tmp[i] = 1;
        }
        for (i = level_nauty + 1; i < POCET_FARIEB; i++) {
            su_ofarbene_lokal[i] = -1;
        }
        i = 0;
        for (j = POCET_VRCHOLOV; j != 0;) {
            --j;
            if (su_ofarbene_lokal[j] == -1) {
                lab_lokal[level_nauty * POCET_VRCHOLOV_FARBA + POCET_VRCHOLOV_FARBA + i] = j;
                i++;
            }
        }
        for (i = level_nauty + 1; i < POCET_FARIEB; i++) {
            su_ofarbene_lokal[i] = i;
        }
        for (i = level_nauty + 1; i != 0;) {
            --i;
            ptn_lokal[i * POCET_VRCHOLOV_FARBA + POCET_VRCHOLOV_FARBA - 1] = 0;
            for (j = POCET_VRCHOLOV_FARBA; j != 0;) {
                --j;
                lab_lokal[i * POCET_VRCHOLOV_FARBA + j] = ofarbenie_lokal[POCET_VRCHOLOV_FARBA * i + j];
            }
        }
        k = 0;
        l = 0;
        for (j = 0; j < POCET_VRCHOLOV; j++) {
            perm_nauty[l][k] = lab_lokal[j];
            lab_tmp[j] = lab_lokal[j];
            k++;
            if (k == POCET_VRCHOLOV_FARBA) {
                l++;
                k = 0;
            }
        }
        nauty(g_lokal, lab_lokal, ptn_lokal, NILSET, orbits, &options, &stats, workspace, 50 * MAXM, M, POCET_VRCHOLOV, cg_lokal);

        pom = lab_farby_level_pocet[level_nauty];

        for (i = 0; i < pom; i++) {
            for (j = 0; j < POCET_VRCHOLOV; j++) {
                lab_lokal_upd[j] = lab_farby_level[level_nauty][i][j];
            }
            updatecan(g_lokal, cgi_lokal, lab_lokal_upd, 0, M, POCET_VRCHOLOV);
            for (j = POCET_VRCHOLOV * POCET_SUSEDOV; j >= 0; j--) {
                if (cgi_lokal[j] != cg_lokal[j]) {
                    break;
                }
            }
            if (j < 0) {
                return -1;
            }
        }
        if (level_nauty != POCET_FARIEB - 1) {
            if (level_nauty != 0) {
                switch (level_nauty + 1) {
                    case 1:
                        for (j = 0; j < perm_pole_2_fak; j++) {
                            if (j != 0) {
                                o = 0;
                                for (k = 0; k <= level_nauty + 1; k++) {
                                    for (l = 0; l < POCET_VRCHOLOV_FARBA; l++) {
                                        lab_lokal[o] = perm_nauty[perm_pole_2[j][k] - 1][l];
                                        o++;
                                    }
                                }
                                if (o != POCET_VRCHOLOV) {
                                    for (; o < POCET_VRCHOLOV; o++) {
                                        lab_lokal[o] = lab_tmp[o];
                                    }
                                }
                            }
                            nauty(g_lokal, lab_lokal, ptn_lokal, NILSET, orbits, &options, &stats, workspace, 50 * MAXM, M, POCET_VRCHOLOV, cg_lokal);
                            for (i = 0; i < POCET_VRCHOLOV; i++) {
                                lab_farby_level[level_nauty][lab_farby_level_pocet[level_nauty]][i] = lab_lokal[i];
                            }
                            lab_farby_level_pocet[level_nauty]++;
                        }
                        break;
                    case 2:
                        for (j = 0; j < perm_pole_3_fak; j++) {
                            if (j != 0) {
                                o = 0;
                                for (k = 0; k <= level_nauty + 1; k++) {
                                    for (l = 0; l < POCET_VRCHOLOV_FARBA; l++) {
                                        lab_lokal[o] = perm_nauty[perm_pole_3[j][k] - 1][l];
                                        o++;
                                    }
                                }
                                if (o != POCET_VRCHOLOV) {
                                    for (; o < POCET_VRCHOLOV; o++) {
                                        lab_lokal[o] = lab_tmp[o];
                                    }
                                }
                            }
                            nauty(g_lokal, lab_lokal, ptn_lokal, NILSET, orbits, &options, &stats, workspace, 50 * MAXM, M, POCET_VRCHOLOV, cg_lokal);
                            for (i = 0; i < POCET_VRCHOLOV; i++) {
                                lab_farby_level[level_nauty][lab_farby_level_pocet[level_nauty]][i] = lab_lokal[i];
                            }
                            lab_farby_level_pocet[level_nauty]++;
                        }
                        break;
                    case 3:
                        for (j = 0; j < perm_pole_4_fak; j++) {
                            if (j != 0) {
                                o = 0;
                                for (k = 0; k <= level_nauty + 1; k++) {
                                    for (l = 0; l < POCET_VRCHOLOV_FARBA; l++) {
                                        lab_lokal[o] = perm_nauty[perm_pole_4[j][k] - 1][l];
                                        o++;
                                    }
                                }
                                if (o != POCET_VRCHOLOV) {
                                    for (; o < POCET_VRCHOLOV; o++) {
                                        lab_lokal[o] = lab_tmp[o];
                                    }
                                }
                            }
                            nauty(g_lokal, lab_lokal, ptn_lokal, NILSET, orbits, &options, &stats, workspace, 50 * MAXM, M, POCET_VRCHOLOV, cg_lokal);
                            for (i = 0; i < POCET_VRCHOLOV; i++) {
                                lab_farby_level[level_nauty][lab_farby_level_pocet[level_nauty]][i] = lab_lokal[i];
                            }
                            lab_farby_level_pocet[level_nauty]++;
                        }
                        break;
                    
                    default:
                        break;
                }
            } else {
                for (i = 0; i < POCET_VRCHOLOV; i++) {
                    lab_farby_level[level_nauty][lab_farby_level_pocet[level_nauty]][i] = lab_lokal[i];
                }
                lab_farby_level_pocet[level_nauty]++;
            }
        } else {
            switch (level_nauty + 1) {
                case 2:
                    for (j = 0; j < perm_pole_2_fak; j++) {
                        if (j != 0) {
                            o = 0;
                            for (k = 0; k <= level_nauty; k++) {
                                for (l = 0; l < POCET_VRCHOLOV_FARBA; l++) {
                                    lab_lokal[o] = perm_nauty[perm_pole_2[j][k] - 1][l];
                                    o++;
                                }
                            }
                            if (o != POCET_VRCHOLOV) {
                                for (; o < POCET_VRCHOLOV; o++) {
                                    lab_lokal[o] = lab_tmp[o];
                                }
                            }
                        }
                        nauty(g_lokal, lab_lokal, ptn_lokal, NILSET, orbits, &options, &stats, workspace, 50 * MAXM, M, POCET_VRCHOLOV, cg_lokal);
                        for (i = 0; i < POCET_VRCHOLOV; i++) {
                            lab_farby_level[level_nauty][lab_farby_level_pocet[level_nauty]][i] = lab_lokal[i];
                        }
                        lab_farby_level_pocet[level_nauty]++;
                    }
                    break;
                case 3:
                    for (j = 0; j < perm_pole_3_fak; j++) {
                        if (j != 0) {
                            o = 0;
                            for (k = 0; k <= level_nauty; k++) {
                                for (l = 0; l < POCET_VRCHOLOV_FARBA; l++) {
                                    lab_lokal[o] = perm_nauty[perm_pole_3[j][k] - 1][l];
                                    o++;
                                }
                            }
                            if (o != POCET_VRCHOLOV) {
                                for (; o < POCET_VRCHOLOV; o++) {
                                    lab_lokal[o] = lab_tmp[o];
                                }
                            }
                        }
                        nauty(g_lokal, lab_lokal, ptn_lokal, NILSET, orbits, &options, &stats, workspace, 50 * MAXM, M, POCET_VRCHOLOV, cg_lokal);
                        for (i = 0; i < POCET_VRCHOLOV; i++) {
                            lab_farby_level[level_nauty][lab_farby_level_pocet[level_nauty]][i] = lab_lokal[i];
                        }
                        lab_farby_level_pocet[level_nauty]++;
                    }
                    break;
                case 4:
                    for (j = 0; j < perm_pole_4_fak; j++) {
                        if (j != 0) {
                            o = 0;
                            for (k = 0; k <= level_nauty; k++) {
                                for (l = 0; l < POCET_VRCHOLOV_FARBA; l++) {
                                    lab_lokal[o] = perm_nauty[perm_pole_4[j][k] - 1][l];
                                    o++;
                                }
                            }
                            if (o != POCET_VRCHOLOV) {
                                for (; o < POCET_VRCHOLOV; o++) {
                                    lab_lokal[o] = lab_tmp[o];
                                }
                            }
                        }
                        nauty(g_lokal, lab_lokal, ptn_lokal, NILSET, orbits, &options, &stats, workspace, 50 * MAXM, M, POCET_VRCHOLOV, cg_lokal);
                        for (i = 0; i < POCET_VRCHOLOV; i++) {
                            lab_farby_level[level_nauty][lab_farby_level_pocet[level_nauty]][i] = lab_lokal[i];
                        }
                        lab_farby_level_pocet[level_nauty]++;
                    }
                    break;
                default:
                    break;
            }
        }

        for (i = 0; i < POCET_VRCHOLOV; i++) {
            ofarbenie_global[level_nauty][ofarbenie_global_pocet[level_nauty]][i] = ofarbenie_lokal[i];
        }
        ofarbenie_global_pocet[level_nauty]++;
        return 1;
    } else {
        for (i = 0; i < POCET_VRCHOLOV; i++) {
            ofarbenie_global[level_nauty][ofarbenie_global_pocet[level_nauty]][i] = ofarbenie_lokal[i];
        }
        ofarbenie_global_pocet[level_nauty]++;
        return 1;
    }
}

int FACTOR_STAR_DFS::RunNautyKoniec(int su_ofarbene_lokal[POCET_VRCHOLOV], int level) {
    int i, j, k, l, o, pom;
    nvector ptn_lokal[POCET_VRCHOLOV];
    nvector lab_lokal[POCET_VRCHOLOV];
    permutation lab_lokal_upd[POCET_VRCHOLOV];


    unsigned int perm_nauty[POCET_FARIEB][POCET_VRCHOLOV_FARBA];

    unsigned int ofarbenie_lokal[POCET_VRCHOLOV];

    for (i = 0; i < POCET_VRCHOLOV; i++) {
        ofarbenie_lokal[i] = 0;
    }

    l = 0;
    for (i = 0; i < POCET_FARIEB; i++) {
        for (j = 0; j < POCET_VRCHOLOV; j++) {
            if (su_ofarbene_lokal[j] == i) {
                ofarbenie_lokal[l] = j;
                l++;
            }
        }
        if (i == 1) {
        }
    }

    for (i = 0; i < POCET_VRCHOLOV; i++) {
        if (su_ofarbene_lokal[i] == 0) {
            ofarbenie_lokal[l] = i;
            l++;
        }
    }

    k = 0;
    l = 0;
    for (i = 0; i < POCET_VRCHOLOV; i++) {

        ptn_lokal[i] = 1;
        lab_lokal[i] = ofarbenie_lokal[i];
        perm_nauty[l][k] = lab_lokal[i];
        k++;
        if (k == POCET_VRCHOLOV_FARBA) {
            l++;
            k = 0;
        }
    }

    for (i = 1; i <= POCET_FARIEB; i++) {
        ptn_lokal[(POCET_VRCHOLOV_FARBA * i) - 1] = 0;
    }
    nauty(g, lab_lokal, ptn_lokal, NILSET, orbits, &options, &stats, workspace, 50 * MAXM, M, POCET_VRCHOLOV, cg);

    pom = lab_farby_level_pocet[level];

    if (zapis_iba_do_labu == 1) {
        pom = 0;
    }

    for (i = 0; i < pom; i++) {
        for (j = 0; j < POCET_VRCHOLOV; j++) {
            lab_lokal_upd[j] = lab_farby_level[level][i][j];
        }
        updatecan(g, cgi, lab_lokal_upd, 0, M, POCET_VRCHOLOV);
        for (j = POCET_VRCHOLOV * POCET_SUSEDOV; j >= 0; j--) {
            if (cgi[j] != cg[j]) {
                break;
            }
        }
        if (j < 0) {
            return -1;
        }
    }
    switch (POCET_FARIEB) {
        case 3:
            for (j = 0; j < perm_pole_3_fak; j++) {
                if (j != 0) {
                    o = 0;
                    for (k = 0; k < POCET_FARIEB; k++) {
                        for (l = 0; l < POCET_VRCHOLOV_FARBA; l++) {
                            lab_lokal[o] = perm_nauty[perm_pole_3[j][k] - 1][l];
                            o++;
                        }
                    }
                    nauty(g, lab_lokal, ptn_lokal, NILSET, orbits, &options, &stats, workspace, 50 * MAXM, M, POCET_VRCHOLOV, cg);
                }
                for (i = 0; i < POCET_VRCHOLOV; i++) {
                    lab_farby_level[level][lab_farby_level_pocet[level]][i] = lab_lokal[i];
                }
                lab_farby_level_pocet[level]++;
            }
            break;
        case 4:
            for (j = 0; j < perm_pole_4_fak; j++) {
                if (j != 0) {
                    o = 0;
                    for (k = 0; k < POCET_FARIEB; k++) {
                        for (l = 0; l < POCET_VRCHOLOV_FARBA; l++) {
                            lab_lokal[o] = perm_nauty[perm_pole_4[j][k] - 1][l];
                            o++;
                        }
                    }
                    nauty(g, lab_lokal, ptn_lokal, NILSET, orbits, &options, &stats, workspace, 50 * MAXM, M, POCET_VRCHOLOV, cg);
                }
                for (i = 0; i < POCET_VRCHOLOV; i++) {
                    lab_farby_level[level][lab_farby_level_pocet[level]][i] = lab_lokal[i];
                }
                lab_farby_level_pocet[level]++;
            }
            break;
    }
    return 1;
}

extern int compare(const void * a, const void * b);

void FACTOR_STAR_DFS::vyrataj_D_tabulku(int akt_faktorizacia) {
    unsigned int i, j, k, index, prva_farba[POCET_VRCHOLOV_FARBA], akt_farba[POCET_VRCHOLOV_FARBA], dlzka_cyklu, dlzka_all_cyklov, pocet_cyklov;
    unsigned int A, S, l;
    int uplna_D_tabulka[VELKOST_D * POCET_VRCHOLOV / 4];

    for (i = 0; i < VELKOST_D * POCET_VRCHOLOV / 4; i++) {
        uplna_D_tabulka[i] = 0;
    }

    index = 0;
    for (i = 0; i < POCET_FARIEB; i++) {
        for (j = i + 1; j < POCET_FARIEB; j++) {
            index++;
            for (k = 0; k < POCET_VRCHOLOV_FARBA; k++) {
                akt_farba[k] = faktorizacia[akt_faktorizacia]->ofarbenie[j * POCET_VRCHOLOV_FARBA + k];
                prva_farba[k] = faktorizacia[akt_faktorizacia]->ofarbenie[i * POCET_VRCHOLOV_FARBA + k];
            }
            pocet_cyklov = 0;
            dlzka_all_cyklov = 0;

            do {
                dlzka_cyklu = 0;
                for (k = 0; k < POCET_VRCHOLOV_FARBA; k++) {
                    if (akt_farba[k] != -1) {
                        A = akt_farba[k];
                        akt_farba[k] = -1;
                        dlzka_cyklu = 1;
                        break;
                    }
                }
                do {
                    for (k = 0; k < POCET_SUSEDOV; k++) {
                        for (l = 0; l < POCET_VRCHOLOV_FARBA; l++) {
                            if (prva_farba[l] == default_susedia[A][k]) {
                                S = default_susedia[A][k];
                                prva_farba[l] = -1;
                                dlzka_cyklu++;
                                goto endk;
                            }
                        }
                    }
endk:
                    ;
                    A = -1;
                    for (k = 0; k < POCET_SUSEDOV; k++) {
                        for (l = 0; l < POCET_VRCHOLOV_FARBA; l++) {
                            if (akt_farba[l] == default_susedia[S][k]) {
                                A = default_susedia[S][k];
                                akt_farba[l] = -1;
                                dlzka_cyklu++;
                                goto endk1;
                            }
                        }
                    }
endk1:
                    ;

                } while (A != -1);
                uplna_D_tabulka[((index - 1) * POCET_VRCHOLOV / 4) + pocet_cyklov] = dlzka_cyklu;
                dlzka_all_cyklov += dlzka_cyklu;
                pocet_cyklov++;
            } while (dlzka_all_cyklov < POCET_PERM_VRCHOLOV);
        }
    }
    qsort(uplna_D_tabulka, VELKOST_D * POCET_VRCHOLOV / 4, sizeof (int), compare);
    for (i = 0; i < VELKOST_D * POCET_VRCHOLOV / 4; i++) {
        faktorizacia[akt_faktorizacia]->D_tabulka[i] = uplna_D_tabulka[i];
    }

}

void FACTOR_STAR_DFS::NaplnDefault() {
    int i, j, k, l, tmp, hrana, sused, zhoda;
    int N = DIMENSION;
    int Value[DIMENSION];
    int perm_sused[DIMENSION];

    options.writemarkers = FALSE;
    options.getcanon = TRUE;
    options.defaultptn = FALSE;
    options.writeautoms = FALSE;
    options.linelength = 120;
    options.cartesian = FALSE;

    m = M = (POCET_VRCHOLOV + WORDSIZE - 1) / WORDSIZE;

    switch (N) {
        case 6:
            for (i = 0; i < N; i++) {
                Value[i] = 0;
            }
            perm_pole_tmp = 0;
            visit(Value, N, 0);
            N--;
        case 5:
            for (i = 0; i < N; i++) {
                Value[i] = 0;
            }
            perm_pole_tmp = 0;
            visit(Value, N, 0);
            N--;
        case 4:
            for (i = 0; i < N; i++) {
                Value[i] = 0;
            }
            perm_pole_tmp = 0;
            visit(Value, N, 0);
            N--;
        case 3:
            for (i = 0; i < N; i++) {
                Value[i] = 0;
            }
            perm_pole_tmp = 0;
            visit(Value, N, 0);
            N--;
        case 2:
            for (i = 0; i < N; i++) {
                Value[i] = 0;
            }
            perm_pole_tmp = 0;
            visit(Value, N, 0);
    }

    for (i = 0; i < POCET_PERM_VRCHOLOV; i++) {
        for (j = 0; j < DIMENSION; j++) {
            perm_vrcholy[i][j] = perm_pole_4[i][j];
        }
    }

    hrana = 0;
    for (i = 0; i < POCET_PERM_VRCHOLOV; i++) {
        for (j = 0; j < DIMENSION; j++) {
            perm_sused[j] = perm_vrcholy[i][j];
        }
        for (j = 1; j < DIMENSION; j++) { //vymeni 0ty a j-ty prvok v permutacii
            tmp = perm_sused[j];
            perm_sused[j] = perm_sused[0];
            perm_sused[0] = tmp;

            for (k = 0; k < POCET_PERM_VRCHOLOV; k++) {
                zhoda = 0;
                for (l = 0; l < DIMENSION; l++) {
                    if (perm_vrcholy[k][l] == perm_sused[l]) {
                        zhoda++;
                    }
                }
                if (zhoda == DIMENSION) { //k je index perm_suseda v perm_vrcholy
                    goto end31;
                }
            }
end31:
            ;
            perm_susedia[i][j - 1] = k;
            if ((vyskyt_perm_vrcholov[k] < DIMENSION - 1) && (vyskyt_perm_vrcholov[i] < DIMENSION - 1)) { //ak este moze, spravi novu hranu pre i,k
                vyskyt_perm_vrcholov[k]++;
                vyskyt_perm_vrcholov[i]++;
                for (l = 0; l < DIMENSION; l++) {
                    perm_hrany[hrana][l] = perm_vrcholy[i][l];
                    perm_hrany[hrana][l + DIMENSION] = perm_sused[l];
                    hrany[hrana][0] = i;
                    hrany[hrana][1] = k;

                }
                hrana++;
            }
            tmp = perm_sused[0]; //vrati perm_suseda do povodnej formy
            perm_sused[0] = perm_sused[j];
            perm_sused[j] = tmp;
        }

    }
    /*
        for (i=0;i<POCET_PERM_VRCHOLOV;i++) {
            for (j=0;j<DIMENSION-2;j++) {
                for (k=j+1;k<DIMENSION-2;k++) {
                    if (perm_susedia[i][j]>perm_susedia[i][k]) {
                        tmp=perm_susedia[i][j];
                        perm_susedia[i][j]=perm_susedia[i][k];
                        perm_susedia[i][k]=tmp;
                    }
                }
            }
        }
     */
    for (i = 0; i < POCET_VRCHOLOV; i++) { //naplnenenie default_susedia
        zhoda = 0;
        for (k = 0; k < DIMENSION - 1; k++) {
            if ((perm_susedia[hrany[i][0]][k] != hrany[i][1])) {
                for (l = 0; l < POCET_VRCHOLOV; l++) {
                    if (((hrany[l][0] == perm_susedia[hrany[i][0]][k]) && (hrany[l][1] == hrany[i][0])) || ((hrany[l][1] == perm_susedia[hrany[i][0]][k]) && (hrany[l][0] == hrany[i][0]))) {
                        default_susedia[i][zhoda] = l;
                        zhoda++;
                        break;
                    }
                }
            }

        }
        for (k = 0; k < DIMENSION - 1; k++) {
            if ((perm_susedia[hrany[i][1]][k] != hrany[i][0])) {
                for (l = 0; l < POCET_VRCHOLOV; l++) {
                    if (((hrany[l][0] == perm_susedia[hrany[i][1]][k]) && (hrany[l][1] == hrany[i][1])) || ((hrany[l][1] == perm_susedia[hrany[i][1]][k]) && (hrany[l][0] == hrany[i][1]))) {
                        default_susedia[i][zhoda] = l;
                        zhoda++;
                        break;
                    }
                }
            }
        }
    }

    for (i = 0; i < POCET_VRCHOLOV; i++) {
        for (j = 0; j < POCET_SUSEDOV; j++) {
            for (k = j; k < POCET_SUSEDOV; k++) {
                if (default_susedia[i][j] < default_susedia[i][k]) {
                    tmp = default_susedia[i][j];
                    default_susedia[i][j] = default_susedia[i][k];
                    default_susedia[i][k] = tmp;
                }
            }

        }
    }
    /*      ////////////////////////////////////////////////////////////vypisy start
        for (k=0;k<POCET_PERM_VRCHOLOV;k++) {
                    printf(" %d :",k);
                    for (l=0;l<DIMENSION;l++) {
                        printf("%d",perm_vrcholy[k][l]);
                    }
                    printf("\n");
                }


        for (i=0;i<POCET_PERM_VRCHOLOV;i++) {
            printf("%d :",i);
            for (j=0;j<DIMENSION-1;j++) {
                printf(" %d ", perm_susedia[i][j]);
            }
            printf("\n");
        }

        for (i=0;i<POCET_VRCHOLOV;i++) {
            printf("hrana %d :",i);
            for (j=0;j<DIMENSION;j++) {
                printf("%d",perm_hrany[i][j]);
            }
            printf(" ");
            for (j=0;j<DIMENSION;j++) {
                printf("%d",perm_hrany[i][DIMENSION+j]);
            }
            printf("\n");
        }

        for (i=0;i<POCET_VRCHOLOV;i++) {
            printf("\n hrana %d vrcholy: ",i);
            printf("%d , %d ", hrany[i][0], hrany[i][1]);
        }

        for (i=0; i<POCET_VRCHOLOV; i++) {
            printf("\n hrana %d susedia: ",i);
            for (j=0; j<POCET_SUSEDOV;j++) {
                printf("%d ",default_susedia[i][j]);
            }
        }
     */ ////////////////////////////////////////////////////////////vypisy end

    for (i = 0; i < POCET_VRCHOLOV; i++) {
        default_ofarbenie[i] = -1;
        ofarbenie[i] = -1;
        su_ofarbene[i] = -1;
    }

    default_ofarbenie[0] = 0;
    ofarbenie[0] = 0;
    su_ofarbene[ofarbenie[0]] = 0;
    for (i = 1; i < POCET_FARIEB; i++) {
        default_ofarbenie[i * POCET_VRCHOLOV_FARBA] = i; //default_susedia[0][i-1]
        ofarbenie[i * POCET_VRCHOLOV_FARBA] = i; //default_susedia[0][i-1];
        su_ofarbene[ofarbenie[i * POCET_VRCHOLOV_FARBA]] = i;
    }
    for (novy_vrchol = 0; novy_vrchol < POCET_VRCHOLOV; novy_vrchol++) {
        gv = GRAPHROW(g, novy_vrchol, M);
        EMPTYSET(gv, m);
        for (i = 0; i < POCET_SUSEDOV; i++) {
            sused = default_susedia[novy_vrchol][i];
            ADDELEMENT(gv, sused);
        }
    }
    /*
        for (i=0; i<POCET_VRCHOLOV; i++) {
           printf("%d. hrana:  ", i);
           for (j=0; j<POCET_SUSEDOV; j++) {
               printf("%d ", default_susedia[i][j]);
           }
           printf("\n");
        }

        for (i=0; i<POCET_BIN_VRCHOLOV; i++) {
            for (j=0; j<POCET_BIN_VRCHOLOV; j++) {



                if (nove_vrcholy[i][j] != -1) {
                   printf("hrana : %d  ", nove_vrcholy[i][j]);
                   printf("nove vrcholy : %d %d \n", i, j);
                }
            }
        }
     */
}

void FACTOR_STAR_DFS::visit(int *Value, int N, int k) {
    static int level = -1;
    level = level + 1;
    Value[k] = level;
    int i;


    if (level == N)
        print(Value, N);
    else
        for (i = 0; i < N; i++)
            if (Value[i] == 0)
                visit(Value, N, i);

    level = level - 1;
    Value[k] = 0;
}

void FACTOR_STAR_DFS::print(const int *v, const int size) {
    int i, j;

    switch (size) {
        case 6:
            if (v != 0) {

                for (i = 0; i < size; i++) {
                    perm_pole_6[perm_pole_tmp][i] = v[i];
                }
                perm_pole_tmp++;
            }
            break;
        case 5:
            if (v != 0) {
                for (i = 0; i < size; i++) {
                    perm_pole_5[perm_pole_tmp][i] = v[i];
                }
                perm_pole_tmp++;
            }
            break;
        case 4:
            if (v != 0) {
                for (i = 0; i < size; i++) {
                    perm_pole_4[perm_pole_tmp][i] = v[i];
                }
                perm_pole_tmp++;
            }
            break;
        case 3:
            if (v != 0) {
                for (i = 0; i < size; i++) {
                    perm_pole_3[perm_pole_tmp][i] = v[i];
                }
                perm_pole_tmp++;
            }
            break;
        case 2:
            if (v != 0) {
                for (i = 0; i < size; i++) {
                    perm_pole_2[perm_pole_tmp][i] = v[i];
                }
                perm_pole_tmp++;
            }
            break;
    }
}

