// File: iPapatsoris[P]Maximum-Independent-Set/src/Alg.cpp
// Function: Alg::run()
void Alg::run() {
    uint32_t searchNodes = 1;
    uint32_t minCompletedSearchNode = NONE;
    bool down = true;
    uint32_t i = 0;
    while(true) {
        if (down) {
            if (searchTree[i]->theta == 5 && !searchTree[i]->hasCut && searchTree[i]->handleCuts()) {
                ;
            } else {
                searchTree[i]->reductions->run(searchTree[i]->theta);
                //cout << "search node " << searchNodes ;
                searchTree[i]->branchingRule.choose(searchTree[i]->graph, *(searchTree[i]->reductions), searchTree[i]->theta, searchTree[i]);
            }
        } else if (searchTree[i]->rightChild == NONE) {
            down = true;
            assert(searchTree[i]->branchingRule.type != BranchingRule::Type::DONE);
        }
        if (down && searchTree[i]->branchingRule.type == BranchingRule::Type::DONE) {
            searchTree[i]->id = searchNodeID++;
            searchTree[i]->finalMis = new vector<uint32_t>();
            searchTree[i]->mis.unfoldHypernodes(searchTree[i]->graph.zeroDegreeNodes, *searchTree[i]->finalMis);
            i = searchTree[i]->parent;
            if (i == NONE) {
                break;
            }
            down = false;
            continue;
        }
        uint32_t *nextChild;
        if (searchTree[i]->leftChild == NONE) {
            nextChild = &searchTree[i]->leftChild;
        } else if (searchTree[i]->rightChild == NONE) {
            nextChild = &searchTree[i]->rightChild;
        } else if (searchTree[i]->hasCut && !searchTree[i]->cutIsDone) {
            chooseCutBranch(searchTree[i]);
            nextChild = &searchTree[i]->rightChild;
            down = true;
        } else {
            if (i < minCompletedSearchNode) {
                minCompletedSearchNode = i;
                cout << i << endl;
            }
            SearchNode *parent = searchTree[i];
            if (parent->hasCut) {
                assert(parent->cutIsDone);
                concatMis(parent);
                //cout << "concating mis" << endl;
            } else {
                chooseMaxMis(parent);
            }
            i = parent->parent;
            if (searchTree.size() == 1) {
                break;
            }
            continue;
        }
        SearchNode *searchNode = new SearchNode(*searchTree[i], i);
        searchNodes++;
        searchTree.push_back(searchNode);
        *nextChild = searchTree.size() - 1;
        if (nextChild == &searchTree[i]->leftChild) {
            branchLeft(searchTree[i]->branchingRule, searchNode, searchTree[i]->mis);
        }
        else if (nextChild == &searchTree[i]->rightChild) {
            branchRight(searchTree[i]->branchingRule, searchNode, searchTree[i]->mis);
        }
        else {
            assert(false);
        }
        i = *nextChild;
    }
    cout << searchNodes << " search nodes\n";
    searchTree[0]->graph.collectZeroDegreeNodes();
    //cout << "Final id " << searchTree[0]->id;
    Mis::print(*searchTree[0]->finalMis);
    delete searchTree[0]->finalMis;
}

