// File: Manca[P]algorithms2/./assignment6.hpp
// Function: assignment6::Check2SAT(std::unordered_map<int, std::vector<int, std::allocator<int>>, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, std::vector<int, std::allocator<int>>>>>&, std::unordered_map<int, std::vector<int, std::allocator<int>>, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, std::vector<int, std::allocator<int>>>>>&)
bool Check2SAT(Graph& G, Graph& GRev)
    {
        // Kosaraju SCC Algorithm
        // step 1: while stack size less than graph size
        // push elements according to their finish times
        while (_S.size() < G.size())
        {
            for (auto element : G)
            {
                // if not found in stack (not explored), let's DFS
                if (!_explored[element.first])
                {
                    DFSFillStack(G, element.first);
                }
            }
        }
        
        _explored.clear();
        std::vector<std::vector<int>> allSCC;

        // step 2: pop elements from stack and DFS
        // on transposed graph
        while (!_S.empty())
        {
            int el = _S.top();
            _S.pop();
            if (_explored[el])
                continue;

            std::vector<int> scc;
            DFSSCC(GRev, el, scc);
            allSCC.push_back(scc);
        }

        // Prints SCCs on reversed graph
        /*  for (auto vec : allSCC)
        {
        for (int el : vec)
        std::cout << " " << el;
        std::cout << std::endl;
        }*/

        // step 3: added step for 2SAT problem
        // if we find X and not X in SCC then
        // 2SAT is unsatisfiable
        for (auto vec : allSCC)
        {
            for (int i = 0; i < vec.size(); i++)
            {
                for (int j = 0; j < vec.size(); j++)
                    if (vec[i] == -vec[j])
                    {
                        return false;
                    }
            }
        }
        return true;
    }

