// File: Laakeri[P]Triangulator/src/treewidth.cpp
// Function: TreeWidth::SolveGraph::solveGraph(Graph const&, int, int, int)
pair<int, vector<pair<int, int> > > solveGraph(const Graph& G, int lowerBound, int okWidth, int upperBound) {
	assert(lowerBound >= 0);
	assert(okWidth <= upperBound);
	if (G.hasCycle()) {
		lowerBound = max(lowerBound, 2);
	}
	else {
		upperBound = min(upperBound, 1);
	}
	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::getTreeWidth(gFill);
	assert(fillWidth >= lowerBound);
	if (fillWidth <= okWidth) return {fillWidth, fill.F};
	
	if (fill.F.size() <= 1) {
		if (fillWidth > upperBound) return {-1, FAILSOLUTION};
		return {fillWidth, fill.F};
	}
	
	vector<Graph> atoms;
	int maxCliqueSeparator;
	tie(maxCliqueSeparator, atoms) = MCS::getAtoms(G, gFill, fill);
	lowerBound = max(lowerBound, maxCliqueSeparator-1);
	if (lowerBound > upperBound) return {-1, FAILSOLUTION};
	okWidth = max(okWidth, lowerBound);
	if (fillWidth <= okWidth) return {fillWidth, fill.F};
	
	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::solveAtom0(atoms[i], 0, sol.F, min(upperBound, fillWidth-1));
		}
		else {
			tSol = SolveAtom::solveAtom0(atoms[i], 0, sol.F, min(upperBound, fillWidth-1));
		}
		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, -0x260(%rbp)
