// File: nilnilnil[P]autocomplete/./include/suggest.hpp
// Function: suggest(PhraseMap&, SegmentTree&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, unsigned int)
vp_t
suggest(PhraseMap &pm, RMQ &st, std::string prefix, uint_t n = 16) {
    pvpi_t phrases = pm.query(prefix);
    // cerr<<"Got "<<phrases.second - phrases.first<<" candidate phrases from PhraseMap"<<endl;

    uint_t first = phrases.first  - pm.repr.begin();
    uint_t last  = phrases.second - pm.repr.begin();

    if (first == last) {
        return vp_t();
    }

    vp_t ret;
    --last;

    pqpr_t heap;
    pui_t best = st.query_max(first, last);
    heap.push(PhraseRange(first, last, best.first, best.second));

    while (ret.size() < n && !heap.empty()) {
        PhraseRange pr = heap.top();
        heap.pop();
        // cerr<<"Top phrase is at index: "<<pr.index<<endl;
        // cerr<<"And is: "<<pm.repr[pr.index].first<<endl;

        ret.push_back(pm.repr[pr.index]);

        uint_t lower = pr.first;
        uint_t upper = pr.index - 1;

        // Prevent underflow
        if (pr.index - 1 < pr.index && lower <= upper) {
            // cerr<<"[1] adding to heap: "<<lower<<", "<<upper<<", "<<best.first<<", "<<best.second<<endl;

            best = st.query_max(lower, upper);
            heap.push(PhraseRange(lower, upper, best.first, best.second));
        }

        lower = pr.index + 1;
        upper = pr.last;

        // Prevent overflow
        if (pr.index + 1 > pr.index && lower <= upper) {
            // cerr<<"[2] adding to heap: "<<lower<<", "<<upper<<", "<<best.first<<", "<<best.second<<endl;

            best = st.query_max(lower, upper);
            heap.push(PhraseRange(lower, upper, best.first, best.second));
        }
    }

    return ret;
}

