LCS: fill the O(nm) table (match → diagonal +1, mismatch → max of up/left), then trace back to read the actual subsequence. LIS: deal values into patience piles; the pile count is the LIS length.
tails array tracks lengths, not a valid subsequence — see middle.md for parent-pointer reconstruction
and professional.md for the proof that tails stays sorted.