// File: s-yata[P]louds-patricia/louds-patricia.cpp
// Function: louds::PatriciaImpl::lookup(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&) const
int64_t lookup(const string &query) const {
    uint64_t node_id = 0;
    for (uint64_t i = 0; i < query.length(); ++i) {
      uint64_t node_pos = louds_.select(node_id) + 1;

      uint64_t end = node_pos;
      uint64_t word = louds_.words[end / 64] >> (end % 64);
      if (word == 0) {
        end += 64 - (end % 64);
        word = louds_.words[end / 64];
        while (word == 0) {
          end += 64;
          word = louds_.words[end / 64];
        }
      }
      end += Ctz(word);
      uint64_t begin = node_pos - node_id - 1;
      end = begin + end - node_pos;

      uint8_t byte = query[i];
      while (begin < end) {
        node_id = (begin + end) / 2;
        if (byte < labels_[node_id]) {
          end = node_id;
        } else if (byte > labels_[node_id]) {
          begin = node_id + 1;
        } else {
          if (links_.get(node_id)) {
            uint64_t tail_pos = tail_bits_.select(links_.rank(node_id));
            for (++i; i < query.length(); ++i) {
              if (tail_bytes_[tail_pos] != (uint8_t)query[i]) {
                return -1;
              }
              ++tail_pos;
              if (tail_bits_.get(tail_pos)) {
                break;
              }
            }
            if (i == query.length()) {
              return -1;
            }
          }
          break;
        }
      }
      if (begin >= end) {
        return -1;
      }
    }
    if (!outs_.get(node_id)) {
      return -1;
    }
    return outs_.rank(node_id);
  }