// Assembly:
subq $0x148, %rsp            # imm = 0x148
movq %rcx, 0x30(%rsp)
movq %rsi, %rax
movq 0x30(%rsp), %rsi
movq %rdi, 0x38(%rsp)
movq %rdi, %rcx
movq %rcx, 0x40(%rsp)
movq %rdi, 0x140(%rsp)
movq %rax, 0x138(%rsp)
movq %rdx, 0x130(%rsp)
movq %rsi, 0x128(%rsp)
movl %r8d, 0x124(%rsp)
movq 0x138(%rsp), %rdi
callq 0xdc40
movq %rax, 0x110(%rsp)
movq %rdx, 0x118(%rsp)
leaq 0x110(%rsp), %rax
movq %rax, 0x48(%rsp)
movq 0x138(%rsp), %rdi
callq 0xda50
movq 0x48(%rsp), %rdi
movq %rax, 0x100(%rsp)
leaq 0x100(%rsp), %rsi
callq 0xdca0
movl %eax, 0x10c(%rsp)
leaq 0x110(%rsp), %rax
addq $0x8, %rax
movq %rax, 0x50(%rsp)
movq 0x138(%rsp), %rdi
callq 0xda50
movq 0x50(%rsp), %rdi
movq %rax, 0xf0(%rsp)
leaq 0xf0(%rsp), %rsi
callq 0xdca0
movl %eax, 0xfc(%rsp)
movl 0x10c(%rsp), %eax
cmpl 0xfc(%rsp), %eax
jne 0x7870
movq 0x38(%rsp), %rdi
xorl %esi, %esi
movl $0x18, %edx
callq 0x52a0
movq 0x38(%rsp), %rdi
callq 0xdf20
jmp 0x7bc3
movq 0x38(%rsp), %rdi
movb $0x0, 0xef(%rsp)
callq 0xdf20
movl 0xfc(%rsp), %eax
decl %eax
movl %eax, 0xfc(%rsp)
leaq 0xc8(%rsp), %rdi
callq 0xdf30
jmp 0x78a1
movq 0x130(%rsp), %rdi
movl 0x10c(%rsp), %esi
movl 0xfc(%rsp), %edx
callq 0xd500
movq %rax, 0x28(%rsp)
jmp 0x78c3
movq 0x28(%rsp), %rax
movq %rax, 0xb4(%rsp)
movl 0x10c(%rsp), %esi
movl 0xfc(%rsp), %edx
movl 0xb4(%rsp), %ecx
movl 0xb8(%rsp), %r8d
leaq 0xa4(%rsp), %rdi
callq 0xdfc0
jmp 0x78fc
leaq 0xc8(%rsp), %rdi
leaq 0xa4(%rsp), %rsi
callq 0xdf60
jmp 0x7913
jmp 0x7915
movq 0x38(%rsp), %rdi
callq 0xe000
movq %rax, %rcx
movl 0x124(%rsp), %eax
movl %eax, %edx
xorl %eax, %eax
cmpq %rdx, %rcx
movb %al, 0x27(%rsp)
jae 0x7953
leaq 0xc8(%rsp), %rdi
callq 0xe020
movb %al, 0x26(%rsp)
jmp 0x7949
movb 0x26(%rsp), %al
xorb $-0x1, %al
movb %al, 0x27(%rsp)
movb 0x27(%rsp), %al
testb $0x1, %al
jne 0x7960
jmp 0x7b8c
leaq 0xc8(%rsp), %rdi
callq 0xe040
movq %rax, 0x18(%rsp)
jmp 0x7974
movq 0x18(%rsp), %rax
movups (%rax), %xmm0
movaps %xmm0, 0x90(%rsp)
leaq 0xc8(%rsp), %rdi
callq 0xe050
jmp 0x7993
movq 0x138(%rsp), %rdi
movl 0x9c(%rsp), %eax
movl %eax, %esi
callq 0xe110
movq 0x38(%rsp), %rdi
movq %rax, %rsi
callq 0xe0a0
jmp 0x79b8
movl 0x90(%rsp), %eax
movl %eax, 0x8c(%rsp)
movl 0x9c(%rsp), %eax
subl $0x1, %eax
movl %eax, 0x88(%rsp)
movl 0x9c(%rsp), %eax
subl $0x1, %eax
cmpl 0x9c(%rsp), %eax
jae 0x7ac4
movl 0x8c(%rsp), %eax
cmpl 0x88(%rsp), %eax
ja 0x7ac4
movq 0x130(%rsp), %rdi
movl 0x8c(%rsp), %esi
movl 0x88(%rsp), %edx
callq 0xd500
movq %rax, 0x10(%rsp)
jmp 0x7a24
movq 0x10(%rsp), %rax
movq %rax, 0x80(%rsp)
leaq 0xb4(%rsp), %rdi
leaq 0x80(%rsp), %rsi
callq 0xe130
movl 0x8c(%rsp), %esi
movl 0x88(%rsp), %edx
movl 0xb4(%rsp), %ecx
movl 0xb8(%rsp), %r8d
leaq 0x70(%rsp), %rdi
callq 0xdfc0
jmp 0x7a6f
leaq 0xc8(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0xdf60
jmp 0x7a83
jmp 0x7ac4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xc0(%rsp)
movl %eax, 0xbc(%rsp)
jmp 0x7bb7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xc0(%rsp)
movl %eax, 0xbc(%rsp)
leaq 0xc8(%rsp), %rdi
callq 0xe160
jmp 0x7bb7
movl 0x9c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x8c(%rsp)
movl 0x94(%rsp), %eax
movl %eax, 0x88(%rsp)
movl 0x9c(%rsp), %eax
addl $0x1, %eax
cmpl 0x9c(%rsp), %eax
jbe 0x7b87
movl 0x8c(%rsp), %eax
cmpl 0x88(%rsp), %eax
ja 0x7b87
movq 0x130(%rsp), %rdi
movl 0x8c(%rsp), %esi
movl 0x88(%rsp), %edx
callq 0xd500
movq %rax, 0x8(%rsp)
jmp 0x7b2c
movq 0x8(%rsp), %rax
movq %rax, 0x68(%rsp)
leaq 0xb4(%rsp), %rdi
leaq 0x68(%rsp), %rsi
callq 0xe130
movl 0x8c(%rsp), %esi
movl 0x88(%rsp), %edx
movl 0xb4(%rsp), %ecx
movl 0xb8(%rsp), %r8d
leaq 0x58(%rsp), %rdi
callq 0xdfc0
jmp 0x7b71
leaq 0xc8(%rsp), %rdi
leaq 0x58(%rsp), %rsi
callq 0xdf60
jmp 0x7b85
jmp 0x7b87
jmp 0x7915
movb $0x1, 0xef(%rsp)
leaq 0xc8(%rsp), %rdi
callq 0xe160
testb $0x1, 0xef(%rsp)
jne 0x7bb5
movq 0x38(%rsp), %rdi
callq 0xe170
jmp 0x7bc3
movq 0x38(%rsp), %rdi
callq 0xe170
jmp 0x7bd0
movq 0x40(%rsp), %rax
addq $0x148, %rsp            # imm = 0x148
retq
movq 0xc0(%rsp), %rdi
callq 0x5a40
nopl (%rax)