// File: Laakeri[P]Triangulator/src/bayes.cpp
// Function: Bayes::SolveGraph::solveGraph(Graph const&, long, long, std::vector<long, std::allocator<long>>)
pair<int64_t, vector<pair<int, int> > > solveGraph(const Graph& G, int64_t lowerBound, int64_t upperBound, vector<int64_t> tableSizes) {
	assert(lowerBound >= 0);
	assert(lowerBound <= upperBound);
	assert((int)tableSizes.size() == G.n);
	for (int i = 0; i < G.n; i++) {
		for (int nx : G.g[i]) {
			lowerBound = max(lowerBound, tableSizes[i]*tableSizes[nx]);
		}
	}
	
	auto fill = MCS::MCS_MP(G);
	
	Graph gFill = G;
	gFill.addEdges(fill.F);
	
	int64_t fillWidth = MCS::getBayesWidth(gFill, tableSizes);
	
	assert(fillWidth >= lowerBound);
	if (fillWidth <= lowerBound) return {fillWidth, fill.F};
	
	if (fill.F.size() <= 0) {
		if (fillWidth > upperBound) return {-1, FAILSOLUTION};
		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<int64_t, vector<pair<int, int> > > sol = {0, {}};
	for (int i = 0; i < (int)atoms.size(); i++) {
		pair<int64_t, vector<pair<int, int> > > tSol;
		if (i+1 < (int)atoms.size()) {
			tSol = SolveAtom::solveAtom(atoms[i], 0, upperBound - sol.F, atoms[i].mapTableInto(tableSizes));
		}
		else {
			tSol = SolveAtom::solveAtom(atoms[i], max((int64_t)0, lowerBound - sol.F), upperBound - sol.F, atoms[i].mapTableInto(tableSizes));
		}
		if (tSol.S == FAILSOLUTION) {
			if (fillWidth <= upperBound) {
				return {fillWidth, fill.F};
			}
			else {
				return {-1, FAILSOLUTION};
			}
		}
		sol.F += tSol.F;
		if (sol.F > upperBound) return {-1, FAILSOLUTION};
		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 $0x350, %rsp            # imm = 0x350
movq %r8, -0x2c0(%rbp)
movq %rdi, -0x2b8(%rbp)
movq %rdi, %rax
movq %rax, -0x2b0(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
cmpq $0x0, -0x18(%rbp)
jl 0x93d0
jmp 0x93ef
leaq 0x4ff4b(%rip), %rdi     # 0x59322
leaq 0x4fe9e(%rip), %rsi     # 0x5927c
movl $0x33, %edx
leaq 0x4ff48(%rip), %rcx     # 0x59332
callq 0x31a0
movq -0x18(%rbp), %rax
cmpq -0x20(%rbp), %rax
jg 0x93fb
jmp 0x941a
leaq 0x4ffa6(%rip), %rdi     # 0x593a8
leaq 0x4fe73(%rip), %rsi     # 0x5927c
movl $0x34, %edx
leaq 0x4ff1d(%rip), %rcx     # 0x59332
callq 0x31a0
movq -0x2c0(%rbp), %rdi
callq 0xbb80
movq -0x10(%rbp), %rcx
cmpl 0x50(%rcx), %eax
jne 0x9431
jmp 0x9450
leaq 0x4ff89(%rip), %rdi     # 0x593c1
leaq 0x4fe3d(%rip), %rsi     # 0x5927c
movl $0x35, %edx
leaq 0x4fee7(%rip), %rcx     # 0x59332
callq 0x31a0
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x50(%rcx), %eax
jge 0x9522
movq -0x10(%rbp), %rdi
addq $0x38, %rdi
movslq -0x2c(%rbp), %rsi
callq 0xbba0
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rdi
callq 0x6680
movq %rax, -0x40(%rbp)
movq -0x38(%rbp), %rdi
callq 0x66b0
movq %rax, -0x48(%rbp)
leaq -0x40(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0xbbc0
testb $0x1, %al
jne 0x94a9
jmp 0x9512
leaq -0x40(%rbp), %rdi
callq 0xbc00
movq -0x2c0(%rbp), %rdi
movl (%rax), %eax
movl %eax, -0x4c(%rbp)
movslq -0x2c(%rbp), %rsi
callq 0xbc60
movq -0x2c0(%rbp), %rdi
movq (%rax), %rax
movq %rax, -0x2c8(%rbp)
movslq -0x4c(%rbp), %rsi
callq 0xbc60
movq %rax, %rcx
movq -0x2c8(%rbp), %rax
imulq (%rcx), %rax
movq %rax, -0x58(%rbp)
leaq -0x18(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0xbc20
movq (%rax), %rax
movq %rax, -0x18(%rbp)
leaq -0x40(%rbp), %rdi
callq 0xbc80
jmp 0x9496
jmp 0x9514
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x9457
movq -0x10(%rbp), %rsi
leaq -0x88(%rbp), %rdi
callq 0x28a90
movq -0x10(%rbp), %rsi
leaq -0xe0(%rbp), %rdi
callq 0xb8b0
jmp 0x9544
leaq -0xe0(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x15db0
jmp 0x9559
movq -0x2c0(%rbp), %rsi
leaq -0xe0(%rbp), %rdi
callq 0x2a2a0
movq %rax, -0x2d0(%rbp)
jmp 0x9575
movq -0x2d0(%rbp), %rax
movq %rax, -0xf8(%rbp)
movq -0xf8(%rbp), %rax
cmpq -0x18(%rbp), %rax
jl 0x9592
jmp 0x95df
leaq 0x4fccb(%rip), %rdi     # 0x59264
leaq 0x4fcdc(%rip), %rsi     # 0x5927c
movl $0x43, %edx
leaq 0x4fd86(%rip), %rcx     # 0x59332
callq 0x31a0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
jmp 0x9d57
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
jmp 0x9d4b
movq -0xf8(%rbp), %rax
cmpq -0x18(%rbp), %rax
jg 0x9617
movq -0x2b8(%rbp), %rdi
leaq -0xf8(%rbp), %rsi
leaq -0x88(%rbp), %rdx
callq 0xb9b0
jmp 0x9608
movl $0x1, -0xfc(%rbp)
jmp 0x9d23
leaq -0x88(%rbp), %rdi
callq 0x5680
cmpq $0x0, %rax
ja 0x9696
movq -0xf8(%rbp), %rax
cmpq -0x20(%rbp), %rax
jle 0x966b
movq -0x2b8(%rbp), %rdi
movl $0xffffffff, -0x100(%rbp) # imm = 0xFFFFFFFF
leaq 0x70c7a(%rip), %rdx     # 0x7a2c8
leaq -0x100(%rbp), %rsi
callq 0xb970
jmp 0x965c
movl $0x1, -0xfc(%rbp)
jmp 0x9d23
movq -0x2b8(%rbp), %rdi
leaq -0xf8(%rbp), %rsi
leaq -0x88(%rbp), %rdx
callq 0xb9b0
jmp 0x9687
movl $0x1, -0xfc(%rbp)
jmp 0x9d23
movq -0x10(%rbp), %rsi
leaq -0x138(%rbp), %rdi
leaq -0xe0(%rbp), %rdx
leaq -0x88(%rbp), %rcx
callq 0x292b0
jmp 0x96b6
leaq -0x130(%rbp), %rsi
leaq -0x118(%rbp), %rdi
movq %rdi, -0x2d8(%rbp)
callq 0xbca0
leaq -0x138(%rbp), %rdi
callq 0xbcd0
movq -0x2d8(%rbp), %rdi
callq 0xbcf0
movq -0x2d8(%rbp), %rdi
movq %rax, -0x148(%rbp)
callq 0xbd20
movq %rax, -0x150(%rbp)
movq -0x148(%rbp), %rdi
movq -0x150(%rbp), %rsi
callq 0x9d70
jmp 0x9717
movl $0x0, -0x17c(%rbp)
xorps %xmm0, %xmm0
movaps %xmm0, -0x1a0(%rbp)
movq $0x0, -0x190(%rbp)
leaq -0x1a0(%rbp), %rdi
movq %rdi, -0x2e0(%rbp)
callq 0xbd50
movq -0x2e0(%rbp), %rdx
leaq -0x178(%rbp), %rdi
leaq -0x17c(%rbp), %rsi
callq 0xb970
jmp 0x9765
leaq -0x1a0(%rbp), %rdi
callq 0x5470
movl $0x0, -0x1a4(%rbp)
movl -0x1a4(%rbp), %eax
movl %eax, -0x2e4(%rbp)
leaq -0x118(%rbp), %rdi
callq 0xbd70
movq %rax, %rcx
movl -0x2e4(%rbp), %eax
cmpl %ecx, %eax
jge 0x9ca4
leaq -0x1c8(%rbp), %rdi
callq 0xbda0
jmp 0x97b2
movl -0x1a4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2e8(%rbp)
leaq -0x118(%rbp), %rdi
callq 0xbd70
movq %rax, %rcx
movl -0x2e8(%rbp), %eax
cmpl %ecx, %eax
jge 0x9921
movslq -0x1a4(%rbp), %rsi
leaq -0x118(%rbp), %rdi
movq %rdi, -0x300(%rbp)
callq 0xbde0
movq -0x300(%rbp), %rdi
movq %rax, -0x2f8(%rbp)
movq -0x20(%rbp), %rax
movq -0x178(%rbp), %rcx
subq %rcx, %rax
movq %rax, -0x2f0(%rbp)
movslq -0x1a4(%rbp), %rsi
callq 0xbde0
movq -0x2c0(%rbp), %rdx
movq %rax, %rsi
leaq -0x200(%rbp), %rdi
callq 0xbe00
jmp 0x983f
movq -0x2f0(%rbp), %rcx
movq -0x2f8(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
leaq -0x1e8(%rbp), %rdi
leaq -0x200(%rbp), %r8
callq 0x8f70
jmp 0x9866
leaq -0x1c8(%rbp), %rdi
leaq -0x1e8(%rbp), %rsi
callq 0xbf30
leaq -0x1e8(%rbp), %rdi
callq 0xbf70
leaq -0x200(%rbp), %rdi
callq 0xbae0
jmp 0x9a42
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
jmp 0x9d15
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
leaq -0x1a0(%rbp), %rdi
callq 0x5470
jmp 0x9d15
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
jmp 0x9d09
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
jmp 0x9c96
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
leaq -0x200(%rbp), %rdi
callq 0xbae0
jmp 0x9c96
movslq -0x1a4(%rbp), %rsi
leaq -0x118(%rbp), %rdi
callq 0xbde0
movq %rax, -0x310(%rbp)
movq $0x0, -0x228(%rbp)
movq -0x18(%rbp), %rax
movq -0x178(%rbp), %rcx
subq %rcx, %rax
movq %rax, -0x230(%rbp)
leaq -0x228(%rbp), %rdi
leaq -0x230(%rbp), %rsi
callq 0xbc20
movq %rax, -0x308(%rbp)
jmp 0x9977
movq -0x308(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x320(%rbp)
movq -0x20(%rbp), %rax
movq -0x178(%rbp), %rcx
subq %rcx, %rax
movq %rax, -0x318(%rbp)
movslq -0x1a4(%rbp), %rsi
leaq -0x118(%rbp), %rdi
callq 0xbde0
movq -0x2c0(%rbp), %rdx
movq %rax, %rsi
leaq -0x248(%rbp), %rdi
callq 0xbe00
jmp 0x99c8
movq -0x318(%rbp), %rcx
movq -0x320(%rbp), %rdx
movq -0x310(%rbp), %rsi
leaq -0x220(%rbp), %rdi
leaq -0x248(%rbp), %r8
callq 0x8f70
jmp 0x99f2
leaq -0x1c8(%rbp), %rdi
leaq -0x220(%rbp), %rsi
callq 0xbf30
leaq -0x220(%rbp), %rdi
callq 0xbf70
leaq -0x248(%rbp), %rdi
callq 0xbae0
jmp 0x9a42
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
leaq -0x248(%rbp), %rdi
callq 0xbae0
jmp 0x9c96
leaq -0x1c0(%rbp), %rdi
leaq 0x70878(%rip), %rsi     # 0x7a2c8
callq 0x5600
movb %al, -0x321(%rbp)
jmp 0x9a5d
movb -0x321(%rbp), %al
testb $0x1, %al
jne 0x9a69
jmp 0x9ad6
movq -0xf8(%rbp), %rax
cmpq -0x20(%rbp), %rax
jg 0x9aa1
movq -0x2b8(%rbp), %rdi
leaq -0xf8(%rbp), %rsi
leaq -0x88(%rbp), %rdx
callq 0xb9b0
jmp 0x9a92
movl $0x1, -0xfc(%rbp)
jmp 0x9c46
movq -0x2b8(%rbp), %rdi
movl $0xffffffff, -0x24c(%rbp) # imm = 0xFFFFFFFF
leaq 0x7080f(%rip), %rdx     # 0x7a2c8
leaq -0x24c(%rbp), %rsi
callq 0xb970
jmp 0x9ac7
movl $0x1, -0xfc(%rbp)
jmp 0x9c46
movq -0x1c8(%rbp), %rax
addq -0x178(%rbp), %rax
movq %rax, -0x178(%rbp)
movq -0x178(%rbp), %rax
cmpq -0x20(%rbp), %rax
jle 0x9b2d
movq -0x2b8(%rbp), %rdi
movl $0xffffffff, -0x250(%rbp) # imm = 0xFFFFFFFF
leaq 0x707b8(%rip), %rdx     # 0x7a2c8
leaq -0x250(%rbp), %rsi
callq 0xb970
jmp 0x9b1e
movl $0x1, -0xfc(%rbp)
jmp 0x9c46
movslq -0x1a4(%rbp), %rsi
leaq -0x118(%rbp), %rdi
callq 0xbde0
movq %rax, -0x330(%rbp)
leaq -0x1c0(%rbp), %rsi
leaq -0x280(%rbp), %rdi
callq 0x56a0
jmp 0x9b5c
movq -0x330(%rbp), %rsi
leaq -0x268(%rbp), %rdi
leaq -0x280(%rbp), %rdx
callq 0x16aa0
jmp 0x9b78
leaq -0x1c0(%rbp), %rdi
movq %rdi, -0x348(%rbp)
leaq -0x268(%rbp), %rsi
movq %rsi, -0x350(%rbp)
callq 0x5790
movq -0x350(%rbp), %rdi
callq 0x5470
leaq -0x280(%rbp), %rdi
callq 0x5470
leaq -0x170(%rbp), %rdi
movq %rdi, -0x340(%rbp)
callq 0xc040
movq %rax, -0x290(%rbp)
leaq -0x288(%rbp), %rdi
leaq -0x290(%rbp), %rsi
callq 0xc070
movq -0x348(%rbp), %rdi
callq 0xc0b0
movq -0x348(%rbp), %rdi
movq %rax, -0x298(%rbp)
callq 0xc040
movq -0x340(%rbp), %rdi
movq %rax, -0x2a0(%rbp)
movq -0x288(%rbp), %rsi
movq -0x298(%rbp), %rdx
movq -0x2a0(%rbp), %rcx
callq 0xbf90
movq %rax, -0x338(%rbp)
jmp 0x9c2e
movq -0x338(%rbp), %rax
movq %rax, -0x2a8(%rbp)
movl $0x0, -0xfc(%rbp)
leaq -0x1c8(%rbp), %rdi
callq 0xbf70
movl -0xfc(%rbp), %eax
testl %eax, %eax
jne 0x9cef
jmp 0x9c62
jmp 0x9c64
movl -0x1a4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1a4(%rbp)
jmp 0x977b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
leaq -0x280(%rbp), %rdi
callq 0x5470
leaq -0x1c8(%rbp), %rdi
callq 0xbf70
jmp 0x9d09
movq -0x178(%rbp), %rax
cmpq -0x20(%rbp), %rax
jg 0x9cb3
jmp 0x9cd2
leaq 0x4f725(%rip), %rdi     # 0x593df
leaq 0x4f5bb(%rip), %rsi     # 0x5927c
movl $0x66, %edx
leaq 0x4f665(%rip), %rcx     # 0x59332
callq 0x31a0
movq -0x2b8(%rbp), %rdi
leaq -0x178(%rbp), %rsi
callq 0xc0e0
movl $0x1, -0xfc(%rbp)
leaq -0x178(%rbp), %rdi
callq 0xbf70
leaq -0x118(%rbp), %rdi
callq 0xc120
jmp 0x9d23
leaq -0x178(%rbp), %rdi
callq 0xbf70
leaq -0x118(%rbp), %rdi
callq 0xc120
jmp 0x9d4b
leaq -0xe0(%rbp), %rdi
callq 0x59e0
leaq -0x88(%rbp), %rdi
callq 0x57e0
movq -0x2b0(%rbp), %rax
addq $0x350, %rsp            # imm = 0x350
popq %rbp
retq
leaq -0xe0(%rbp), %rdi
callq 0x59e0
leaq -0x88(%rbp), %rdi
callq 0x57e0
movq -0xe8(%rbp), %rdi
callq 0x3480
nop