// Assembly:
subq $0x128, %rsp            # imm = 0x128
movq %rdi, 0x118(%rsp)
movq %rsi, 0x110(%rsp)
leaq 0x3a332(%rip), %rdi     # 0x44300
callq 0x12420
movq %rax, 0x48(%rsp)
movq 0x118(%rsp), %rdi
callq 0x12430
movq %rax, %rcx
movq 0x48(%rsp), %rax
cmpq %rcx, %rax
jae 0xa0f4
movq 0x118(%rsp), %rax
movq %rax, 0x108(%rsp)
movq 0x108(%rsp), %rdi
callq 0x12440
movq %rax, 0x100(%rsp)
movq 0x108(%rsp), %rdi
callq 0x12470
movq %rax, 0xf8(%rsp)
leaq 0x100(%rsp), %rdi
leaq 0xf8(%rsp), %rsi
callq 0x124a0
testb $0x1, %al
jne 0xa04e
jmp 0xa0ef
leaq 0x100(%rsp), %rdi
callq 0x124c0
movq %rax, %rsi
leaq 0xd8(%rsp), %rdi
movq %rdi, 0x38(%rsp)
callq 0x124e0
movq 0x38(%rsp), %rsi
leaq 0x3a2d4(%rip), %rdi     # 0x44350
callq 0x11100
movq %rax, 0x40(%rsp)
jmp 0xa088
movq 0x40(%rsp), %rax
testb $0x1, (%rax)
jne 0xa0d0
movq 0x118(%rsp), %rdi
movl 0xd8(%rsp), %esi
callq 0x9e20
jmp 0xa0a8
jmp 0xa0d0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xd0(%rsp)
movl %eax, 0xcc(%rsp)
leaq 0xd8(%rsp), %rdi
callq 0x12520
jmp 0xa3ae
leaq 0xd8(%rsp), %rdi
callq 0x12520
leaq 0x100(%rsp), %rdi
callq 0x12540
jmp 0xa030
jmp 0x9fc7
leaq 0x3a255(%rip), %rdi     # 0x44350
callq 0x12570
leaq 0xb0(%rsp), %rdi
callq 0x12580
leaq 0x3a1ec(%rip), %rdi     # 0x44300
callq 0x12590
movb %al, 0x37(%rsp)
jmp 0xa11f
movb 0x37(%rsp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0xa12e
jmp 0xa219
leaq 0x3a1cb(%rip), %rdi     # 0x44300
callq 0x125b0
movq %rax, 0x28(%rsp)
jmp 0xa141
movq 0x28(%rsp), %rax
movl (%rax), %eax
movl %eax, 0xac(%rsp)
leaq 0x3a1aa(%rip), %rdi     # 0x44300
callq 0x125c0
jmp 0xa15d
leaq 0x3a1ec(%rip), %rdi     # 0x44350
leaq 0xac(%rsp), %rsi
callq 0x11100
movq %rax, 0x20(%rsp)
jmp 0xa178
movq 0x20(%rsp), %rax
testb $0x1, (%rax)
je 0xa19d
jmp 0xa10d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xd0(%rsp)
movl %eax, 0xcc(%rsp)
jmp 0xa3a1
leaq 0x90(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x10fd0
movq 0x18(%rsp), %rdx
movq 0x110(%rsp), %rdi
movl 0xac(%rsp), %esi
callq 0x9ee0
jmp 0xa1ca
leaq 0xb0(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0x125d0
jmp 0xa1e1
leaq 0x90(%rsp), %rdi
callq 0x107c0
jmp 0xa10d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xd0(%rsp)
movl %eax, 0xcc(%rsp)
leaq 0x90(%rsp), %rdi
callq 0x107c0
jmp 0xa3a1
leaq 0xb0(%rsp), %rax
movq %rax, 0x88(%rsp)
movq 0x88(%rsp), %rdi
callq 0x12640
movq %rax, 0x80(%rsp)
movq 0x88(%rsp), %rdi
callq 0x12670
movq %rax, 0x78(%rsp)
leaq 0x80(%rsp), %rdi
leaq 0x78(%rsp), %rsi
callq 0x126a0
testb $0x1, %al
jne 0xa26b
jmp 0xa373
leaq 0x80(%rsp), %rdi
callq 0x126e0
movq %rax, %rsi
leaq 0x60(%rsp), %rdi
callq 0x126f0
jmp 0xa287
movl $0x0, 0x5c(%rsp)
movslq 0x5c(%rsp), %rax
movq %rax, 0x10(%rsp)
leaq 0x60(%rsp), %rdi
callq 0x102a0
movq %rax, %rcx
movq 0x10(%rsp), %rax
cmpq %rcx, %rax
jae 0xa343
movl $0x0, 0x58(%rsp)
movslq 0x58(%rsp), %rax
movq %rax, 0x8(%rsp)
leaq 0x60(%rsp), %rdi
callq 0x102a0
movq %rax, %rcx
movq 0x8(%rsp), %rax
cmpq %rcx, %rax
jae 0xa331
movslq 0x5c(%rsp), %rsi
leaq 0x60(%rsp), %rdi
callq 0x11720
movl (%rax), %eax
movl %eax, 0x4(%rsp)
movslq 0x58(%rsp), %rsi
leaq 0x60(%rsp), %rdi
callq 0x11720
movq %rax, %rdx
movl 0x4(%rsp), %eax
xorl %ecx, %ecx
subl (%rdx), %ecx
cmpl %ecx, %eax
jne 0xa322
movb $0x0, 0x127(%rsp)
movl $0x1, 0x54(%rsp)
jmp 0xa34b
jmp 0xa324
movl 0x58(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x58(%rsp)
jmp 0xa2bc
jmp 0xa333
movl 0x5c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x5c(%rsp)
jmp 0xa28f
movl $0x0, 0x54(%rsp)
leaq 0x60(%rsp), %rdi
callq 0x107c0
movl 0x54(%rsp), %eax
testl %eax, %eax
jne 0xa383
jmp 0xa35f
jmp 0xa361
leaq 0x80(%rsp), %rdi
callq 0x127f0
jmp 0xa250
movb $0x1, 0x127(%rsp)
movl $0x1, 0x54(%rsp)
leaq 0xb0(%rsp), %rdi
callq 0x11780
movb 0x127(%rsp), %al
andb $0x1, %al
addq $0x128, %rsp            # imm = 0x128
retq
leaq 0xb0(%rsp), %rdi
callq 0x11780
movq 0xd0(%rsp), %rdi
callq 0x3460
nopl (%rax,%rax)