// Assembly:
subq $0xd8, %rsp
movq %rdi, 0xd0(%rsp)
movq 0xd0(%rsp), %rax
movq %rax, 0x90(%rsp)
movl $0x1, 0xcc(%rsp)
movl $0xffffffff, 0xc8(%rsp) # imm = 0xFFFFFFFF
movb $0x1, 0xc7(%rsp)
movl $0x0, 0xc0(%rsp)
testb $0x1, 0xc7(%rsp)
je 0x39147
movq 0x90(%rsp), %rdi
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq (%rax), %rax
cmpl $0x5, 0x4(%rax)
jne 0x39030
movq 0x90(%rsp), %rdi
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq (%rax), %rax
testb $0x1, 0x128(%rax)
jne 0x39030
movq 0x90(%rsp), %rdi
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq (%rax), %rdi
callq 0x39850
testb $0x1, %al
jne 0x3902b
jmp 0x39030
jmp 0x39145
movq 0x90(%rsp), %rdi
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq 0x90(%rsp), %rdi
movq (%rax), %rax
movq 0x108(%rax), %rax
movq %rax, 0x68(%rsp)
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq 0x68(%rsp), %rdi
movq (%rax), %rsi
addq $0x4, %rsi
callq 0x2e4f0
movq 0x90(%rsp), %rdi
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq 0x90(%rsp), %rdi
movq (%rax), %rax
addq $0x8, %rax
movq %rax, 0x70(%rsp)
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq 0x90(%rsp), %rdi
movq (%rax), %rax
addq $0x30, %rax
movq %rax, 0x78(%rsp)
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq 0x90(%rsp), %rdi
movq (%rax), %rax
movq 0x108(%rax), %rax
movq %rax, 0x80(%rsp)
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq 0x90(%rsp), %rdi
movq (%rax), %rax
addq $0x4, %rax
movq %rax, 0x88(%rsp)
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq 0x70(%rsp), %rdi
movq 0x78(%rsp), %rsi
movq 0x80(%rsp), %rdx
movq 0x88(%rsp), %rcx
movq (%rax), %r8
callq 0x3a440
jmp 0x391b5
movq 0x90(%rsp), %rdi
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq (%rax), %rax
cmpl $-0x1, 0x118(%rax)
jne 0x391b3
movq 0x90(%rsp), %rdi
movb $0x1, 0xc7(%rsp)
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq (%rax), %rax
cmpl $0xb, 0x8(%rax)
je 0x39192
jmp 0x391b1
leaq 0xd8c8(%rip), %rdi      # 0x46a61
leaq 0xd900(%rip), %rsi      # 0x46aa0
movl $0x3b, %edx
leaq 0xd900(%rip), %rcx      # 0x46aac
callq 0x2110
jmp 0x391b3
jmp 0x391b5
testb $0x1, 0xc7(%rsp)
je 0x39320
movq 0x90(%rsp), %rdi
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq (%rax), %rax
cmpl $0xb, 0x8(%rax)
jne 0x39320
movq 0x90(%rsp), %rdi
movl 0x24fe4(%rip), %eax     # 0x5e1d8
movl %eax, 0x4c(%rsp)
addl $0x1, %eax
movl %eax, 0x24fd7(%rip)     # 0x5e1d8
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movl 0x4c(%rsp), %ecx
movq (%rax), %rax
movl %ecx, (%rax)
movl $0x18, %edi
callq 0x21b0
movq %rax, %rdi
movq %rdi, 0x50(%rsp)
xorl %esi, %esi
movl $0x18, %edx
callq 0x20e0
movq 0x50(%rsp), %rdi
callq 0x17e60
movq 0x90(%rsp), %rdi
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq 0x50(%rsp), %rcx
movq 0x90(%rsp), %rdi
movq (%rax), %rax
movq %rcx, 0x120(%rax)
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq 0x90(%rsp), %rdi
movq (%rax), %rax
addq $0x80, %rax
movq %rax, 0x58(%rsp)
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq 0x90(%rsp), %rdi
movq (%rax), %rax
addq $0x30, %rax
addq $0x20, %rax
movq %rax, 0x60(%rsp)
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq 0x58(%rsp), %rdi
movq 0x60(%rsp), %rsi
movq (%rax), %rax
movq 0x120(%rax), %rdx
callq 0x41260
movq 0x90(%rsp), %rdi
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq (%rax), %rax
movl 0x110(%rax), %eax
movl %eax, 0xc0(%rsp)
cmpl $-0x1, 0xc0(%rsp)
jne 0x39313
jmp 0x39796
movb $0x0, 0xc7(%rsp)
jmp 0x38fb8
movq 0x90(%rsp), %rdi
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq (%rax), %rax
cmpl $-0x1, 0x114(%rax)
jne 0x3936e
movq 0x90(%rsp), %rdi
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq (%rax), %rax
addq $0x114, %rax            # imm = 0x114
movq %rax, 0xb8(%rsp)
jmp 0x39560
movq 0x90(%rsp), %rdi
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq (%rax), %rax
cmpl $-0x1, 0x118(%rax)
jne 0x393bc
movq 0x90(%rsp), %rdi
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq (%rax), %rax
addq $0x118, %rax            # imm = 0x118
movq %rax, 0xb8(%rsp)
jmp 0x3955e
movq 0x90(%rsp), %rdi
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq (%rax), %rax
testb $0x1, 0x128(%rax)
je 0x3945a
movq 0x90(%rsp), %rdi
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq (%rax), %rax
testb $0x1, 0x199(%rax)
jne 0x3945a
movq 0x90(%rsp), %rdi
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq 0x90(%rsp), %rdi
movq (%rax), %rsi
callq 0x3aa00
movq 0x90(%rsp), %rdi
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq (%rax), %rax
addq $0x118, %rax            # imm = 0x118
movq %rax, 0xb8(%rsp)
movb $0x1, 0xc7(%rsp)
jmp 0x3955c
movl 0xc0(%rsp), %eax
cmpl 0xc8(%rsp), %eax
jae 0x3949a
movl 0xc0(%rsp), %eax
movl %eax, 0xc8(%rsp)
movl 0xc0(%rsp), %esi
movq 0x24b4a(%rip), %rdi     # 0x5dfd0
callq 0x2230
movq %rax, %rdi
movq 0x24b23(%rip), %rsi     # 0x5dfb8
callq 0x21d0
movq 0x90(%rsp), %rdi
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq (%rax), %rax
movq %rax, 0xb0(%rsp)
movq 0xb0(%rsp), %rax
testb $0x1, 0x128(%rax)
je 0x39515
movq 0xb0(%rsp), %rax
testb $0x1, 0x199(%rax)
je 0x394df
jmp 0x394fe
leaq 0xd5d6(%rip), %rdi      # 0x46abc
leaq 0xd5b3(%rip), %rsi      # 0x46aa0
movl $0x58, %edx
leaq 0xd5b3(%rip), %rcx      # 0x46aac
callq 0x2110
movq 0x90(%rsp), %rdi
movq 0xb0(%rsp), %rsi
callq 0x3aba0
jmp 0x3952a
movq 0x90(%rsp), %rdi
movq 0xb0(%rsp), %rsi
callq 0x3af50
movq 0x90(%rsp), %rdi
movq 0xb0(%rsp), %rax
movl 0x110(%rax), %eax
movl %eax, 0xc0(%rsp)
callq 0x3b170
cmpq $0x1, %rax
jne 0x39557
jmp 0x39796
jmp 0x38fb8
jmp 0x3955e
jmp 0x39560
movl $0x1a0, %edi            # imm = 0x1A0
callq 0x21b0
movq 0x90(%rsp), %rdi
movq %rax, 0x40(%rsp)
movq %rax, 0x38(%rsp)
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq 0x40(%rsp), %rdi
movq (%rax), %rsi
leaq 0xc0(%rsp), %rdx
callq 0x38c30
jmp 0x395a1
movq 0x90(%rsp), %rdi
movq 0x38(%rsp), %rax
movq %rax, 0xa8(%rsp)
movl 0xcc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xcc(%rsp)
leaq 0xa8(%rsp), %rsi
callq 0x3a060
movq 0x90(%rsp), %rdi
callq 0x3b170
movq 0x90(%rsp), %rdi
subq $0x1, %rax
movl %eax, %ecx
movq 0xb8(%rsp), %rax
movl %ecx, (%rax)
movq 0xb8(%rsp), %rax
movq %rax, 0x30(%rsp)
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq %rax, %rcx
movq 0x30(%rsp), %rax
movq (%rcx), %rcx
addq $0x114, %rcx            # imm = 0x114
cmpq %rcx, %rax
jne 0x396bd
movq 0x90(%rsp), %rdi
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq 0x90(%rsp), %rdi
movq (%rax), %rax
addq $0x8, %rax
movq %rax, 0x20(%rsp)
movq 0xa8(%rsp), %rax
movq %rax, 0x28(%rsp)
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq 0x90(%rsp), %rdi
movq 0x20(%rsp), %rsi
movq 0x28(%rsp), %rdx
movq (%rax), %rcx
addq $0x80, %rcx
callq 0x3b190
jmp 0x39780
movq 0x38(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xa0(%rsp)
movl %eax, 0x9c(%rsp)
callq 0x2180
jmp 0x39834
movq 0x90(%rsp), %rdi
movq 0xb8(%rsp), %rax
movq %rax, 0x18(%rsp)
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq %rax, %rcx
movq 0x18(%rsp), %rax
movq (%rcx), %rcx
addq $0x118, %rcx            # imm = 0x118
cmpq %rcx, %rax
jne 0x3975f
movq 0x90(%rsp), %rdi
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq 0x90(%rsp), %rdi
movq (%rax), %rax
addq $0x8, %rax
movq %rax, 0x8(%rsp)
movq 0xa8(%rsp), %rax
movq %rax, 0x10(%rsp)
movl 0xc0(%rsp), %eax
movl %eax, %esi
callq 0x3a420
movq 0x90(%rsp), %rdi
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq (%rax), %rcx
addq $0x80, %rcx
callq 0x3b940
jmp 0x3977e
leaq 0xca20(%rip), %rdi      # 0x46186
leaq 0xd333(%rip), %rsi      # 0x46aa0
movl $0x6f, %edx
leaq 0xd333(%rip), %rcx      # 0x46aac
callq 0x2110
jmp 0x39780
movq 0xb8(%rsp), %rax
movl (%rax), %eax
movl %eax, 0xc0(%rsp)
jmp 0x38fb8
movl 0xcc(%rsp), %esi
movq 0x2482c(%rip), %rdi     # 0x5dfd0
callq 0x2230
movq %rax, %rdi
leaq 0xd31b(%rip), %rsi      # 0x46ace
callq 0x2190
movq 0x90(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x3a420
movq (%rax), %rdi
addq $0x30, %rdi
callq 0x9e10
movq 0x90(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x3a420
movq (%rax), %rax
movq 0x120(%rax), %rdi
callq 0x415b0
movq 0x90(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x3a420
movq (%rax), %rax
movq 0x120(%rax), %rax
movq %rax, (%rsp)
cmpq $0x0, %rax
je 0x3982c
movq (%rsp), %rdi
callq 0x18520
movq (%rsp), %rdi
callq 0x2180
addq $0xd8, %rsp
retq
movq 0xa0(%rsp), %rdi
callq 0x2310
nopw %cs:(%rax,%rax)