// File: chhylp123[P]hifiasm/inter.cpp
// Function: hc_chain_backtrack(long, long const*, unsigned long const*, unsigned long*, unsigned long*, unsigned long*, long*, long*)
int64_t hc_chain_backtrack(int64_t n, const int64_t *f, const uint64_t *p, uint64_t *srt, uint64_t *u, uint64_t *v, 
int64_t *n_u_, int64_t *n_v_)
{
	if(n_u_) *n_u_ = 0; if(n_v_) *n_v_ = 0;
	int64_t i, k, n_v, n_srt, n_v0, n_u, sc;
	if (n == 0) return 0;
	// v[] keeps the peak score up to i; f[] is the score ending at i, not always the peak
	*n_u_ = *n_v_ = 0;	
	for (i = 0, k = 0; i < n; ++i) {
		if(f[i] >= 0) {
			srt[k] = (uint64_t)f[i]; srt[k] <<= 32; srt[k] |= (((uint64_t)i)<<1); k++;
		}
	}
	n_srt = k;
	radix_sort_gfa64(srt, srt + n_srt); ///sort by score

	///from the largest to the smallest
	for (k = n_srt-1, n_v = n_u = 0; k >= 0; --k) { // precompute n_u
		n_v0 = n_v;
		for (i = ((uint32_t)srt[k])>>1; i >= 0 && (srt[i]&1) == 0; i = (p[i]==(uint64_t)-1?-1:p[i])) {
			v[n_v++] = i; srt[i] |= 1;
		}
		if(n_v <= n_v0) continue;
		sc = i < 0? srt[k]>>32: (int64_t)(srt[k]>>32)-f[i]; 
		u[n_u++] = (((uint64_t)sc)<<32) | ((uint64_t)(n_v-n_v0));
	}

	if(n_u_) *n_u_ = n_u; if(n_v_) *n_v_ = n_v;
	return n_u;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq 0x18(%rbp), %rax
movq 0x10(%rbp), %rax
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq %r8, -0x30(%rbp)
movq %r9, -0x38(%rbp)
cmpq $0x0, 0x10(%rbp)
je 0x2d418d
movq 0x10(%rbp), %rax
movq $0x0, (%rax)
cmpq $0x0, 0x18(%rbp)
je 0x2d419f
movq 0x18(%rbp), %rax
movq $0x0, (%rax)
cmpq $0x0, -0x10(%rbp)
jne 0x2d41b3
movq $0x0, -0x8(%rbp)
jmp 0x2d440c
movq 0x18(%rbp), %rax
movq $0x0, (%rax)
movq 0x10(%rbp), %rax
movq $0x0, (%rax)
movq $0x0, -0x40(%rbp)
movq $0x0, -0x48(%rbp)
movq -0x40(%rbp), %rax
cmpq -0x10(%rbp), %rax
jge 0x2d4251
movq -0x18(%rbp), %rax
movq -0x40(%rbp), %rcx
cmpq $0x0, (%rax,%rcx,8)
jl 0x2d4241
movq -0x18(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rdx
movq -0x28(%rbp), %rax
movq -0x48(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x28(%rbp), %rax
movq -0x48(%rbp), %rcx
movq (%rax,%rcx,8), %rdx
shlq $0x20, %rdx
movq %rdx, (%rax,%rcx,8)
movq -0x40(%rbp), %rdx
shlq %rdx
movq -0x28(%rbp), %rax
movq -0x48(%rbp), %rcx
orq (%rax,%rcx,8), %rdx
movq %rdx, (%rax,%rcx,8)
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0x2d4243
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
jmp 0x2d41d9
movq -0x48(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x28(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x58(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rsi
callq 0x27a9b0
movq -0x58(%rbp), %rax
subq $0x1, %rax
movq %rax, -0x48(%rbp)
movq $0x0, -0x68(%rbp)
movq $0x0, -0x50(%rbp)
cmpq $0x0, -0x48(%rbp)
jl 0x2d43e0
movq -0x50(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x28(%rbp), %rax
movq -0x48(%rbp), %rcx
movq (%rax,%rcx,8), %rax
shrl %eax
movl %eax, %eax
movq %rax, -0x40(%rbp)
xorl %eax, %eax
cmpq $0x0, -0x40(%rbp)
movb %al, -0x71(%rbp)
jl 0x2d42da
movq -0x28(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
andq $0x1, %rax
cmpq $0x0, %rax
sete %al
movb %al, -0x71(%rbp)
movb -0x71(%rbp), %al
testb $0x1, %al
jne 0x2d42e3
jmp 0x2d434b
movq -0x40(%rbp), %rdx
movq -0x38(%rbp), %rax
movq -0x50(%rbp), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, -0x50(%rbp)
movq %rdx, (%rax,%rcx,8)
movq -0x28(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rdx
orq $0x1, %rdx
movq %rdx, (%rax,%rcx,8)
movq -0x20(%rbp), %rax
movq -0x40(%rbp), %rcx
cmpq $-0x1, (%rax,%rcx,8)
jne 0x2d432e
movq $-0x1, %rax
movq %rax, -0x80(%rbp)
jmp 0x2d433e
movq -0x20(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rax
movq %rax, -0x40(%rbp)
jmp 0x2d42b4
movq -0x50(%rbp), %rax
cmpq -0x60(%rbp), %rax
jg 0x2d4357
jmp 0x2d43cf
cmpq $0x0, -0x40(%rbp)
jge 0x2d4377
movq -0x28(%rbp), %rax
movq -0x48(%rbp), %rcx
movq (%rax,%rcx,8), %rax
shrq $0x20, %rax
movq %rax, -0x88(%rbp)
jmp 0x2d439a
movq -0x28(%rbp), %rax
movq -0x48(%rbp), %rcx
movq (%rax,%rcx,8), %rax
shrq $0x20, %rax
movq -0x18(%rbp), %rcx
movq -0x40(%rbp), %rdx
subq (%rcx,%rdx,8), %rax
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rdx
shlq $0x20, %rdx
movq -0x50(%rbp), %rax
subq -0x60(%rbp), %rax
orq %rax, %rdx
movq -0x30(%rbp), %rax
movq -0x68(%rbp), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, -0x68(%rbp)
movq %rdx, (%rax,%rcx,8)
movq -0x48(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0x2d428d
cmpq $0x0, 0x10(%rbp)
je 0x2d43f2
movq -0x68(%rbp), %rcx
movq 0x10(%rbp), %rax
movq %rcx, (%rax)
cmpq $0x0, 0x18(%rbp)
je 0x2d4404
movq -0x50(%rbp), %rcx
movq 0x18(%rbp), %rax
movq %rcx, (%rax)
movq -0x68(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x90, %rsp
popq %rbp
retq
nopl (%rax)