movq %rdi, %rax
movq %rax, -0x258(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movl %ecx, -0x18(%rbp)
movl %r8d, -0x1c(%rbp)
cmpl $0x0, -0x14(%rbp)
jl 0x56ce6
jmp 0x56d05
leaq 0x2635(%rip), %rdi      # 0x59322
leaq 0x460c(%rip), %rsi      # 0x5b300
movl $0xa3, %edx
leaq 0x4759(%rip), %rcx      # 0x5b459
callq 0x31a0
movl -0x18(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jg 0x56d0f
jmp 0x56d2e
leaq 0x2b15(%rip), %rdi      # 0x5982b
leaq 0x45e3(%rip), %rsi      # 0x5b300
movl $0xa4, %edx
leaq 0x4730(%rip), %rcx      # 0x5b459
callq 0x31a0
movq -0x10(%rbp), %rdi
callq 0x16f10
testb $0x1, %al
jne 0x56d3d
jmp 0x56d58
movl $0x2, -0x20(%rbp)
leaq -0x14(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x23c80
movl (%rax), %eax
movl %eax, -0x14(%rbp)
jmp 0x56d71
movl $0x1, -0x24(%rbp)
leaq -0x1c(%rbp), %rdi
leaq -0x24(%rbp), %rsi
callq 0x23e40
movl (%rax), %eax
movl %eax, -0x1c(%rbp)
movl -0x14(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jle 0x56d9c
movq -0x260(%rbp), %rdi
movl $0xffffffff, -0x28(%rbp) # imm = 0xFFFFFFFF
leaq -0x28(%rbp), %rsi
leaq 0xc27a0e(%rip), %rdx    # 0xc7e7a0
callq 0x23c40
jmp 0x575a7
leaq -0x18(%rbp), %rdi
leaq -0x14(%rbp), %rsi
callq 0x23c80
movl (%rax), %eax
movl %eax, -0x18(%rbp)
movq -0x10(%rbp), %rsi
leaq -0x58(%rbp), %rdi
callq 0x28a90
movq -0x10(%rbp), %rsi
leaq -0xb0(%rbp), %rdi
callq 0xb8b0
jmp 0x56dcd
leaq -0xb0(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x15db0
jmp 0x56ddf
leaq -0xb0(%rbp), %rdi
callq 0x29da0
movl %eax, -0x264(%rbp)
jmp 0x56df3
movl -0x264(%rbp), %eax
movl %eax, -0xc0(%rbp)
movl -0xc0(%rbp), %eax
cmpl -0x14(%rbp), %eax
jl 0x56e0c
jmp 0x56e59
leaq 0x2451(%rip), %rdi      # 0x59264
leaq 0x44e6(%rip), %rsi      # 0x5b300
movl $0xb4, %edx
leaq 0x4633(%rip), %rcx      # 0x5b459
callq 0x31a0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb8(%rbp)
movl %eax, -0xbc(%rbp)
jmp 0x5759c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb8(%rbp)
movl %eax, -0xbc(%rbp)
jmp 0x57590
movl -0xc0(%rbp), %eax
cmpl -0x18(%rbp), %eax
jg 0x56e8c
movq -0x260(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
leaq -0x58(%rbp), %rdx
callq 0x23cc0
jmp 0x56e7d
movl $0x1, -0xc4(%rbp)
jmp 0x57579
leaq -0x58(%rbp), %rdi
callq 0x5680
cmpq $0x1, %rax
ja 0x56f03
movl -0xc0(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jle 0x56edb
movq -0x260(%rbp), %rdi
movl $0xffffffff, -0xc8(%rbp) # imm = 0xFFFFFFFF
leaq 0xc278e2(%rip), %rdx    # 0xc7e7a0
leaq -0xc8(%rbp), %rsi
callq 0x23c40
jmp 0x56ecc
movl $0x1, -0xc4(%rbp)
jmp 0x57579
movq -0x260(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
leaq -0x58(%rbp), %rdx
callq 0x23cc0
jmp 0x56ef4
movl $0x1, -0xc4(%rbp)
jmp 0x57579
leaq -0xe0(%rbp), %rdi
callq 0x2dd10
movq -0x10(%rbp), %rsi
leaq -0x108(%rbp), %rdi
leaq -0xb0(%rbp), %rdx
leaq -0x58(%rbp), %rcx
callq 0x292b0
jmp 0x56f2c
leaq -0x118(%rbp), %rdi
movq %rdi, -0x280(%rbp)
leaq -0xe4(%rbp), %rsi
leaq -0xe0(%rbp), %rdx
callq 0x58810
movq -0x280(%rbp), %rdi
leaq -0x108(%rbp), %rsi
movq %rsi, -0x278(%rbp)
callq 0x58850
movq -0x278(%rbp), %rdi
callq 0xbcd0
movl -0xe4(%rbp), %eax
decl %eax
movl %eax, -0x11c(%rbp)
leaq -0x14(%rbp), %rdi
leaq -0x11c(%rbp), %rsi
callq 0x23c80
movq %rax, -0x270(%rbp)
jmp 0x56f9a
movq -0x270(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jle 0x56ffa
movq -0x260(%rbp), %rdi
movl $0xffffffff, -0x120(%rbp) # imm = 0xFFFFFFFF
leaq 0xc277da(%rip), %rdx    # 0xc7e7a0
leaq -0x120(%rbp), %rsi
callq 0x23c40
jmp 0x56fd4
movl $0x1, -0xc4(%rbp)
jmp 0x5755d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb8(%rbp)
movl %eax, -0xbc(%rbp)
jmp 0x5756b
leaq -0x18(%rbp), %rdi
leaq -0x14(%rbp), %rsi
callq 0x23c80
movq %rax, -0x288(%rbp)
jmp 0x57010
movq -0x288(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x18(%rbp)
movl -0xc0(%rbp), %eax
cmpl -0x18(%rbp), %eax
jg 0x5704f
movq -0x260(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
leaq -0x58(%rbp), %rdx
callq 0x23cc0
jmp 0x57040
movl $0x1, -0xc4(%rbp)
jmp 0x5755d
leaq -0xe0(%rbp), %rdi
movq %rdi, -0x290(%rbp)
callq 0xbcf0
movq -0x290(%rbp), %rdi
movq %rax, -0x130(%rbp)
callq 0xbd20
movq %rax, -0x138(%rbp)
movq -0x130(%rbp), %rdi
movq -0x138(%rbp), %rsi
callq 0x575d0
jmp 0x57091
xorps %xmm0, %xmm0
movaps %xmm0, -0x180(%rbp)
movq $0x0, -0x170(%rbp)
leaq -0x180(%rbp), %rdi
movq %rdi, -0x298(%rbp)
callq 0xbd50
movq -0x298(%rbp), %rdx
leaq -0x160(%rbp), %rdi
leaq -0x14(%rbp), %rsi
callq 0x23dc0
jmp 0x570d2
leaq -0x180(%rbp), %rdi
callq 0x5470
movl $0x0, -0x184(%rbp)
movl -0x184(%rbp), %eax
movl %eax, -0x29c(%rbp)
leaq -0xe0(%rbp), %rdi
callq 0xbd70
movq %rax, %rcx
movl -0x29c(%rbp), %eax
cmpl %ecx, %eax
jge 0x574f8
leaq -0x1a8(%rbp), %rdi
callq 0x23e00
jmp 0x5711f
movl -0x184(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2a0(%rbp)
leaq -0xe0(%rbp), %rdi
callq 0xbd70
movq %rax, %rcx
movl -0x2a0(%rbp), %eax
cmpl %ecx, %eax
jge 0x57234
movslq -0x184(%rbp), %rsi
leaq -0xe0(%rbp), %rdi
callq 0xbde0
movq %rax, -0x2b8(%rbp)
movl -0x160(%rbp), %eax
movl %eax, -0x2ac(%rbp)
movl -0xc0(%rbp), %eax
decl %eax
movl %eax, -0x1cc(%rbp)
leaq -0x1c(%rbp), %rdi
leaq -0x1cc(%rbp), %rsi
callq 0x23e40
movq %rax, -0x2a8(%rbp)
jmp 0x57198
movl -0x2ac(%rbp), %ecx
movq -0x2b8(%rbp), %rsi
movq -0x2a8(%rbp), %rax
movl (%rax), %r8d
leaq -0x1c8(%rbp), %rdi
xorl %edx, %edx
callq 0x56570
jmp 0x571bf
leaq -0x1a8(%rbp), %rdi
leaq -0x1c8(%rbp), %rsi
callq 0x23fb0
leaq -0x1c8(%rbp), %rdi
callq 0x5a20
jmp 0x572c7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb8(%rbp)
movl %eax, -0xbc(%rbp)
leaq -0x180(%rbp), %rdi
callq 0x5470
jmp 0x5756b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb8(%rbp)
movl %eax, -0xbc(%rbp)
jmp 0x5754f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb8(%rbp)
movl %eax, -0xbc(%rbp)
jmp 0x574ea
movslq -0x184(%rbp), %rsi
leaq -0xe0(%rbp), %rdi
callq 0xbde0
movq %rax, -0x2d0(%rbp)
movl -0x160(%rbp), %eax
movl %eax, -0x2c4(%rbp)
movl -0xc0(%rbp), %eax
decl %eax
movl %eax, -0x1f4(%rbp)
leaq -0x1c(%rbp), %rdi
leaq -0x1f4(%rbp), %rsi
callq 0x23e40
movq %rax, -0x2c0(%rbp)
jmp 0x57281
movl -0x2c4(%rbp), %ecx
movq -0x2d0(%rbp), %rsi
movq -0x2c0(%rbp), %rax
movl (%rax), %r8d
leaq -0x1f0(%rbp), %rdi
xorl %edx, %edx
callq 0x56570
jmp 0x572a8
leaq -0x1a8(%rbp), %rdi
leaq -0x1f0(%rbp), %rsi
callq 0x23fb0
leaq -0x1f0(%rbp), %rdi
callq 0x5a20
leaq -0x1a0(%rbp), %rdi
leaq 0xc274cb(%rip), %rsi    # 0xc7e7a0
callq 0x5600
movb %al, -0x2d1(%rbp)
jmp 0x572e2
movb -0x2d1(%rbp), %al
testb $0x1, %al
jne 0x572ee
jmp 0x57356
movl -0xc0(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jg 0x57321
movq -0x260(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
leaq -0x58(%rbp), %rdx
callq 0x23cc0
jmp 0x57312
movl $0x1, -0xc4(%rbp)
jmp 0x5749a
movq -0x260(%rbp), %rdi
movl $0xffffffff, -0x1f8(%rbp) # imm = 0xFFFFFFFF
leaq 0xc27467(%rip), %rdx    # 0xc7e7a0
leaq -0x1f8(%rbp), %rsi
callq 0x23c40
jmp 0x57347
movl $0x1, -0xc4(%rbp)
jmp 0x5749a
leaq -0x160(%rbp), %rdi
leaq -0x1a8(%rbp), %rsi
callq 0x23c80
movq %rax, -0x2e0(%rbp)
jmp 0x57372
movq -0x2e0(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x160(%rbp)
movslq -0x184(%rbp), %rsi
leaq -0xe0(%rbp), %rdi
callq 0xbde0
movq %rax, -0x2e8(%rbp)
leaq -0x1a0(%rbp), %rsi
leaq -0x228(%rbp), %rdi
callq 0x56a0
jmp 0x573b0
movq -0x2e8(%rbp), %rsi
leaq -0x210(%rbp), %rdi
leaq -0x228(%rbp), %rdx
callq 0x16aa0
jmp 0x573cc
leaq -0x1a0(%rbp), %rdi
movq %rdi, -0x300(%rbp)
leaq -0x210(%rbp), %rsi
movq %rsi, -0x308(%rbp)
callq 0x5790
movq -0x308(%rbp), %rdi
callq 0x5470
leaq -0x228(%rbp), %rdi
callq 0x5470
leaq -0x158(%rbp), %rdi
movq %rdi, -0x2f8(%rbp)
callq 0xc040
movq %rax, -0x238(%rbp)
leaq -0x230(%rbp), %rdi
leaq -0x238(%rbp), %rsi
callq 0xc070
movq -0x300(%rbp), %rdi
callq 0xc0b0
movq -0x300(%rbp), %rdi
movq %rax, -0x240(%rbp)
callq 0xc040
movq -0x2f8(%rbp), %rdi
movq %rax, -0x248(%rbp)
movq -0x230(%rbp), %rsi
movq -0x240(%rbp), %rdx
movq -0x248(%rbp), %rcx
callq 0xbf90
movq %rax, -0x2f0(%rbp)
jmp 0x57482
movq -0x2f0(%rbp), %rax
movq %rax, -0x250(%rbp)
movl $0x0, -0xc4(%rbp)
leaq -0x1a8(%rbp), %rdi
callq 0x5a20
movl -0xc4(%rbp), %eax
testl %eax, %eax
jne 0x57541
jmp 0x574b6
jmp 0x574b8
movl -0x184(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x184(%rbp)
jmp 0x570e8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb8(%rbp)
movl %eax, -0xbc(%rbp)
leaq -0x228(%rbp), %rdi
callq 0x5470
leaq -0x1a8(%rbp), %rdi
callq 0x5a20
jmp 0x5754f
movl -0x160(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jg 0x57505
jmp 0x57524
leaq 0x1ed3(%rip), %rdi      # 0x593df
leaq 0x3ded(%rip), %rsi      # 0x5b300
movl $0xdd, %edx
leaq 0x3f3a(%rip), %rcx      # 0x5b459
callq 0x31a0
movq -0x260(%rbp), %rdi
leaq -0x160(%rbp), %rsi
callq 0x23ff0
movl $0x1, -0xc4(%rbp)
leaq -0x160(%rbp), %rdi
callq 0x5a20
jmp 0x5755d
leaq -0x160(%rbp), %rdi
callq 0x5a20
jmp 0x5756b
leaq -0xe0(%rbp), %rdi
callq 0xc120
jmp 0x57579
leaq -0xe0(%rbp), %rdi
callq 0xc120
jmp 0x57590
leaq -0xb0(%rbp), %rdi
callq 0x59e0
leaq -0x58(%rbp), %rdi
callq 0x57e0
jmp 0x575a7
leaq -0xb0(%rbp), %rdi
callq 0x59e0
leaq -0x58(%rbp), %rdi
callq 0x57e0
jmp 0x575b7
movq -0x258(%rbp), %rax
addq $0x310, %rsp            # imm = 0x310
popq %rbp
retq
movq -0xb8(%rbp), %rdi
callq 0x3480
nopw %cs:(%rax,%rax)