// File: /workspace/github_cpp_makefile_star2_O3/ikatanic[P]lcskpp/lcskpp.cpp
// Function: lcskpp(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, int, std::vector<std::pair<int, int>, std::allocator<std::pair<int, int>>>*)
int lcskpp(const string& a, const string& b, int k,
          vector<pair<int, int>>* reconstruction) {
  int m = b.size();
  vector<pair<int, int>> matches;
  calc_matches(a, b, k, &matches);

  int n_matches = matches.size();
  vector<pair<int, int>> MinYPrefix(m + 1, {m+1, -1});
  MinYPrefix[0].first = -1;

  int r = 0;  // current lcsk++ length
  int log_r = 1;  // log(r+1) + 1

  vector<int> match_dp(matches.size());
  vector<int> recon(matches.size());

  int ptr = 0;
  int query_ptr = 0;
  int cont_ptr = 0;
  int last_idx = -1;

  // We process matches row by row (while loop).
  // When at row i, we also handle queries on MinYPrefix for matches
  // in row i+k-1 (query_ptr).
  // cont_ptr points to ptr's possible continuation (applicable only to k > 1).
  while (ptr < n_matches) {
    int i = matches[ptr].first;  // current row index
    int i_row_ptr = ptr;


    while (query_ptr < n_matches && matches[query_ptr].first < i+k) {
      int query_row_i = matches[query_ptr].first;

      // count matches in row query_row_i
      int query_row_end = query_ptr;
      while (query_row_end < n_matches &&
             matches[query_row_end].first == query_row_i) query_row_end++;
      int row_count = query_row_end - query_ptr;

      // decide between binary search for each match (Hunt and Szymanski) and
      // sweep through MinYPrefix (Kuo and Cross).
      if (row_count * log_r * 6 < r) {
        int last_l = 0;
        while (query_ptr < query_row_end) {
          int j = matches[query_ptr].second;

          if (MinYPrefix[last_l].first < j-k+1) {
            int lo = last_l+1, hi = r+1;
            while (lo < hi) {
              int mid = (lo + hi) / 2;
              if (MinYPrefix[mid].first < j - k + 1)
                lo = mid + 1;
              else
                hi = mid;
            }
            last_l = lo;
          }

          recon[query_ptr] = MinYPrefix[last_l-1].second;
          match_dp[query_ptr++] = last_l-1+k;
        }
      } else {
        int l = 0;
        while (query_ptr < query_row_end) {
          int j = matches[query_ptr].second;
          while (MinYPrefix[l].first < j-k+1) l++;
          recon[query_ptr] = MinYPrefix[l-1].second;
          match_dp[query_ptr++] = l-1+k;
        }
      }
    }

    if (k > 1) {
      while (cont_ptr < i_row_ptr && matches[cont_ptr].first < i-1) cont_ptr++;
    }

    // now the main loop through matches in row i, finishing off their
    // dp calculation and doing updates to MinYPrefix
    while (ptr < n_matches && matches[ptr].first == i) {
      int j = matches[ptr].second;
      int& ptr_dp = match_dp[ptr];

      // update MinYPrefix
      for (int s = ptr_dp; s > ptr_dp-k && MinYPrefix[s].first > j; --s) {
        MinYPrefix[s] = {j, ptr};
      }

      // Try continuation
      if (k > 1) {
        while (cont_ptr < i_row_ptr && matches[cont_ptr].second < j-1)
          cont_ptr++;
        if (cont_ptr < i_row_ptr && matches[cont_ptr].second == j-1 &&
            match_dp[cont_ptr] + 1 > ptr_dp) {
                ptr_dp = match_dp[cont_ptr] + 1;
                recon[ptr] = cont_ptr;
                MinYPrefix[ptr_dp] = min(MinYPrefix[ptr_dp], {j, ptr});
              }
      }

      if (ptr_dp > r) {
        r = ptr_dp;
        last_idx = ptr;
        while ((1 << log_r) < r+1) log_r++;
      }

      ptr++;
    }
  }

  if (reconstruction) {
    reconstruction->clear();

    int i = last_idx;
    while (i != -1) {
      assert(0 <= i && i < matches.size());

      if (recon[i] != -1 &&
          matches[recon[i]].first+1 == matches[i].first &&
          matches[recon[i]].second+1 == matches[i].second) {
        // continuation
        reconstruction->push_back({matches[i].first, matches[i].second});
      } else {
        // non-overlapping match
        assert(recon[i] == -1 ||
          (matches[recon[i]].first + k <= matches[i].first &&
           matches[recon[i]].second + k <= matches[i].second));
        for (int j = 0; j < k; ++j) {
          reconstruction->push_back({matches[i].first-j, matches[i].second-j});
        }
      }

      i = recon[i];
    }
    reverse(reconstruction->begin(), reconstruction->end());
  }

  return r;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb8, %rsp
movq %rcx, 0x18(%rsp)
movl %edx, %r14d
movq 0x8(%rsi), %r15
pxor %xmm0, %xmm0
leaq 0x30(%rsp), %rcx
movdqa %xmm0, (%rcx)
movq $0x0, 0x10(%rcx)
callq 0x27c2
movq 0x38(%rsp), %rbx
subq 0x30(%rsp), %rbx
incl %r15d
movslq %r15d, %rsi
leaq 0x88(%rsp), %rdx
movl %esi, (%rdx)
movl $0xffffffff, 0x4(%rdx)  # imm = 0xFFFFFFFF
leaq 0xa0(%rsp), %rdi
leaq 0x68(%rsp), %rcx
callq 0x3f94
movq 0xa0(%rsp), %rax
movl $0xffffffff, (%rax)     # imm = 0xFFFFFFFF
movq 0x38(%rsp), %rsi
subq 0x30(%rsp), %rsi
sarq $0x3, %rsi
leaq 0x88(%rsp), %rdi
leaq 0x68(%rsp), %rdx
callq 0x3d6c
movq 0x38(%rsp), %rsi
subq 0x30(%rsp), %rsi
sarq $0x3, %rsi
leaq 0x68(%rsp), %rdi
leaq 0x8(%rsp), %rdx
callq 0x3d6c
shrq $0x3, %rbx
testl %ebx, %ebx
movq 0x18(%rsp), %rdi
jle 0x3861
movq 0x30(%rsp), %rdx
movq %rbx, 0x28(%rsp)
andl $0x7fffffff, %ebx       # imm = 0x7FFFFFFF
movq %rbx, 0x80(%rsp)
movl $0xffffffff, %r11d      # imm = 0xFFFFFFFF
movl $0x1, %ecx
xorl %r12d, %r12d
movl $0x0, 0x20(%rsp)
xorl %r8d, %r8d
xorl %r13d, %r13d
movl %r11d, 0x54(%rsp)
movslq %r13d, %r10
movl (%rdx,%r10,8), %eax
movq 0x28(%rsp), %rdi
movl 0x20(%rsp), %ebx
cmpl %edi, %ebx
movq %rax, (%rsp)
jge 0x3693
leal (%rax,%r14), %ebp
leal (%rcx,%rcx), %eax
leal (%rax,%rax,2), %eax
movl %eax, 0x58(%rsp)
movq 0xa0(%rsp), %rsi
movq 0x68(%rsp), %r11
movq 0x88(%rsp), %r15
leal 0x1(%r12), %eax
movl %eax, 0x48(%rsp)
movq %r12, 0x10(%rsp)
movq %r10, 0x60(%rsp)
movl %ebp, 0x24(%rsp)
movl %r13d, 0x5c(%rsp)
movslq %ebx, %rax
movl (%rdx,%rax,8), %r9d
cmpl %ebp, %r9d
jge 0x3693
movl %ebx, %r13d
cmpl %edi, %ebx
jge 0x358c
leaq (%rdx,%rax,8), %r12
movl %ebx, %r13d
cmpl %r9d, (%r12)
jne 0x3587
incl %r13d
addq $0x8, %r12
cmpl %r13d, %edi
jne 0x3572
movl %edi, %r13d
movq 0x10(%rsp), %r12
movl %r13d, %r9d
subl %ebx, %r9d
imull 0x58(%rsp), %r9d
cmpl %r12d, %r9d
jge 0x3627
cmpl %ebx, %r13d
jle 0x3686
movslq %r13d, %rdi
xorl %r12d, %r12d
movl 0x4(%rdx,%rax,8), %r9d
movslq %r12d, %r10
subl %r14d, %r9d
cmpl %r9d, (%rsi,%r10,8)
jle 0x35c6
movl %r12d, %ebp
jmp 0x3604
leal 0x1(%r12), %ebp
cmpl 0x10(%rsp), %r12d
jge 0x3604
movl 0x48(%rsp), %r10d
movl %r10d, %r12d
leal (%r12,%rbp), %ebx
movl %ebx, %r10d
shrl $0x1f, %r10d
addl %ebx, %r10d
sarl %r10d
movslq %r10d, %rbx
cmpl %r9d, (%rsi,%rbx,8)
jg 0x35fc
incl %r10d
movl %r10d, %ebp
jmp 0x35ff
movl %r10d, %r12d
cmpl %r12d, %ebp
jl 0x35da
movslq %ebp, %r9
movl -0x4(%rsi,%r9,8), %r10d
movl %r10d, (%r11,%rax,4)
addl %r14d, %r9d
decl %r9d
movl %r9d, (%r15,%rax,4)
incq %rax
movl %ebp, %r12d
cmpq %rdi, %rax
jne 0x35b0
jmp 0x3670
cmpl %ebx, %r13d
jle 0x3686
movslq %r13d, %rdi
xorl %r9d, %r9d
movl 0x4(%rdx,%rax,8), %ebp
subl %r14d, %ebp
movslq %r9d, %r12
leaq -0x1(%r12), %r9
addl $-0x2, %r12d
movq %r9, %r10
incq %r9
incl %r12d
cmpl %ebp, 0x8(%rsi,%r10,8)
jle 0x3645
movslq %r12d, %r10
movl 0x4(%rsi,%r10,8), %ebx
movl %ebx, (%r11,%rax,4)
addl %r14d, %r10d
movl %r10d, (%r15,%rax,4)
incq %rax
cmpq %rdi, %rax
jne 0x3632
movl %r13d, %ebx
movq 0x28(%rsp), %rdi
movq 0x10(%rsp), %r12
movq 0x60(%rsp), %r10
movl 0x24(%rsp), %ebp
cmpl %edi, %ebx
movl 0x5c(%rsp), %r13d
jl 0x3554
cmpl $0x2, %r14d
movl %ebx, 0x20(%rsp)
jl 0x36d0
cmpl %r13d, %r8d
movq (%rsp), %r9
jge 0x36d4
leal -0x1(%r9), %eax
movslq %r8d, %r9
leaq (%rdx,%r9,8), %rsi
movq %r10, %r11
subq %r9, %r11
xorl %r9d, %r9d
cmpl %eax, (%rsi,%r9,8)
jge 0x36cd
incq %r9
cmpq %r9, %r11
jne 0x36ba
movl %r13d, %r8d
jmp 0x36d0
addl %r9d, %r8d
movq (%rsp), %r9
cmpl %edi, %r13d
movq 0x18(%rsp), %rdi
movl 0x54(%rsp), %r11d
jge 0x3851
movq 0x88(%rsp), %r15
movq 0xa0(%rsp), %rsi
movq 0x68(%rsp), %rax
movq %rax, 0x48(%rsp)
cmpl %r9d, (%rdx,%r10,8)
jne 0x384e
movl (%r15,%r10,4), %ebp
testl %r14d, %r14d
jle 0x381c
movq %r12, %rbx
movl 0x4(%rdx,%r10,8), %eax
movslq %ebp, %r9
cmpl %eax, (%rsi,%r9,8)
jle 0x3760
decq %r9
movl %eax, 0x8(%rsi,%r9,8)
movl %r10d, 0xc(%rsi,%r9,8)
movq %r10, %r12
movl (%r15,%r10,4), %ebp
movl %ebp, %r10d
subl %r14d, %r10d
movslq %r10d, %r10
cmpq %r10, %r9
jle 0x375d
leaq -0x1(%r9), %r10
cmpl %eax, (%rsi,%r9,8)
movq %r10, %r9
movq %r12, %r10
jg 0x372c
jmp 0x3760
movq %r12, %r10
cmpl $0x2, %r14d
jl 0x37dd
cmpl %r13d, %r8d
movq %rbx, %r12
jge 0x3818
leal -0x1(%rax), %r9d
movslq %r8d, %r8
cmpl %r9d, 0x4(%rdx,%r8,8)
jge 0x3790
incq %r8
cmpl %r8d, %r13d
jne 0x3779
movl %r13d, %r8d
jmp 0x3818
jne 0x3818
movl (%r15,%r8,4), %r9d
cmpl %ebp, %r9d
jl 0x3818
movq %r12, 0x10(%rsp)
movl %r11d, %r12d
incl %r9d
movl %r9d, (%r15,%r10,4)
movq 0x48(%rsp), %rdi
movl %r8d, (%rdi,%r10,4)
movslq (%r15,%r10,4), %r9
leaq (%rsi,%r9,8), %r9
movl %eax, 0x8(%rsp)
movq %r10, %rbp
movl %r10d, 0xc(%rsp)
movl (%r9), %r11d
cmpl %r11d, %eax
jge 0x37e6
movl %eax, %r11d
leaq 0x8(%rsp), %r10
jmp 0x37f9
movq (%rsp), %r9
movq %rbx, %r12
jmp 0x381c
jle 0x37ed
movq %r9, %r10
jmp 0x37f9
movslq 0x4(%r9), %rdi
movq %r9, %r10
cmpq %rdi, %rbp
jl 0x37d3
movl %r11d, (%r9)
movl 0x4(%r10), %eax
movl %eax, 0x4(%r9)
movq %rbp, %r10
movl (%r15,%rbp,4), %ebp
movq 0x18(%rsp), %rdi
movl %r12d, %r11d
movq 0x10(%rsp), %r12
movq (%rsp), %r9
cmpl %r12d, %ebp
jle 0x3838
movl $0x1, %eax
shll %cl, %eax
incl %ecx
cmpl %ebp, %eax
jle 0x3821
decl %ecx
movl %r10d, %r11d
movl %ebp, %r12d
jmp 0x383b
movl %r12d, %ebp
incq %r10
cmpq 0x80(%rsp), %r10
jne 0x3701
jmp 0x3869
movl %r10d, %r13d
movl %r12d, %ebp
cmpl 0x28(%rsp), %r13d
jl 0x34f4
jmp 0x3869
xorl %ebp, %ebp
movl $0xffffffff, %r11d      # imm = 0xFFFFFFFF
testq %rdi, %rdi
je 0x39eb
movq (%rdi), %rax
movq 0x8(%rdi), %rcx
cmpq %rax, %rcx
je 0x3885
movq %rax, 0x8(%rdi)
movq %rax, %rcx
cmpl $-0x1, %r11d
je 0x39b0
leaq 0x8(%rsp), %r15
testl %r11d, %r11d
js 0x3a41
movl %r11d, %r12d
movq 0x30(%rsp), %rax
movq 0x38(%rsp), %rcx
subq %rax, %rcx
sarq $0x3, %rcx
cmpq %r12, %rcx
jbe 0x3a41
movq 0x68(%rsp), %rcx
movslq (%rcx,%r12,4), %rcx
cmpq $-0x1, %rcx
je 0x3930
movl (%rax,%rcx,8), %edx
leal 0x1(%rdx), %r9d
movl (%rax,%r12,8), %esi
cmpl %esi, %r9d
jne 0x3913
movl 0x4(%rax,%rcx,8), %r8d
incl %r8d
cmpl 0x4(%rax,%r12,8), %r8d
jne 0x3913
movl %r9d, 0x8(%rsp)
movl 0x4(%rax,%r12,8), %eax
movl %eax, 0xc(%rsp)
movq 0x8(%rdi), %rsi
cmpq 0x10(%rdi), %rsi
je 0x399a
movq 0x8(%rsp), %rax
movq %rax, (%rsi)
addq $0x8, 0x8(%rdi)
jmp 0x3985
addl %r14d, %edx
cmpl %esi, %edx
jg 0x3a60
movl 0x4(%rax,%rcx,8), %ecx
addl %r14d, %ecx
cmpl 0x4(%rax,%r12,8), %ecx
jg 0x3a60
testl %r14d, %r14d
jle 0x3985
xorl %r13d, %r13d
movq 0x30(%rsp), %rax
movq (%rax,%r12,8), %xmm0
movd %r13d, %xmm1
pshufd $0x50, %xmm1, %xmm1     # xmm1 = xmm1[0,0,1,1]
psubd %xmm1, %xmm0
movq %xmm0, 0x8(%rsp)
movq 0x8(%rdi), %rsi
cmpq 0x10(%rdi), %rsi
je 0x3970
movq 0x8(%rsp), %rax
movq %rax, (%rsi)
addq $0x8, 0x8(%rdi)
jmp 0x397d
movq %r15, %rdx
callq 0x406a
movq 0x18(%rsp), %rdi
incl %r13d
cmpl %r13d, %r14d
jne 0x3938
movq 0x68(%rsp), %rax
movl (%rax,%r12,4), %r11d
cmpl $-0x1, %r11d
jne 0x3894
jmp 0x39a9
movq %r15, %rdx
callq 0x406a
movq 0x18(%rsp), %rdi
jmp 0x3985
movq (%rdi), %rax
movq 0x8(%rdi), %rcx
cmpq %rcx, %rax
setne %dl
addq $-0x8, %rcx
cmpq %rax, %rcx
seta %sil
andb %dl, %sil
cmpb $0x1, %sil
jne 0x39eb
movl (%rax), %edx
movl (%rcx), %esi
movl %esi, (%rax)
movl %edx, (%rcx)
movl 0x4(%rax), %edx
movl 0x4(%rcx), %esi
movl %esi, 0x4(%rax)
movl %edx, 0x4(%rcx)
addq $0x8, %rax
addq $-0x8, %rcx
cmpq %rcx, %rax
jb 0x39ca
movq 0x68(%rsp), %rdi
testq %rdi, %rdi
je 0x39fa
callq 0x2130
movq 0x88(%rsp), %rdi
testq %rdi, %rdi
je 0x3a0c
callq 0x2130
movq 0xa0(%rsp), %rdi
testq %rdi, %rdi
je 0x3a1e
callq 0x2130
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x3a2d
callq 0x2130
movl %ebp, %eax
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x162c(%rip), %rdi      # 0x5074
leaq 0x1642(%rip), %rsi      # 0x5091
leaq 0x1646(%rip), %rcx      # 0x509c
movl $0x81, %edx
callq 0x20e0
leaq 0x167f(%rip), %rdi      # 0x50e6
leaq 0x1623(%rip), %rsi      # 0x5091
leaq 0x1627(%rip), %rcx      # 0x509c
movl $0x8c, %edx
callq 0x20e0
jmp 0x3a92
movq %rax, %rbx
jmp 0x3aa4
movq %rax, %rbx
jmp 0x3ab6
jmp 0x3a8d
movq %rax, %rbx
jmp 0x3ac8
movq %rax, %rbx
movq 0x68(%rsp), %rdi
testq %rdi, %rdi
je 0x3aa4
callq 0x2130
movq 0x88(%rsp), %rdi
testq %rdi, %rdi
je 0x3ab6
callq 0x2130
movq 0xa0(%rsp), %rdi
testq %rdi, %rdi
je 0x3ac8
callq 0x2130
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x3ad7
callq 0x2130
movq %rbx, %rdi
callq 0x2200
nop