// File: s-yata[P]louds-patricia/louds-patricia.cpp
// Function: louds::PatriciaImpl::build()
void build() {
    trie_.build();

    louds_.add(0);
    louds_.add(1);
    outs_.add(trie_.levels[0].outs.get(0));
    links_.add(0);
    labels_.push_back(' ');

    queue<Node> queue;
    if (!trie_.levels[1].louds.get(0)) {
      queue.push(Node{ 1, 0 });
    }
    while (!queue.empty()) {
      Node node = queue.front();
      if (node.level_id != 0) {
        while (!trie_.levels[node.level_id].louds.get(node.node_pos)) {
          louds_.add(0);
          uint64_t level_id = node.level_id;
          uint64_t node_pos = node.node_pos;
          uint64_t node_id = node_pos - trie_.levels[level_id].louds.rank(node_pos);
          labels_.push_back(trie_.levels[level_id].labels[node_id]);
          for ( ; ; ) {
            node_pos = (node_id == 0) ? 0 :
              trie_.levels[level_id + 1].louds.select(node_id - 1) + 1;
            if (trie_.levels[level_id].outs.get(node_id) ||
              !trie_.levels[level_id + 1].louds.get(node_pos + 1)) {
              break;
            }
            node_id = node_pos - node_id;
            tail_bits_.add(level_id == node.level_id);
            ++level_id;
            tail_bytes_.push_back(trie_.levels[level_id].labels[node_id]);
          }
          if (!trie_.levels[level_id + 1].louds.get(node_pos)) {
            queue.push(Node{ level_id + 1, node_pos });
          } else {
            queue.push(Node{ 0, 0 });
          }
          links_.add(level_id > node.level_id);
          outs_.add(trie_.levels[level_id].outs.get(node_id));
          ++node.node_pos;
          ++node_id;
        }
      }
      louds_.add(1);
      queue.pop();
    }

    louds_.build();
    outs_.build();
    links_.build();
    tail_bits_.add(1);
    tail_bits_.build();

    // Note: trie_ is no longer required.
  }

