use DP in longestCommonSubstring

Used the dynamic programming approach to reduce the complexity of longestCommonSubstring to O(mn) from O(mn^2).
@vkostyukov What's the best way to handle a compound key `(i,j)` with an immutable `Map`?