// File: fpavetic[P]lcskpp/lcskpp.cpp
// Function: lcskpp_sparse_slow(std::vector<std::pair<int, int>, std::allocator<std::pair<int, int>>> const&, int, int*, std::vector<std::pair<int, int>, std::allocator<std::pair<int, int>>>*)
static void lcskpp_sparse_slow(
    const vector<pair<int, int> >& matches,
    const int k, int* lcskpp_length,
    vector<pair<int, int> >* lcskpp_reconstruction) {
  assert(is_sorted(matches.begin(), matches.end()));

  if (matches.empty()) {
    *lcskpp_length = 0;
    if (lcskpp_reconstruction) lcskpp_reconstruction->clear();
  } else {
    int n = matches.size();
    vector<int> dp(n);
    vector<int> recon(n);
    int best_idx = 0;
    *lcskpp_length = 0;
    
    for (int i = 0; i < n; ++i) {
      dp[i] = k;
      recon[i] = -1;

      int end_row_i = matches[i].first+k-1;
      int end_col_i = matches[i].second+k-1;

      int primary_diagonal_i = end_row_i - end_col_i;
      int secondary_diagonal_i = (end_row_i + end_col_i)/2;

      for (int j = i-1; j >= 0; --j) {
        if (matches[j].first + k <= matches[i].first &&
            matches[j].second + k <= matches[i].second) {
          // 1) Taking the entire match interval and continuing
          // another match which 'ended'.
          if (dp[j] + k > dp[i]) {
            dp[i] = dp[j] + k;
            recon[i] = j;
          }
        } else {
          // 2) Continuation on the same primary diagonal.
          int end_row_j = matches[j].first+k-1;
          int end_col_j = matches[j].second+k-1;
          int primary_diagonal_j = end_row_j - end_col_j;
          int secondary_diagonal_j = (end_row_j + end_col_j)/2;
	  
          if (primary_diagonal_i == primary_diagonal_j &&
              secondary_diagonal_i > secondary_diagonal_j &&
              secondary_diagonal_i - secondary_diagonal_j < k) {
            if (dp[j] + secondary_diagonal_i - secondary_diagonal_j 
                > dp[i]) {
              dp[i] = 
                dp[j] + secondary_diagonal_i - secondary_diagonal_j;
              recon[i] = j;
            }
          }
        }
      }

      if (dp[i] > *lcskpp_length) {
        best_idx = i;
        *lcskpp_length = dp[i];
      }
    }

    if (lcskpp_reconstruction) {
      fill_lcskpp_reconstruction(matches, k, recon, best_idx, 
                                 *lcskpp_length, 
                                 lcskpp_reconstruction);
    }
  }
}

