My `X`

is the set of still available numbers. Gets accepted in about 230 ms:

```
def countArrangement(self, N):
def count(i, X):
if i == 1:
return 1
return sum(count(i - 1, X - {x})
for x in X
if x % i == 0 or i % x == 0)
return count(N, set(range(1, N + 1)))
```

Note that my `i`

goes **downwards**, from N to 1. Because position `i = 1`

can hold **any** number, so I don't even have to check whether the last remaining number fits there. Also, position `i = 2`

happily holds every second number and `i = 3`

happily holds every third number, so filling the lowest positions **last** has a relatively high chance of success. In other words, it's relatively hard to end up with dead ends this way.

If I go **upwards** (from 1 to N), it takes about 2300 ms:

```
def countArrangement(self, N):
def count(i, X):
if i > N:
return 1
return sum(count(i + 1, X - {x})
for x in X
if x % i == 0 or i % x == 0)
return count(1, set(range(1, N + 1)))
```