Solution tested for small n, correct and fast so far