// File: /workspace/github_cpp_makefile_star2_O3/iPapatsoris[P]Maximum-Independent-Set/src/Graph.cpp
// Function: Graph::getFunnels(std::vector<Graph::Funnel, std::allocator<Graph::Funnel>>&, unsigned int const*, unsigned int*, Graph::Funnel*) const
bool Graph::getFunnels(vector<Funnel> &funnels, const uint32_t *measure, uint32_t *effectiveNode, Funnel *fourFunnel) const {
    GraphTraversal graphTraversal(*this);
    while (graphTraversal.curNode != NONE) {
        uint32_t nodeV = graphTraversal.curNode;
        uint32_t vDegree = getNodeDegree(nodeV);
        if (vDegree == 3 || vDegree == 4) {
            vector<uint32_t> neighborsV;
            gatherNeighbors(nodeV, neighborsV);
            for (uint32_t i = 0 ; i < neighborsV.size() ; i++) {
                uint32_t nodeA = neighborsV[i];
                uint32_t nodeB, nodeC, nodeD;
                if (i == 0) {
                    nodeB = neighborsV[1];
                    nodeC = neighborsV[2];
                    nodeD = (neighborsV.size() == 3 ? NONE : neighborsV[3]);
                } else if (i == 1) {
                    nodeB = neighborsV[0];
                    nodeC = neighborsV[2];
                    nodeD = (neighborsV.size() == 3 ? NONE : neighborsV[3]);
                } else if (i == 2) {
                    nodeB = neighborsV[0];
                    nodeC = neighborsV[1];
                    nodeD = (neighborsV.size() == 3 ? NONE : neighborsV[3]);
                } else {
                    nodeB = neighborsV[0];
                    nodeC = neighborsV[1];
                    nodeD = (neighborsV.size() == 3 ? NONE : neighborsV[2]);
                }
                if (edgeExists(nodeB, nodeC) && (vDegree == 3 || vDegree == 4 && edgeExists(nodeB, nodeD) && edgeExists(nodeC, nodeD)))  {
                    if (measure == NULL) {
                        funnels.push_back(Funnel(nodeA, nodeB, nodeC, nodeD, nodeV));
                        if (vDegree == 4 || (getNodeDegree(nodeA) == 4 && (getNodeDegree(nodeB) == 4 || getNodeDegree(nodeC) == 4))) {
                            return true;
                        }
                    } else {
                        uint32_t degree3NodesCount;
                        if (getNodeDegree(nodeA) == 3) {
                            degree3NodesCount++;
                        }
                        if (getNodeDegree(nodeB) == 3) {
                            degree3NodesCount++;
                        }
                        if (getNodeDegree(nodeC) == 3) {
                            degree3NodesCount++;
                        }
                        if (vDegree == 4 && getNodeDegree(nodeD) == 3) {
                            degree3NodesCount++;
                        }
                        if (degree3NodesCount >= 3) {
                            Graph newGraph = *this;
                            unordered_set<uint32_t> extendedGrandchildren;
                            goToNode(nodeV, graphTraversal);
                            getExtendedGrandchildren(graphTraversal, extendedGrandchildren);
                            extendedGrandchildren.insert(nodeV);
                            std::unordered_set<uint32_t> neighbors;
                            gatherAllNeighbors(extendedGrandchildren, neighbors);
                            unordered_set<uint32_t> *smaller = &neighbors;
                            unordered_set<uint32_t> *bigger = &extendedGrandchildren;
                            if (smaller->size() > bigger->size()) {
                                std::unordered_set<uint32_t> *tmp = smaller;
                                smaller = bigger;
                                bigger = tmp;
                            }
                            smaller->insert(bigger->begin(), bigger->end());
                            ReduceInfo dummy;
                            newGraph.remove(vector<uint32_t>(smaller->begin(), smaller->end()), dummy);
                            if (newGraph.getEffectiveNodeMeasure(*measure - 20) <= *measure - 20) {
                                *effectiveNode = nodeV;
                                return true;
                            }
                        }
                        Funnel funnel(nodeA, nodeB, nodeC, nodeD, nodeV);
                        if (vDegree == 4) {
                            *fourFunnel = funnel;
                            return true;
                        } else {
                            funnels.push_back(funnel);
                        }
                    }
                }
            }
        }
        getNextNode(graphTraversal);
    }
    return false;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x158, %rsp            # imm = 0x158
movq %r8, 0xd8(%rsp)
movq %rcx, 0xd0(%rsp)
movq %rdx, %rbx
movq %rsi, %r14
movq %rdi, %r13
leaq 0x2c(%rsp), %rsi
movq $-0x1, (%rsi)
callq 0xb94a
leaq 0x10(%rsp), %r15
leaq 0x8(%rsp), %r12
movq %r14, 0x60(%rsp)
movq %rbx, 0xe0(%rsp)
movl 0x2c(%rsp), %ebp
cmpl $-0x1, %ebp
je 0x5bdb
movl %ebp, 0x10(%rsp)
movq %r13, %rdi
movq %r15, %rsi
callq 0xc2d2
movq %rax, 0x20(%rsp)
addl $-0x3, %eax
cmpl $0x1, %eax
movl %ebp, 0x34(%rsp)
ja 0x5bbb
xorps %xmm0, %xmm0
movaps %xmm0, 0x40(%rsp)
movq $0x0, 0x50(%rsp)
movl $0xffffffff, 0x80(%rsp) # imm = 0xFFFFFFFF
movq %r13, %rdi
movq %r15, %rsi
leaq 0x40(%rsp), %rdx
xorl %ecx, %ecx
leaq 0x80(%rsp), %r8
callq 0xc092
movq 0x40(%rsp), %rdi
movq 0x48(%rsp), %rax
subq %rdi, %rax
je 0x5b23
xorl %ebp, %ebp
movl (%rdi,%rbp,4), %ecx
movl %ecx, 0x18(%rsp)
cmpl $0x2, %ebp
je 0x5671
cmpl $0x1, %ebp
je 0x5666
testl %ebp, %ebp
jne 0x568e
movl 0x4(%rdi), %ecx
jmp 0x5668
movl (%rdi), %ecx
movl %ecx, 0x8(%rsp)
movl 0x8(%rdi), %ecx
jmp 0x567a
movl (%rdi), %ecx
movl %ecx, 0x8(%rsp)
movl 0x4(%rdi), %ecx
movl %ecx, 0x4(%rsp)
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
cmpq $0xc, %rax
je 0x56a9
movl 0xc(%rdi), %ecx
jmp 0x56a9
movl (%rdi), %ecx
movl %ecx, 0x8(%rsp)
movl 0x4(%rdi), %ecx
movl %ecx, 0x4(%rsp)
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
cmpq $0xc, %rax
je 0x56a9
movl 0x8(%rdi), %ecx
movl %ecx, 0xc(%rsp)
movq %r13, %rdi
movq %r12, %rsi
leaq 0x4(%rsp), %rdx
callq 0xbf3a
cmpl $-0x1, %eax
je 0x5b04
cmpl $0x3, 0x20(%rsp)
jne 0x59fa
testq %rbx, %rbx
je 0x5a3e
movq %r13, %rdi
leaq 0x18(%rsp), %rsi
callq 0xc2d2
movl %eax, %r15d
movq %r13, %rdi
leaq 0x8(%rsp), %rsi
callq 0xc2d2
movl %eax, %r12d
movq %r13, %rdi
leaq 0x4(%rsp), %rsi
callq 0xc2d2
xorl %ecx, %ecx
cmpl $0x3, %r12d
sete %cl
xorl %edx, %edx
cmpl $0x3, %r15d
sete %dl
movl 0x38(%rsp), %esi
addl %edx, %esi
xorl %edx, %edx
cmpl $0x3, %eax
sete %dl
addl %ecx, %edx
addl %esi, %edx
cmpl $0x4, 0x20(%rsp)
jne 0x574f
movl %edx, %r15d
movq %r13, %rdi
leaq 0xc(%rsp), %rsi
callq 0xc2d2
xorl %ecx, %ecx
cmpl $0x3, %eax
sete %cl
movl %r15d, %edx
addl %ecx, %edx
movl %edx, 0x38(%rsp)
cmpl $0x3, %edx
leaq 0x8(%rsp), %r12
jb 0x598b
leaq 0x80(%rsp), %rdi
movq %r13, %rsi
callq 0x274c
leaq 0x150(%rsp), %rax
movq %rax, 0x120(%rsp)
movq $0x1, 0x128(%rsp)
leaq 0x130(%rsp), %r14
xorps %xmm0, %xmm0
movups %xmm0, (%r14)
movl $0x3f800000, 0x140(%rsp) # imm = 0x3F800000
movups %xmm0, -0x8(%rax)
movq %r13, %rdi
leaq 0x10(%rsp), %rsi
leaq 0x2c(%rsp), %rdx
callq 0xba5a
leaq 0x120(%rsp), %r15
leaq 0xe8(%rsp), %r12
movb $0x0, 0xe8(%rsp)
movq %r13, %rdi
leaq 0x2c(%rsp), %rsi
movq %r15, %rdx
xorl %ecx, %ecx
movq %r12, %r8
callq 0x3fee
movq %r15, 0xe8(%rsp)
movq %r15, %rdi
leaq 0x10(%rsp), %rsi
movq %r12, %rdx
callq 0xd538
leaq 0x118(%rsp), %rax
movq %rax, 0xe8(%rsp)
movq $0x1, 0xf0(%rsp)
xorps %xmm0, %xmm0
movups %xmm0, -0x20(%rax)
movl $0x3f800000, 0x108(%rsp) # imm = 0x3F800000
movups %xmm0, -0x8(%rax)
movl $0xffffffff, 0x68(%rsp) # imm = 0xFFFFFFFF
movq %r14, %rbx
leaq 0x68(%rsp), %r14
movq (%rbx), %rbx
testq %rbx, %rbx
je 0x5865
leaq 0x8(%rbx), %rsi
movq %r13, %rdi
movq %r12, %rdx
movq %r15, %rcx
movq %r14, %r8
callq 0xde74
testb %al, %al
jne 0x5844
movq 0xf8(%rsp), %rsi
movq %r15, %rcx
movq %r12, %r15
movq 0x100(%rsp), %r12
movq 0x130(%rsp), %rax
movq 0x138(%rsp), %r14
cmpq %r14, %r12
cmovaq %rcx, %r15
movq %rax, %rbx
cmovaq %rsi, %rbx
movq %r15, 0x68(%rsp)
testq %rbx, %rbx
je 0x58cc
leaq 0x8(%rbx), %rsi
movq %r15, %rdi
leaq 0x68(%rsp), %rdx
callq 0xd538
movq (%rbx), %rbx
testq %rbx, %rbx
jne 0x58a3
movq 0x130(%rsp), %rax
movq 0xf8(%rsp), %rsi
cmpq %r14, %r12
movl $0x0, 0x3c(%rsp)
cmovaq %rax, %rsi
leaq 0x68(%rsp), %rbx
movq %rbx, %rdi
xorl %edx, %edx
leaq 0x1f(%rsp), %rcx
callq 0xc336
xorl %eax, %eax
movb %al, 0x17(%rsp)
movb %al, 0x16(%rsp)
leaq 0x80(%rsp), %rdi
movq %rbx, %rsi
leaq 0x3c(%rsp), %rdx
leaq 0x17(%rsp), %rcx
xorl %r8d, %r8d
leaq 0x16(%rsp), %r9
callq 0xbaa6
movq 0xe0(%rsp), %rbx
movq 0x60(%rsp), %r14
leaq 0x8(%rsp), %r12
movq 0x68(%rsp), %rdi
testq %rdi, %rdi
je 0x593c
callq 0x21a0
movl (%rbx), %eax
addl $-0x14, %eax
movl %eax, 0x68(%rsp)
leaq 0x80(%rsp), %rdi
leaq 0x68(%rsp), %rsi
callq 0x527e
movl (%rbx), %ecx
addl $-0x14, %ecx
cmpl %ecx, %eax
jbe 0x5b65
leaq 0xe8(%rsp), %rdi
callq 0xc950
leaq 0x120(%rsp), %rdi
callq 0xc950
leaq 0x80(%rsp), %rdi
callq 0x2950
movl 0x18(%rsp), %eax
movl %eax, 0x80(%rsp)
movl 0x8(%rsp), %eax
movl %eax, 0x84(%rsp)
movl 0x4(%rsp), %eax
movl %eax, 0x88(%rsp)
movl 0xc(%rsp), %eax
movl %eax, 0x8c(%rsp)
movl 0x10(%rsp), %eax
movl %eax, 0x90(%rsp)
cmpl $0x4, 0x20(%rsp)
je 0x5b2a
movq 0x8(%r14), %rsi
cmpq 0x10(%r14), %rsi
je 0x5a9b
movl 0x90(%rsp), %eax
movl %eax, 0x10(%rsi)
movups 0x80(%rsp), %xmm0
movups %xmm0, (%rsi)
addq $0x14, 0x8(%r14)
jmp 0x5b04
cmpl $0x4, 0x20(%rsp)
jne 0x5b04
movq %r13, %rdi
movq %r12, %rsi
leaq 0xc(%rsp), %rdx
callq 0xbf3a
cmpl $-0x1, %eax
je 0x5b04
movq %r13, %rdi
leaq 0x4(%rsp), %rsi
leaq 0xc(%rsp), %rdx
callq 0xbf3a
cmpl $-0x1, %eax
jne 0x56d1
jmp 0x5b04
movl 0x18(%rsp), %eax
movl %eax, 0x80(%rsp)
movl 0x8(%rsp), %eax
movl %eax, 0x84(%rsp)
movl 0x4(%rsp), %eax
movl %eax, 0x88(%rsp)
movl 0xc(%rsp), %eax
movl %eax, 0x8c(%rsp)
movl 0x10(%rsp), %eax
movl %eax, 0x90(%rsp)
movq 0x8(%r14), %rsi
cmpq 0x10(%r14), %rsi
je 0x5aad
movl 0x90(%rsp), %eax
movl %eax, 0x10(%rsi)
movups 0x80(%rsp), %xmm0
movups %xmm0, (%rsi)
addq $0x14, 0x8(%r14)
jmp 0x5abd
movq %r14, %rdi
leaq 0x80(%rsp), %rdx
callq 0xe224
jmp 0x5b04
movq %r14, %rdi
leaq 0x80(%rsp), %rdx
callq 0xe008
cmpl $0x4, 0x20(%rsp)
je 0x5b9a
movq %r13, %rdi
leaq 0x18(%rsp), %rsi
callq 0xc2d2
cmpl $0x4, %eax
jne 0x5b04
movq %r13, %rdi
movq %r12, %rsi
callq 0xc2d2
cmpl $0x4, %eax
je 0x5b9a
movq %r13, %rdi
leaq 0x4(%rsp), %rsi
callq 0xc2d2
cmpl $0x4, %eax
je 0x5b9a
incl %ebp
movq 0x40(%rsp), %rdi
movq 0x48(%rsp), %rax
subq %rdi, %rax
movq %rax, %rcx
sarq $0x2, %rcx
cmpq %rbp, %rcx
ja 0x564c
xorl %r14d, %r14d
xorl %ebp, %ebp
jmp 0x5ba7
movl 0x90(%rsp), %eax
movq 0xd8(%rsp), %rcx
movl %eax, 0x10(%rcx)
movl 0x80(%rsp), %eax
movl %eax, (%rcx)
movl 0x84(%rsp), %eax
movl %eax, 0x4(%rcx)
movl 0x88(%rsp), %eax
movl %eax, 0x8(%rcx)
movl 0x8c(%rsp), %eax
movl %eax, 0xc(%rcx)
jmp 0x5b9a
movl 0x10(%rsp), %eax
movq 0xd0(%rsp), %rcx
movl %eax, (%rcx)
leaq 0xe8(%rsp), %rdi
callq 0xc950
leaq 0x120(%rsp), %rdi
callq 0xc950
leaq 0x80(%rsp), %rdi
callq 0x2950
movl $0x1, %ebp
movb $0x1, %r14b
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x5bb1
callq 0x21a0
testb %r14b, %r14b
movq 0x60(%rsp), %r14
jne 0x5bca
movq %r13, %rdi
leaq 0x2c(%rsp), %rsi
callq 0xb94a
xorl %ebp, %ebp
testl %ebp, %ebp
leaq 0x10(%rsp), %r15
movl 0x34(%rsp), %ebp
je 0x55d0
cmpl $-0x1, %ebp
setne %al
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x5c1c
jmp 0x5c1c
jmp 0x5c1c
jmp 0x5c15
jmp 0x5c1c
jmp 0x5c23
jmp 0x5c23
movq %rax, %rbx
movq 0x68(%rsp), %rdi
testq %rdi, %rdi
je 0x5c26
callq 0x21a0
jmp 0x5c26
movq %rax, %rbx
jmp 0x5c33
jmp 0x5c1c
movq %rax, %rbx
jmp 0x5c4d
jmp 0x5c23
movq %rax, %rbx
leaq 0xe8(%rsp), %rdi
callq 0xc950
leaq 0x120(%rsp), %rdi
callq 0xc950
leaq 0x80(%rsp), %rdi
callq 0x2950
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x5c5c
callq 0x21a0
movq %rbx, %rdi
callq 0x2320