// Assembly:
subq $0x98, %rsp
movq %rdi, 0x88(%rsp)
movq %rsi, 0x80(%rsp)
movq 0x88(%rsp), %rax
movq %rax, 0x38(%rsp)
movq $0x0, 0x78(%rsp)
movq $0x0, 0x70(%rsp)
movq 0x70(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0x80(%rsp), %rdi
callq 0x21e0
movq %rax, %rcx
movq 0x30(%rsp), %rax
cmpq %rcx, %rax
jae 0x76e5
movq 0x38(%rsp), %rdi
addq $0x48, %rdi
movq 0x78(%rsp), %rsi
callq 0x4380
movq 0x38(%rsp), %rdi
addq $0x1, %rax
movq %rax, 0x68(%rsp)
movq 0x68(%rsp), %rax
movq %rax, 0x60(%rsp)
addq $0x48, %rdi
movq 0x60(%rsp), %rsi
shrq $0x6, %rsi
callq 0x9700
movq (%rax), %rax
movq 0x60(%rsp), %rcx
andq $0x3f, %rcx
shrq %cl, %rax
movq %rax, 0x58(%rsp)
cmpq $0x0, 0x58(%rsp)
jne 0x746a
movq 0x38(%rsp), %rdi
movq 0x60(%rsp), %rcx
andq $0x3f, %rcx
movl $0x40, %eax
subq %rcx, %rax
addq 0x60(%rsp), %rax
movq %rax, 0x60(%rsp)
addq $0x48, %rdi
movq 0x60(%rsp), %rsi
shrq $0x6, %rsi
callq 0x9700
movq (%rax), %rax
movq %rax, 0x58(%rsp)
cmpq $0x0, 0x58(%rsp)
jne 0x7468
movq 0x38(%rsp), %rdi
movq 0x60(%rsp), %rax
addq $0x40, %rax
movq %rax, 0x60(%rsp)
addq $0x48, %rdi
movq 0x60(%rsp), %rsi
shrq $0x6, %rsi
callq 0x9700
movq (%rax), %rax
movq %rax, 0x58(%rsp)
jmp 0x7431
jmp 0x746a
movq 0x58(%rsp), %rdi
callq 0x5c60
addq 0x60(%rsp), %rax
movq %rax, 0x60(%rsp)
movq 0x68(%rsp), %rax
subq 0x78(%rsp), %rax
subq $0x1, %rax
movq %rax, 0x50(%rsp)
movq 0x50(%rsp), %rax
addq 0x60(%rsp), %rax
subq 0x68(%rsp), %rax
movq %rax, 0x60(%rsp)
movq 0x80(%rsp), %rdi
movq 0x70(%rsp), %rsi
callq 0x21a0
movb (%rax), %al
movb %al, 0x4f(%rsp)
movq 0x50(%rsp), %rax
cmpq 0x60(%rsp), %rax
jae 0x76b6
movq 0x38(%rsp), %rdi
movq 0x50(%rsp), %rax
addq 0x60(%rsp), %rax
shrq %rax
movq %rax, 0x78(%rsp)
movzbl 0x4f(%rsp), %eax
movl %eax, 0x2c(%rsp)
addq $0x138, %rdi            # imm = 0x138
movq 0x78(%rsp), %rsi
callq 0xa1a0
movq %rax, %rcx
movl 0x2c(%rsp), %eax
movzbl (%rcx), %ecx
cmpl %ecx, %eax
jge 0x751b
movq 0x78(%rsp), %rax
movq %rax, 0x60(%rsp)
jmp 0x76b1
movq 0x38(%rsp), %rdi
movzbl 0x4f(%rsp), %eax
movl %eax, 0x28(%rsp)
addq $0x138, %rdi            # imm = 0x138
movq 0x78(%rsp), %rsi
callq 0xa1a0
movq %rax, %rcx
movl 0x28(%rsp), %eax
movzbl (%rcx), %ecx
cmpl %ecx, %eax
jle 0x755b
movq 0x78(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x50(%rsp)
jmp 0x76af
movq 0x38(%rsp), %rdi
addq $0xe8, %rdi
movq 0x78(%rsp), %rsi
callq 0x41d0
cmpq $0x0, %rax
je 0x76ad
movq 0x38(%rsp), %rdi
movq %rdi, %rax
addq $0x150, %rax            # imm = 0x150
movq %rax, 0x20(%rsp)
addq $0xe8, %rdi
movq 0x78(%rsp), %rsi
callq 0x42a0
movq 0x20(%rsp), %rdi
movq %rax, %rsi
callq 0x4380
movq %rax, 0x40(%rsp)
movq 0x70(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x70(%rsp)
movq 0x70(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x80(%rsp), %rdi
callq 0x21e0
movq %rax, %rcx
movq 0x18(%rsp), %rax
cmpq %rcx, %rax
jae 0x7676
movq 0x38(%rsp), %rdi
addq $0x1a0, %rdi            # imm = 0x1A0
movq 0x40(%rsp), %rsi
callq 0xa1a0
movzbl (%rax), %eax
movl %eax, 0x14(%rsp)
movq 0x80(%rsp), %rdi
movq 0x70(%rsp), %rsi
callq 0x21a0
movq %rax, %rcx
movl 0x14(%rsp), %eax
movzbl (%rcx), %ecx
cmpl %ecx, %eax
je 0x7635
movq $-0x1, 0x90(%rsp)
jmp 0x772d
movq 0x38(%rsp), %rdi
movq 0x40(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x40(%rsp)
addq $0x150, %rdi            # imm = 0x150
movq 0x40(%rsp), %rsi
callq 0x41d0
cmpq $0x0, %rax
je 0x7661
jmp 0x7676
jmp 0x7663
movq 0x70(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x70(%rsp)
jmp 0x75bf
movq 0x70(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x80(%rsp), %rdi
callq 0x21e0
movq %rax, %rcx
movq 0x8(%rsp), %rax
cmpq %rcx, %rax
jne 0x76ab
movq $-0x1, 0x90(%rsp)
jmp 0x772d
jmp 0x76ad
jmp 0x76b6
jmp 0x76b1
jmp 0x74bd
movq 0x50(%rsp), %rax
cmpq 0x60(%rsp), %rax
jb 0x76d0
movq $-0x1, 0x90(%rsp)
jmp 0x772d
jmp 0x76d2
movq 0x70(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x70(%rsp)
jmp 0x7376
movq 0x38(%rsp), %rdi
addq $0x98, %rdi
movq 0x78(%rsp), %rsi
callq 0x41d0
cmpq $0x0, %rax
jne 0x770f
movq $-0x1, 0x90(%rsp)
jmp 0x772d
movq 0x38(%rsp), %rdi
addq $0x98, %rdi
movq 0x78(%rsp), %rsi
callq 0x42a0
movq %rax, 0x90(%rsp)
movq 0x90(%rsp), %rax
addq $0x98, %rsp
retq
nopl (%rax)