// Assembly:
subq $0x148, %rsp            # imm = 0x148
movq %rdi, 0x140(%rsp)
movq 0x140(%rsp), %rdi
movq %rdi, 0x80(%rsp)
callq 0x4160
movq 0x80(%rsp), %rdi
addq $0x48, %rdi
movq %rdi, 0x70(%rsp)
xorl %eax, %eax
movl %eax, %esi
movq %rsi, 0x90(%rsp)
callq 0x2860
movq 0x70(%rsp), %rdi
movl $0x1, %esi
movq %rsi, 0x88(%rsp)
callq 0x2860
movq 0x80(%rsp), %rdi
movq 0x90(%rsp), %rsi
movq %rdi, %rax
addq $0x98, %rax
movq %rax, 0x78(%rsp)
callq 0x2840
movq 0x90(%rsp), %rsi
movq %rax, %rdi
addq $0x50, %rdi
callq 0x41d0
movq 0x78(%rsp), %rdi
movq %rax, %rsi
callq 0x2860
movq 0x80(%rsp), %rdi
movq 0x90(%rsp), %rsi
addq $0xe8, %rdi
callq 0x2860
movq 0x80(%rsp), %rdi
addq $0x138, %rdi            # imm = 0x138
movb $0x20, 0x13f(%rsp)
leaq 0x13f(%rsp), %rsi
callq 0x78a0
leaq 0xe8(%rsp), %rdi
callq 0x4210
movq 0x80(%rsp), %rdi
movq 0x88(%rsp), %rsi
callq 0x2840
movq 0x90(%rsp), %rsi
movq %rax, %rdi
callq 0x41d0
movq %rax, 0x98(%rsp)
jmp 0x6d2d
movq 0x98(%rsp), %rax
cmpq $0x0, %rax
jne 0x6da8
movq 0xd0(%rsp), %rax
andq $-0x1000000, %rax       # imm = 0xFF000000
incq %rax
movq %rax, 0xd0(%rsp)
movq 0xd0(%rsp), %rax
andl $0xffffff, %eax         # imm = 0xFFFFFF
movq %rax, 0xd0(%rsp)
leaq 0xe8(%rsp), %rdi
leaq 0xd0(%rsp), %rsi
callq 0x4240
jmp 0x6d80
jmp 0x6da8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xe0(%rsp)
movl %eax, 0xdc(%rsp)
leaq 0xe8(%rsp), %rdi
callq 0x4930
jmp 0x732a
jmp 0x6daa
leaq 0xe8(%rsp), %rdi
callq 0x4270
movb %al, 0x6f(%rsp)
jmp 0x6dbd
movb 0x6f(%rsp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x6dcc
jmp 0x72a5
leaq 0xe8(%rsp), %rdi
callq 0x4290
movq %rax, 0x60(%rsp)
jmp 0x6de0
movq 0x60(%rsp), %rax
movq (%rax), %rax
movq %rax, 0xc8(%rsp)
movq 0xc8(%rsp), %rax
andq $0xffffff, %rax         # imm = 0xFFFFFF
cmpl $0x0, %eax
je 0x7279
jmp 0x6e09
movq 0x80(%rsp), %rdi
movq 0xc8(%rsp), %rax
andl $0xffffff, %eax         # imm = 0xFFFFFF
movl %eax, %esi
callq 0x2840
movq %rax, %rdi
movq 0xc8(%rsp), %rsi
shrq $0x18, %rsi
callq 0x41d0
movq %rax, 0x58(%rsp)
jmp 0x6e40
movq 0x58(%rsp), %rax
cmpq $0x0, %rax
setne %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x6e57
jmp 0x7277
movq 0x80(%rsp), %rdi
addq $0x48, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x2860
jmp 0x6e6e
movq 0x80(%rsp), %rdi
movq 0xc8(%rsp), %rax
andl $0xffffff, %eax         # imm = 0xFFFFFF
movq %rax, 0xc0(%rsp)
movq 0xc8(%rsp), %rax
shrq $0x18, %rax
movq %rax, 0xb8(%rsp)
movq 0xb8(%rsp), %rax
movq %rax, 0x48(%rsp)
movq 0xc0(%rsp), %rsi
callq 0x2840
movq %rax, %rdi
movq 0xb8(%rsp), %rsi
callq 0x42a0
movq %rax, 0x50(%rsp)
jmp 0x6ed0
movq 0x80(%rsp), %rdi
movq 0x50(%rsp), %rcx
movq 0x48(%rsp), %rax
subq %rcx, %rax
movq %rax, 0xb0(%rsp)
movq %rdi, %rax
addq $0x138, %rax            # imm = 0x138
movq %rax, 0x40(%rsp)
movq 0xc0(%rsp), %rsi
callq 0x2840
movq %rax, %rdi
addq $0xa0, %rdi
movq 0xb0(%rsp), %rsi
callq 0x96e0
movq 0x40(%rsp), %rdi
movq %rax, %rsi
callq 0x9670
jmp 0x6f2e
jmp 0x6f30
cmpq $0x0, 0xb0(%rsp)
jne 0x6f44
xorl %eax, %eax
movq %rax, 0x38(%rsp)
jmp 0x6f84
movq 0x80(%rsp), %rdi
movq 0xc0(%rsp), %rsi
incq %rsi
callq 0x2840
movq %rax, %rdi
movq 0xb0(%rsp), %rsi
decq %rsi
callq 0x4380
movq %rax, 0x30(%rsp)
jmp 0x6f76
movq 0x30(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x38(%rsp)
movq 0x80(%rsp), %rdi
movq 0x38(%rsp), %rax
movq %rax, 0xb8(%rsp)
movq 0xc0(%rsp), %rsi
callq 0x2840
movq %rax, %rdi
addq $0x50, %rdi
movq 0xb0(%rsp), %rsi
callq 0x41d0
movq %rax, 0x28(%rsp)
jmp 0x6fc1
movq 0x28(%rsp), %rax
cmpq $0x0, %rax
jne 0x7009
movq 0x80(%rsp), %rdi
movq 0xc0(%rsp), %rsi
incq %rsi
callq 0x2840
movq %rax, %rdi
movq 0xb8(%rsp), %rsi
incq %rsi
callq 0x41d0
movq %rax, 0x20(%rsp)
jmp 0x6ffe
movq 0x20(%rsp), %rax
cmpq $0x0, %rax
jne 0x700e
jmp 0x70c1
movq 0x80(%rsp), %rdi
movq 0xb8(%rsp), %rax
movq 0xb0(%rsp), %rcx
subq %rcx, %rax
movq %rax, 0xb0(%rsp)
addq $0x150, %rdi            # imm = 0x150
movq 0xc0(%rsp), %rax
movq 0xc8(%rsp), %rcx
andl $0xffffff, %ecx         # imm = 0xFFFFFF
subq %rcx, %rax
sete %al
movzbl %al, %eax
movl %eax, %esi
callq 0x2860
jmp 0x7060
movq 0x80(%rsp), %rdi
movq 0xc0(%rsp), %rax
incq %rax
movq %rax, 0xc0(%rsp)
movq %rdi, %rax
addq $0x1a0, %rax            # imm = 0x1A0
movq %rax, 0x18(%rsp)
movq 0xc0(%rsp), %rsi
callq 0x2840
movq %rax, %rdi
addq $0xa0, %rdi
movq 0xb0(%rsp), %rsi
callq 0x96e0
movq 0x18(%rsp), %rdi
movq %rax, %rsi
callq 0x9670
jmp 0x70bc
jmp 0x6f30
movq 0x80(%rsp), %rdi
movq 0xc0(%rsp), %rsi
incq %rsi
callq 0x2840
movq %rax, %rdi
movq 0xb8(%rsp), %rsi
callq 0x41d0
movq %rax, 0x10(%rsp)
jmp 0x70f0
movq 0x10(%rsp), %rax
cmpq $0x0, %rax
jne 0x7160
movl 0xc0(%rsp), %ecx
incl %ecx
movq 0xa8(%rsp), %rax
andl $0xffffff, %ecx         # imm = 0xFFFFFF
andq $-0x1000000, %rax       # imm = 0xFF000000
orq %rcx, %rax
movq %rax, 0xa8(%rsp)
movq 0xb8(%rsp), %rcx
movq 0xa8(%rsp), %rax
shlq $0x18, %rcx
andl $0xffffff, %eax         # imm = 0xFFFFFF
orq %rcx, %rax
movq %rax, 0xa8(%rsp)
leaq 0xe8(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
callq 0x4240
jmp 0x715e
jmp 0x71a0
movzbl 0xa3(%rsp), %eax
shll $0x18, %eax
movl %eax, 0xa0(%rsp)
movq 0xa0(%rsp), %rax
andl $0xffffff, %eax         # imm = 0xFFFFFF
movq %rax, 0xa0(%rsp)
leaq 0xe8(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
callq 0x4240
jmp 0x719e
jmp 0x71a0
movq 0x80(%rsp), %rdi
addq $0xe8, %rdi
movq 0xc0(%rsp), %rax
movq 0xc8(%rsp), %rcx
andl $0xffffff, %ecx         # imm = 0xFFFFFF
subq %rcx, %rax
seta %al
movzbl %al, %eax
movl %eax, %esi
callq 0x2860
jmp 0x71d7
movq 0x80(%rsp), %rdi
movq %rdi, %rax
addq $0x98, %rax
movq %rax, (%rsp)
movq 0xc0(%rsp), %rsi
callq 0x2840
movq %rax, %rdi
addq $0x50, %rdi
movq 0xb0(%rsp), %rsi
callq 0x41d0
movq %rax, 0x8(%rsp)
jmp 0x7214
movq 0x8(%rsp), %rsi
movq (%rsp), %rdi
callq 0x2860
jmp 0x7224
movq 0xc8(%rsp), %rcx
shrq $0x18, %rcx
addq $0x1, %rcx
movq 0xc8(%rsp), %rax
movabsq $0xffffffffff, %rdx     # imm = 0xFFFFFFFFFF
andq %rdx, %rcx
shlq $0x18, %rcx
andq $0xffffff, %rax         # imm = 0xFFFFFF
orq %rcx, %rax
movq %rax, 0xc8(%rsp)
movq 0xb0(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xb0(%rsp)
jmp 0x6e09
jmp 0x7279
movq 0x80(%rsp), %rdi
addq $0x48, %rdi
movl $0x1, %esi
callq 0x2860
jmp 0x7291
leaq 0xe8(%rsp), %rdi
callq 0x46a0
jmp 0x72a0
jmp 0x6daa
movq 0x80(%rsp), %rdi
addq $0x48, %rdi
callq 0x46b0
jmp 0x72b8
movq 0x80(%rsp), %rdi
addq $0x98, %rdi
callq 0x46b0
jmp 0x72ce
movq 0x80(%rsp), %rdi
addq $0xe8, %rdi
callq 0x46b0
jmp 0x72e4
movq 0x80(%rsp), %rdi
addq $0x150, %rdi            # imm = 0x150
movl $0x1, %esi
callq 0x2860
jmp 0x72ff
movq 0x80(%rsp), %rdi
addq $0x150, %rdi            # imm = 0x150
callq 0x46b0
jmp 0x7315
leaq 0xe8(%rsp), %rdi
callq 0x4930
addq $0x148, %rsp            # imm = 0x148
retq
movq 0xe0(%rsp), %rdi
callq 0x2230
nopw (%rax,%rax)