// File: Laakeri[P]Triangulator/src/hyper.cpp
// Function: Hyper::SolveGraph::solveGraph(Graph const&, int, int, int, std::vector<int, std::allocator<int>> const&)
pair<int, vector<pair<int, int> > > solveGraph(const Graph& G, int lowerBound, int okWidth, int upperBound, const vector<int>& vertMap) {
	assert(lowerBound >= 0);
	assert(okWidth <= upperBound);
	if (lowerBound > upperBound) return {-1, FAILSOLUTION};
	okWidth = max(okWidth, lowerBound);
	
	auto fill = MCS::MCS_MP(G);
	
	Graph gFill = G;
	gFill.addEdges(fill.F);
	
	int fillWidth = MCS::getHyperTreeWidth(gFill, vertMap);
	assert(fillWidth >= lowerBound);
	
	if (fillWidth <= okWidth) return {fillWidth, fill.F};
	
	vector<Graph> atoms = MCS::getAtoms(G, gFill, fill).S;
	
	auto cmp = [](const Graph& a, const Graph& b) {
		return a.n > b.n;
	};
	sort(atoms.begin(), atoms.end(), cmp);
	pair<int, vector<pair<int, int> > > sol = {lowerBound, {}};
	for (int i = 0; i < (int)atoms.size(); i++) {
		pair<int, vector<pair<int, int> > > tSol;
		if (i+1 < (int)atoms.size()) {
			tSol = SolveAtom::solveAtom(atoms[i], 1, sol.F, min(upperBound, fillWidth-1), atoms[i].mapTableInto(vertMap));
		}
		else {
			tSol = SolveAtom::solveAtom(atoms[i], 1, sol.F, min(upperBound, fillWidth-1), atoms[i].mapTableInto(vertMap));
		}
		if (tSol.S == FAILSOLUTION) {
			if (fillWidth <= upperBound) {
				return {fillWidth, fill.F};
			}
			else {
				return {-1, FAILSOLUTION};
			}
		}
		sol.F = max(sol.F, tSol.F);
		tSol.S = atoms[i].mapBack(tSol.S);
		sol.S.insert(sol.S.end(), tSol.S.begin(), tSol.S.end());
	}
	assert(sol.F <= upperBound);
	return sol;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x310, %rsp            # imm = 0x310
movq %rdi, -0x278(%rbp)
movq %rdi, %rax
movq %rax, -0x270(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movl %ecx, -0x18(%rbp)
movl %r8d, -0x1c(%rbp)
movq %r9, -0x28(%rbp)
cmpl $0x0, -0x14(%rbp)
jl 0x1f77a
jmp 0x1f799
leaq 0x39ba1(%rip), %rdi     # 0x59322
leaq 0x3a028(%rip), %rsi     # 0x597b0
movl $0x64, %edx
leaq 0x3a19a(%rip), %rcx     # 0x5992e
callq 0x31a0
movl -0x18(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jg 0x1f7a3
jmp 0x1f7c2
leaq 0x3a081(%rip), %rdi     # 0x5982b
leaq 0x39fff(%rip), %rsi     # 0x597b0
movl $0x65, %edx
leaq 0x3a171(%rip), %rcx     # 0x5992e
callq 0x31a0
movl -0x14(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jle 0x1f7ed
movq -0x278(%rbp), %rdi
movl $0xffffffff, -0x2c(%rbp) # imm = 0xFFFFFFFF
leaq -0x2c(%rbp), %rsi
leaq 0x5ab05(%rip), %rdx     # 0x7a2e8
callq 0x23c40
jmp 0x1ff64
leaq -0x18(%rbp), %rdi
leaq -0x14(%rbp), %rsi
callq 0x23c80
movl (%rax), %eax
movl %eax, -0x18(%rbp)
movq -0x10(%rbp), %rsi
leaq -0x60(%rbp), %rdi
callq 0x28a90
movq -0x10(%rbp), %rsi
leaq -0xb8(%rbp), %rdi
callq 0xb8b0
jmp 0x1f81e
leaq -0xb8(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x15db0
jmp 0x1f830
movq -0x28(%rbp), %rsi
leaq -0xb8(%rbp), %rdi
callq 0x2ace0
movl %eax, -0x27c(%rbp)
jmp 0x1f848
movl -0x27c(%rbp), %eax
movl %eax, -0xc8(%rbp)
movl -0xc8(%rbp), %eax
cmpl -0x14(%rbp), %eax
jl 0x1f861
jmp 0x1f8ae
leaq 0x399fc(%rip), %rdi     # 0x59264
leaq 0x39f41(%rip), %rsi     # 0x597b0
movl $0x6f, %edx
leaq 0x3a0b3(%rip), %rcx     # 0x5992e
callq 0x31a0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc0(%rbp)
movl %eax, -0xc4(%rbp)
jmp 0x1ff59
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc0(%rbp)
movl %eax, -0xc4(%rbp)
jmp 0x1ff4d
movl -0xc8(%rbp), %eax
cmpl -0x18(%rbp), %eax
jg 0x1f8e1
movq -0x278(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
leaq -0x60(%rbp), %rdx
callq 0x23cc0
jmp 0x1f8d2
movl $0x1, -0xcc(%rbp)
jmp 0x1ff36
movq -0x10(%rbp), %rsi
leaq -0x108(%rbp), %rdi
leaq -0xb8(%rbp), %rdx
leaq -0x60(%rbp), %rcx
callq 0x292b0
jmp 0x1f8fe
leaq -0x100(%rbp), %rsi
leaq -0xe8(%rbp), %rdi
movq %rdi, -0x288(%rbp)
callq 0xbca0
leaq -0x108(%rbp), %rdi
callq 0xbcd0
movq -0x288(%rbp), %rdi
callq 0xbcf0
movq -0x288(%rbp), %rdi
movq %rax, -0x118(%rbp)
callq 0xbd20
movq %rax, -0x120(%rbp)
movq -0x118(%rbp), %rdi
movq -0x120(%rbp), %rsi
callq 0x1ff80
jmp 0x1f95f
xorps %xmm0, %xmm0
movaps %xmm0, -0x160(%rbp)
movq $0x0, -0x150(%rbp)
leaq -0x160(%rbp), %rdi
movq %rdi, -0x290(%rbp)
callq 0xbd50
movq -0x290(%rbp), %rdx
leaq -0x148(%rbp), %rdi
leaq -0x14(%rbp), %rsi
callq 0x23dc0
jmp 0x1f9a0
leaq -0x160(%rbp), %rdi
callq 0x5470
movl $0x0, -0x164(%rbp)
movl -0x164(%rbp), %eax
movl %eax, -0x294(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0xbd70
movq %rax, %rcx
movl -0x294(%rbp), %eax
cmpl %ecx, %eax
jge 0x1feb9
leaq -0x188(%rbp), %rdi
callq 0x23e00
jmp 0x1f9ed
movl -0x164(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x298(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0xbd70
movq %rax, %rcx
movl -0x298(%rbp), %eax
cmpl %ecx, %eax
jge 0x1fb86
movslq -0x164(%rbp), %rsi
leaq -0xe8(%rbp), %rdi
callq 0xbde0
movq %rax, -0x2b0(%rbp)
movl -0x148(%rbp), %eax
movl %eax, -0x2a4(%rbp)
movl -0xc8(%rbp), %eax
decl %eax
movl %eax, -0x1ac(%rbp)
leaq -0x1c(%rbp), %rdi
leaq -0x1ac(%rbp), %rsi
callq 0x23e40
movq %rax, -0x2a0(%rbp)
jmp 0x1fa66
movq -0x2a0(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x2b4(%rbp)
movslq -0x164(%rbp), %rsi
leaq -0xe8(%rbp), %rdi
callq 0xbde0
movq %rax, %rsi
movq -0x28(%rbp), %rdx
leaq -0x1c8(%rbp), %rdi
callq 0x23e80
jmp 0x1fa9d
movl -0x2b4(%rbp), %r8d
movl -0x2a4(%rbp), %ecx
movq -0x2b0(%rbp), %rsi
leaq -0x1a8(%rbp), %rdi
movl $0x1, %edx
leaq -0x1c8(%rbp), %r9
callq 0x1ed30
jmp 0x1facb
leaq -0x188(%rbp), %rdi
leaq -0x1a8(%rbp), %rsi
callq 0x23fb0
leaq -0x1a8(%rbp), %rdi
callq 0x5a20
leaq -0x1c8(%rbp), %rdi
callq 0x6d30
jmp 0x1fc88
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc0(%rbp)
movl %eax, -0xc4(%rbp)
jmp 0x1ff28
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc0(%rbp)
movl %eax, -0xc4(%rbp)
leaq -0x160(%rbp), %rdi
callq 0x5470
jmp 0x1ff28
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc0(%rbp)
movl %eax, -0xc4(%rbp)
jmp 0x1ff1c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc0(%rbp)
movl %eax, -0xc4(%rbp)
jmp 0x1feab
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc0(%rbp)
movl %eax, -0xc4(%rbp)
leaq -0x1c8(%rbp), %rdi
callq 0x6d30
jmp 0x1feab
movslq -0x164(%rbp), %rsi
leaq -0xe8(%rbp), %rdi
callq 0xbde0
movq %rax, -0x2d0(%rbp)
movl -0x148(%rbp), %eax
movl %eax, -0x2c4(%rbp)
movl -0xc8(%rbp), %eax
decl %eax
movl %eax, -0x1ec(%rbp)
leaq -0x1c(%rbp), %rdi
leaq -0x1ec(%rbp), %rsi
callq 0x23e40
movq %rax, -0x2c0(%rbp)
jmp 0x1fbd3
movq -0x2c0(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x2d4(%rbp)
movslq -0x164(%rbp), %rsi
leaq -0xe8(%rbp), %rdi
callq 0xbde0
movq %rax, %rsi
movq -0x28(%rbp), %rdx
leaq -0x208(%rbp), %rdi
callq 0x23e80
jmp 0x1fc0a
movl -0x2d4(%rbp), %r8d
movl -0x2c4(%rbp), %ecx
movq -0x2d0(%rbp), %rsi
leaq -0x1e8(%rbp), %rdi
movl $0x1, %edx
leaq -0x208(%rbp), %r9
callq 0x1ed30
jmp 0x1fc38
leaq -0x188(%rbp), %rdi
leaq -0x1e8(%rbp), %rsi
callq 0x23fb0
leaq -0x1e8(%rbp), %rdi
callq 0x5a20
leaq -0x208(%rbp), %rdi
callq 0x6d30
jmp 0x1fc88
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc0(%rbp)
movl %eax, -0xc4(%rbp)
leaq -0x208(%rbp), %rdi
callq 0x6d30
jmp 0x1feab
leaq -0x180(%rbp), %rdi
leaq 0x5a652(%rip), %rsi     # 0x7a2e8
callq 0x5600
movb %al, -0x2d5(%rbp)
jmp 0x1fca3
movb -0x2d5(%rbp), %al
testb $0x1, %al
jne 0x1fcaf
jmp 0x1fd17
movl -0xc8(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jg 0x1fce2
movq -0x278(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
leaq -0x60(%rbp), %rdx
callq 0x23cc0
jmp 0x1fcd3
movl $0x1, -0xcc(%rbp)
jmp 0x1fe5b
movq -0x278(%rbp), %rdi
movl $0xffffffff, -0x20c(%rbp) # imm = 0xFFFFFFFF
leaq 0x5a5ee(%rip), %rdx     # 0x7a2e8
leaq -0x20c(%rbp), %rsi
callq 0x23c40
jmp 0x1fd08
movl $0x1, -0xcc(%rbp)
jmp 0x1fe5b
leaq -0x148(%rbp), %rdi
leaq -0x188(%rbp), %rsi
callq 0x23c80
movq %rax, -0x2e0(%rbp)
jmp 0x1fd33
movq -0x2e0(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x148(%rbp)
movslq -0x164(%rbp), %rsi
leaq -0xe8(%rbp), %rdi
callq 0xbde0
movq %rax, -0x2e8(%rbp)
leaq -0x180(%rbp), %rsi
leaq -0x240(%rbp), %rdi
callq 0x56a0
jmp 0x1fd71
movq -0x2e8(%rbp), %rsi
leaq -0x228(%rbp), %rdi
leaq -0x240(%rbp), %rdx
callq 0x16aa0
jmp 0x1fd8d
leaq -0x180(%rbp), %rdi
movq %rdi, -0x300(%rbp)
leaq -0x228(%rbp), %rsi
movq %rsi, -0x308(%rbp)
callq 0x5790
movq -0x308(%rbp), %rdi
callq 0x5470
leaq -0x240(%rbp), %rdi
callq 0x5470
leaq -0x140(%rbp), %rdi
movq %rdi, -0x2f8(%rbp)
callq 0xc040
movq %rax, -0x250(%rbp)
leaq -0x248(%rbp), %rdi
leaq -0x250(%rbp), %rsi
callq 0xc070
movq -0x300(%rbp), %rdi
callq 0xc0b0
movq -0x300(%rbp), %rdi
movq %rax, -0x258(%rbp)
callq 0xc040
movq -0x2f8(%rbp), %rdi
movq %rax, -0x260(%rbp)
movq -0x248(%rbp), %rsi
movq -0x258(%rbp), %rdx
movq -0x260(%rbp), %rcx
callq 0xbf90
movq %rax, -0x2f0(%rbp)
jmp 0x1fe43
movq -0x2f0(%rbp), %rax
movq %rax, -0x268(%rbp)
movl $0x0, -0xcc(%rbp)
leaq -0x188(%rbp), %rdi
callq 0x5a20
movl -0xcc(%rbp), %eax
testl %eax, %eax
jne 0x1ff02
jmp 0x1fe77
jmp 0x1fe79
movl -0x164(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x164(%rbp)
jmp 0x1f9b6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc0(%rbp)
movl %eax, -0xc4(%rbp)
leaq -0x240(%rbp), %rdi
callq 0x5470
leaq -0x188(%rbp), %rdi
callq 0x5a20
jmp 0x1ff1c
movl -0x148(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jg 0x1fec6
jmp 0x1fee5
leaq 0x39512(%rip), %rdi     # 0x593df
leaq 0x398dc(%rip), %rsi     # 0x597b0
movl $0x8e, %edx
leaq 0x39a4e(%rip), %rcx     # 0x5992e
callq 0x31a0
movq -0x278(%rbp), %rdi
leaq -0x148(%rbp), %rsi
callq 0x23ff0
movl $0x1, -0xcc(%rbp)
leaq -0x148(%rbp), %rdi
callq 0x5a20
leaq -0xe8(%rbp), %rdi
callq 0xc120
jmp 0x1ff36
leaq -0x148(%rbp), %rdi
callq 0x5a20
leaq -0xe8(%rbp), %rdi
callq 0xc120
jmp 0x1ff4d
leaq -0xb8(%rbp), %rdi
callq 0x59e0
leaq -0x60(%rbp), %rdi
callq 0x57e0
jmp 0x1ff64
leaq -0xb8(%rbp), %rdi
callq 0x59e0
leaq -0x60(%rbp), %rdi
callq 0x57e0
jmp 0x1ff74
movq -0x270(%rbp), %rax
addq $0x310, %rsp            # imm = 0x310
popq %rbp
retq
movq -0xc0(%rbp), %rdi
callq 0x3480