// File: /workspace/github_cpp_makefile_star2_O1/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 $0xc8, %rsp
movq %rcx, 0x58(%rsp)
movl %edx, %r14d
movq 0x8(%rsi), %rbx
pxor %xmm0, %xmm0
leaq 0x40(%rsp), %rcx
movdqa %xmm0, (%rcx)
movq $0x0, 0x10(%rcx)
callq 0x27bf
movq 0x48(%rsp), %r12
subq 0x40(%rsp), %r12
incl %ebx
movslq %ebx, %rsi
leaq 0x98(%rsp), %rdx
movl %esi, (%rdx)
movl $0xffffffff, 0x4(%rdx)  # imm = 0xFFFFFFFF
leaq 0xb0(%rsp), %rdi
leaq 0x68(%rsp), %rcx
callq 0x3fca
movq 0xb0(%rsp), %rax
movl $0xffffffff, (%rax)     # imm = 0xFFFFFFFF
movq 0x48(%rsp), %rsi
subq 0x40(%rsp), %rsi
sarq $0x3, %rsi
leaq 0x98(%rsp), %rdi
leaq 0x68(%rsp), %rdx
callq 0x3d9e
movq 0x48(%rsp), %rsi
subq 0x40(%rsp), %rsi
sarq $0x3, %rsi
leaq 0x68(%rsp), %rdi
leaq 0x8(%rsp), %rdx
callq 0x3d9e
shrq $0x3, %r12
testl %r12d, %r12d
jle 0x3893
movq 0x40(%rsp), %rdx
movl %r12d, %eax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
movq %rax, 0x90(%rsp)
leaq 0x4(%rdx), %rax
movq %rax, 0x88(%rsp)
movl $0xffffffff, 0x2c(%rsp) # imm = 0xFFFFFFFF
movl $0x1, %ecx
movq $0x0, 0x20(%rsp)
xorl %r13d, %r13d
xorl %r11d, %r11d
xorl %ebp, %ebp
movq %r12, 0x30(%rsp)
movq %r11, 0x38(%rsp)
movslq %ebp, %r10
movl (%rdx,%r10,8), %eax
cmpl %r12d, %r13d
movl %ebp, 0x4(%rsp)
movq %rax, 0x18(%rsp)
jge 0x3689
addl %r14d, %eax
movl %eax, 0x14(%rsp)
leal (%rcx,%rcx), %eax
leal (%rax,%rax,2), %eax
movl %eax, 0x60(%rsp)
movq 0xb0(%rsp), %rdi
movq 0x68(%rsp), %rsi
movq 0x98(%rsp), %r9
movq 0x20(%rsp), %rax
leal 0x1(%rax), %r11d
movslq %r13d, %rax
movl (%rdx,%rax,8), %r8d
cmpl 0x14(%rsp), %r8d
jge 0x3689
movl %r13d, %ebx
cmpl %r12d, %r13d
jge 0x359c
leaq (%rdx,%rax,8), %r15
movl %r13d, %ebx
cmpl %r8d, (%r15)
jne 0x359c
incl %ebx
addq $0x8, %r15
cmpl %ebx, %r12d
jne 0x3589
movl %r12d, %ebx
movl %ebx, %r8d
subl %r13d, %r8d
imull 0x60(%rsp), %r8d
cmpl 0x20(%rsp), %r8d
jge 0x362d
cmpl %r13d, %ebx
jle 0x3680
movslq %ebx, %rbp
xorl %r8d, %r8d
movl 0x4(%rdx,%rax,8), %ebx
movslq %r8d, %r15
subl %r14d, %ebx
cmpl %ebx, (%rdi,%r15,8)
jle 0x35d3
movl %r8d, %r12d
jmp 0x360b
leal 0x1(%r8), %r12d
cmpl 0x20(%rsp), %r8d
jge 0x360b
movl %r11d, %r8d
leal (%r8,%r12), %r13d
movl %r13d, %r15d
shrl $0x1f, %r15d
addl %r13d, %r15d
sarl %r15d
movslq %r15d, %r13
cmpl %ebx, (%rdi,%r13,8)
jg 0x3603
incl %r15d
movl %r15d, %r12d
jmp 0x3606
movl %r15d, %r8d
cmpl %r8d, %r12d
jl 0x35e1
movslq %r12d, %r8
movl -0x4(%rdi,%r8,8), %ebx
movl %ebx, (%rsi,%rax,4)
addl %r14d, %r8d
decl %r8d
movl %r8d, (%r9,%rax,4)
incq %rax
movl %r12d, %r8d
cmpq %rbp, %rax
jne 0x35be
jmp 0x3674
cmpl %r13d, %ebx
jle 0x3680
movslq %ebx, %rbx
xorl %r12d, %r12d
movl 0x4(%rdx,%rax,8), %r8d
subl %r14d, %r8d
movslq %r12d, %r12
leal -0x2(%r12), %ebp
decq %r12
movq %r12, %r15
incl %ebp
incq %r12
cmpl %r8d, 0x8(%rdi,%r15,8)
jle 0x364b
movslq %ebp, %r8
movl 0x4(%rdi,%r8,8), %ebp
movl %ebp, (%rsi,%rax,4)
addl %r14d, %r8d
movl %r8d, (%r9,%rax,4)
incq %rax
cmpq %rbx, %rax
jne 0x3638
movl %eax, %r13d
movq 0x30(%rsp), %r12
movl 0x4(%rsp), %ebp
cmpl %r12d, %r13d
jl 0x3568
cmpl $0x2, %r14d
jl 0x36c8
movq 0x38(%rsp), %r11
cmpl %ebp, %r11d
movq 0x18(%rsp), %r9
jge 0x36d2
leal -0x1(%r9), %eax
movslq %r11d, %rdi
leaq (%rdx,%rdi,8), %rsi
movq %r10, %r8
subq %rdi, %r8
xorl %edi, %edi
cmpl %eax, (%rsi,%rdi,8)
jge 0x36c3
incq %rdi
cmpq %rdi, %r8
jne 0x36b1
movl %ebp, %r11d
jmp 0x36d2
addl %edi, %r11d
jmp 0x36d2
movq 0x38(%rsp), %r11
movq 0x18(%rsp), %r9
cmpl %r12d, %ebp
jge 0x3888
movq 0x98(%rsp), %r12
movq 0xb0(%rsp), %rdi
movq 0x68(%rsp), %rax
movq %rax, 0x80(%rsp)
movl %ebp, %eax
negl %eax
movq %rax, 0x60(%rsp)
movl %r13d, 0x14(%rsp)
cmpl %r9d, (%rdx,%r10,8)
jne 0x3880
movl 0x4(%rdx,%r10,8), %esi
movl (%r12,%r10,4), %r9d
testl %r14d, %r14d
jle 0x3752
movslq %r9d, %r8
cmpl %esi, (%rdi,%r8,8)
jle 0x3752
decq %r8
movl %esi, 0x8(%rdi,%r8,8)
movl %r10d, 0xc(%rdi,%r8,8)
movl (%r12,%r10,4), %r9d
movl %r9d, %eax
subl %r14d, %eax
cltq
cmpq %rax, %r8
jle 0x3752
leaq -0x1(%r8), %rax
cmpl %esi, (%rdi,%r8,8)
movq %rax, %r8
jg 0x372a
cmpl $0x2, %r14d
jl 0x383b
cmpl %ebp, %r11d
jge 0x383b
leal -0x1(%rsi), %ebx
movslq %r11d, %r8
movq 0x88(%rsp), %rax
leaq (%rax,%r8,8), %r15
movq %r11, 0x38(%rsp)
movl %r11d, %eax
movq 0x60(%rsp), %r11
leaq (%r11,%rax), %r13
xorl %r11d, %r11d
movl (%r15,%r11,8), %ebp
cmpl %ebx, %ebp
jge 0x37bc
incq %r11
movl %r13d, %ebp
addl %r11d, %ebp
jne 0x378b
movq 0x38(%rsp), %rax
addl %r11d, %eax
movq %rax, %r11
movl 0x4(%rsp), %ebp
movq 0x18(%rsp), %r9
movl 0x14(%rsp), %r13d
jmp 0x3840
addq %r11, %rax
movq %rax, %r15
cmpl %ebx, %ebp
movl 0x14(%rsp), %r13d
jne 0x37e1
leaq (%r12,%r8,4), %rax
movl (%rax,%r11,4), %eax
cmpl %r9d, %eax
movl 0x4(%rsp), %ebp
jge 0x37ea
movq %r15, %r11
jmp 0x383b
movq %r15, %r11
movl 0x4(%rsp), %ebp
jmp 0x383b
incl %eax
movl %eax, (%r12,%r10,4)
movq %r15, %r11
movq 0x80(%rsp), %rax
movl %r11d, (%rax,%r10,4)
movslq (%r12,%r10,4), %rax
leaq (%rdi,%rax,8), %rax
movl %esi, 0x8(%rsp)
movl %r10d, 0xc(%rsp)
movl (%rax), %r9d
leaq 0x8(%rsp), %r8
cmpl %r9d, %esi
jl 0x3835
movq %rax, %r8
jg 0x3835
movslq 0x4(%rax), %rsi
cmpq %rsi, %r10
movq %rax, %r8
leaq 0x8(%rsp), %rsi
cmovlq %rsi, %r8
movq (%r8), %rsi
movq %rsi, (%rax)
movq 0x18(%rsp), %r9
movl (%r12,%r10,4), %esi
cmpl 0x20(%rsp), %esi
jle 0x3865
movl $0x1, %eax
shll %cl, %eax
incl %ecx
cmpl %esi, %eax
jle 0x384a
decl %ecx
movl %r10d, 0x2c(%rsp)
movl %esi, %eax
movq %rax, 0x20(%rsp)
incq %r10
cmpq 0x90(%rsp), %r10
jne 0x3706
movq 0x30(%rsp), %r12
movl %r12d, %ebp
jmp 0x3888
movl %r10d, %ebp
movq 0x30(%rsp), %r12
cmpl %r12d, %ebp
jl 0x351b
jmp 0x38a4
movq $0x0, 0x20(%rsp)
movl $0xffffffff, 0x2c(%rsp) # imm = 0xFFFFFFFF
movq 0x58(%rsp), %rdi
testq %rdi, %rdi
je 0x3a29
movq (%rdi), %rax
cmpq %rax, 0x8(%rdi)
je 0x38bf
movq %rax, 0x8(%rdi)
movl 0x2c(%rsp), %eax
cmpl $-0x1, %eax
je 0x39e7
leaq 0x8(%rsp), %r12
testl %eax, %eax
js 0x3a82
movl %eax, %r13d
movq 0x40(%rsp), %rax
movq 0x48(%rsp), %rcx
subq %rax, %rcx
sarq $0x3, %rcx
cmpq %r13, %rcx
jbe 0x3a82
movq 0x68(%rsp), %rcx
movslq (%rcx,%r13,4), %rcx
cmpq $-0x1, %rcx
je 0x3972
movl (%rax,%rcx,8), %edx
incl %edx
cmpl (%rax,%r13,8), %edx
jne 0x394b
movl 0x4(%rax,%rcx,8), %edx
incl %edx
cmpl 0x4(%rax,%r13,8), %edx
jne 0x394b
movl (%rax,%r13,8), %ecx
movl %ecx, 0x8(%rsp)
movl 0x4(%rax,%r13,8), %eax
movl %eax, 0xc(%rsp)
movq 0x8(%rdi), %rsi
cmpq 0x10(%rdi), %rsi
je 0x39d8
movq 0x8(%rsp), %rax
movq %rax, (%rsi)
addq $0x8, 0x8(%rdi)
jmp 0x39c4
cmpl $-0x1, %ecx
je 0x3972
movl (%rax,%rcx,8), %edx
addl %r14d, %edx
cmpl (%rax,%r13,8), %edx
jg 0x3aa1
movl 0x4(%rax,%rcx,8), %ecx
addl %r14d, %ecx
cmpl 0x4(%rax,%r13,8), %ecx
jg 0x3aa1
testl %r14d, %r14d
jle 0x39c4
xorl %ebx, %ebx
movq 0x40(%rsp), %rax
movq (%rax,%r13,8), %xmm0
movd %ebx, %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 0x39b0
movq 0x8(%rsp), %rax
movq %rax, (%rsi)
addq $0x8, 0x8(%rdi)
jmp 0x39bd
movq %r12, %rdx
callq 0x4092
movq 0x58(%rsp), %rdi
incl %ebx
cmpl %ebx, %r14d
jne 0x3979
movq 0x68(%rsp), %rax
movl (%rax,%r13,4), %eax
cmpl $-0x1, %eax
jne 0x38d1
jmp 0x39e7
movq %r12, %rdx
callq 0x4092
movq 0x58(%rsp), %rdi
jmp 0x39c4
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 0x3a29
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 0x3a08
movq 0x68(%rsp), %rdi
testq %rdi, %rdi
je 0x3a38
callq 0x2130
movq 0x98(%rsp), %rdi
testq %rdi, %rdi
je 0x3a4a
callq 0x2130
movq 0xb0(%rsp), %rdi
testq %rdi, %rdi
je 0x3a5c
callq 0x2130
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x3a6b
callq 0x2130
movq 0x20(%rsp), %rax
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x15eb(%rip), %rdi      # 0x5074
leaq 0x1601(%rip), %rsi      # 0x5091
leaq 0x1605(%rip), %rcx      # 0x509c
movl $0x81, %edx
callq 0x20e0
leaq 0x163e(%rip), %rdi      # 0x50e6
leaq 0x15e2(%rip), %rsi      # 0x5091
leaq 0x15e6(%rip), %rcx      # 0x509c
movl $0x8c, %edx
callq 0x20e0
jmp 0x3ad3
movq %rax, %rbx
jmp 0x3ae5
movq %rax, %rbx
jmp 0x3af7
jmp 0x3ace
movq %rax, %rbx
jmp 0x3b09
movq %rax, %rbx
movq 0x68(%rsp), %rdi
testq %rdi, %rdi
je 0x3ae5
callq 0x2130
movq 0x98(%rsp), %rdi
testq %rdi, %rdi
je 0x3af7
callq 0x2130
movq 0xb0(%rsp), %rdi
testq %rdi, %rdi
je 0x3b09
callq 0x2130
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x3b18
callq 0x2130
movq %rbx, %rdi
callq 0x2200