// Assembly:
subq $0xf8, %rsp
movq %rdi, 0xf0(%rsp)
movl %esi, 0xec(%rsp)
movq %rdx, 0xe0(%rsp)
movq %rcx, 0xd8(%rsp)
movq 0xf0(%rsp), %rdi
callq 0x7370
movq %rax, 0xd0(%rsp)
movq 0xf0(%rsp), %rdi
callq 0x73a0
movq %rax, 0xc8(%rsp)
movq 0xd0(%rsp), %rdi
movq 0xc8(%rsp), %rsi
callq 0xc060
testb $0x1, %al
jne 0x50cb
jmp 0x50cd
jmp 0x50ec
leaq 0xd2f2(%rip), %rdi      # 0x123c6
leaq 0xcfdd(%rip), %rsi      # 0x120b8
movl $0xf9, %edx
leaq 0xd309(%rip), %rcx      # 0x123f0
callq 0x20f0
movq 0xf0(%rsp), %rdi
callq 0xc0b0
testb $0x1, %al
jne 0x50ff
jmp 0x512a
movq 0xe0(%rsp), %rax
movl $0x0, (%rax)
cmpq $0x0, 0xd8(%rsp)
je 0x5125
movq 0xd8(%rsp), %rdi
callq 0x76e0
jmp 0x5624
movq 0xf0(%rsp), %rdi
callq 0x7350
movl %eax, 0xc4(%rsp)
movslq 0xc4(%rsp), %rax
movq %rax, 0x38(%rsp)
leaq 0xa7(%rsp), %rdi
movq %rdi, 0x40(%rsp)
callq 0x7460
movq 0x38(%rsp), %rsi
movq 0x40(%rsp), %rdx
leaq 0xa8(%rsp), %rdi
callq 0x7470
jmp 0x5176
leaq 0xa7(%rsp), %rdi
callq 0x75f0
movslq 0xc4(%rsp), %rax
movq %rax, 0x28(%rsp)
leaq 0x77(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0x7460
movq 0x28(%rsp), %rsi
movq 0x30(%rsp), %rdx
leaq 0x78(%rsp), %rdi
callq 0x7470
jmp 0x51b5
leaq 0x77(%rsp), %rdi
callq 0x75f0
movl $0x0, 0x70(%rsp)
movq 0xe0(%rsp), %rax
movl $0x0, (%rax)
movl $0x0, 0x6c(%rsp)
movl 0x6c(%rsp), %eax
cmpl 0xc4(%rsp), %eax
jge 0x559d
movl 0xec(%rsp), %eax
movl %eax, 0x24(%rsp)
movslq 0x6c(%rsp), %rsi
leaq 0xa8(%rsp), %rdi
callq 0x7620
movl 0x24(%rsp), %ecx
movl %ecx, (%rax)
movslq 0x6c(%rsp), %rsi
leaq 0x78(%rsp), %rdi
callq 0x7620
movl $0xffffffff, (%rax)     # imm = 0xFFFFFFFF
movq 0xf0(%rsp), %rdi
movslq 0x6c(%rsp), %rsi
callq 0x7440
movl (%rax), %eax
addl 0xec(%rsp), %eax
subl $0x1, %eax
movl %eax, 0x68(%rsp)
movq 0xf0(%rsp), %rdi
movslq 0x6c(%rsp), %rsi
callq 0x7440
movl 0x4(%rax), %eax
addl 0xec(%rsp), %eax
subl $0x1, %eax
movl %eax, 0x64(%rsp)
movl 0x68(%rsp), %eax
subl 0x64(%rsp), %eax
movl %eax, 0x60(%rsp)
movl 0x68(%rsp), %eax
addl 0x64(%rsp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, 0x5c(%rsp)
movl 0x6c(%rsp), %eax
subl $0x1, %eax
movl %eax, 0x58(%rsp)
cmpl $0x0, 0x58(%rsp)
jl 0x5545
movq 0xf0(%rsp), %rdi
movslq 0x58(%rsp), %rsi
callq 0x7440
movl (%rax), %eax
addl 0xec(%rsp), %eax
movl %eax, 0x20(%rsp)
movq 0xf0(%rsp), %rdi
movslq 0x6c(%rsp), %rsi
callq 0x7440
movq %rax, %rcx
movl 0x20(%rsp), %eax
cmpl (%rcx), %eax
jg 0x5407
movq 0xf0(%rsp), %rdi
movslq 0x58(%rsp), %rsi
callq 0x7440
movl 0x4(%rax), %eax
addl 0xec(%rsp), %eax
movl %eax, 0x1c(%rsp)
movq 0xf0(%rsp), %rdi
movslq 0x6c(%rsp), %rsi
callq 0x7440
movq %rax, %rcx
movl 0x1c(%rsp), %eax
cmpl 0x4(%rcx), %eax
jg 0x5407
movslq 0x58(%rsp), %rsi
leaq 0xa8(%rsp), %rdi
callq 0x7620
movl (%rax), %eax
addl 0xec(%rsp), %eax
movl %eax, 0x18(%rsp)
movslq 0x6c(%rsp), %rsi
leaq 0xa8(%rsp), %rdi
callq 0x7620
movq %rax, %rcx
movl 0x18(%rsp), %eax
cmpl (%rcx), %eax
jle 0x5402
movslq 0x58(%rsp), %rsi
leaq 0xa8(%rsp), %rdi
callq 0x7620
movl (%rax), %eax
addl 0xec(%rsp), %eax
movl %eax, 0x10(%rsp)
movslq 0x6c(%rsp), %rsi
leaq 0xa8(%rsp), %rdi
callq 0x7620
movl 0x10(%rsp), %ecx
movl %ecx, (%rax)
movl 0x58(%rsp), %eax
movl %eax, 0x14(%rsp)
movslq 0x6c(%rsp), %rsi
leaq 0x78(%rsp), %rdi
callq 0x7620
movl 0x14(%rsp), %ecx
movl %ecx, (%rax)
jmp 0x5402
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x98(%rsp)
movl %eax, 0x94(%rsp)
leaq 0xa7(%rsp), %rdi
callq 0x75f0
jmp 0x562c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x98(%rsp)
movl %eax, 0x94(%rsp)
leaq 0x77(%rsp), %rdi
callq 0x75f0
jmp 0x5615
jmp 0x5533
movq 0xf0(%rsp), %rdi
movslq 0x58(%rsp), %rsi
callq 0x7440
movl (%rax), %eax
addl 0xec(%rsp), %eax
subl $0x1, %eax
movl %eax, 0x54(%rsp)
movq 0xf0(%rsp), %rdi
movslq 0x58(%rsp), %rsi
callq 0x7440
movl 0x4(%rax), %eax
addl 0xec(%rsp), %eax
subl $0x1, %eax
movl %eax, 0x50(%rsp)
movl 0x54(%rsp), %eax
subl 0x50(%rsp), %eax
movl %eax, 0x4c(%rsp)
movl 0x54(%rsp), %eax
addl 0x50(%rsp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, 0x48(%rsp)
movl 0x60(%rsp), %eax
cmpl 0x4c(%rsp), %eax
jne 0x5531
movl 0x5c(%rsp), %eax
cmpl 0x48(%rsp), %eax
jle 0x5531
movl 0x5c(%rsp), %eax
subl 0x48(%rsp), %eax
cmpl 0xec(%rsp), %eax
jge 0x5531
movslq 0x58(%rsp), %rsi
leaq 0xa8(%rsp), %rdi
callq 0x7620
movl (%rax), %eax
addl 0x5c(%rsp), %eax
subl 0x48(%rsp), %eax
movl %eax, 0xc(%rsp)
movslq 0x6c(%rsp), %rsi
leaq 0xa8(%rsp), %rdi
callq 0x7620
movq %rax, %rcx
movl 0xc(%rsp), %eax
cmpl (%rcx), %eax
jle 0x552f
movslq 0x58(%rsp), %rsi
leaq 0xa8(%rsp), %rdi
callq 0x7620
movl (%rax), %eax
addl 0x5c(%rsp), %eax
subl 0x48(%rsp), %eax
movl %eax, 0x4(%rsp)
movslq 0x6c(%rsp), %rsi
leaq 0xa8(%rsp), %rdi
callq 0x7620
movl 0x4(%rsp), %ecx
movl %ecx, (%rax)
movl 0x58(%rsp), %eax
movl %eax, 0x8(%rsp)
movslq 0x6c(%rsp), %rsi
leaq 0x78(%rsp), %rdi
callq 0x7620
movl 0x8(%rsp), %ecx
movl %ecx, (%rax)
jmp 0x5531
jmp 0x5533
jmp 0x5535
movl 0x58(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x58(%rsp)
jmp 0x5296
movslq 0x6c(%rsp), %rsi
leaq 0xa8(%rsp), %rdi
callq 0x7620
movl (%rax), %eax
movq 0xe0(%rsp), %rcx
cmpl (%rcx), %eax
jle 0x558b
movl 0x6c(%rsp), %eax
movl %eax, 0x70(%rsp)
movslq 0x6c(%rsp), %rsi
leaq 0xa8(%rsp), %rdi
callq 0x7620
movl (%rax), %ecx
movq 0xe0(%rsp), %rax
movl %ecx, (%rax)
jmp 0x558d
movl 0x6c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x6c(%rsp)
jmp 0x51dd
cmpq $0x0, 0xd8(%rsp)
je 0x55fc
movq 0xf0(%rsp), %rdi
movl 0xec(%rsp), %esi
movl 0x70(%rsp), %ecx
movq 0xe0(%rsp), %rax
movl (%rax), %r8d
movq 0xd8(%rsp), %r9
leaq 0x78(%rsp), %rdx
callq 0x6fa0
jmp 0x55da
jmp 0x55fc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x98(%rsp)
movl %eax, 0x94(%rsp)
leaq 0x78(%rsp), %rdi
callq 0x7590
jmp 0x5615
leaq 0x78(%rsp), %rdi
callq 0x7590
leaq 0xa8(%rsp), %rdi
callq 0x7590
jmp 0x5624
leaq 0xa8(%rsp), %rdi
callq 0x7590
jmp 0x562c
addq $0xf8, %rsp
retq
movq 0x98(%rsp), %rdi
callq 0x2270
nopl (%rax)