The chess knight has a unique movement, it may move two squares vertically and one square horizontally, or two squares horizontally and one square vertically (with both forming the shape of an L). The possible movements of chess knight are shown in this diagaram:
A chess knight can move as indicated in the chess diagram below:

We have a chess knight and a phone pad as shown below, the knight can only stand on a numeric cell (i.e. blue cell).

Given an integer n, return how many distinct phone numbers of length n we can dial.
You are allowed to place the knight on any numeric cell initially and then you should perform n - 1 jumps to dial a number of length n. All jumps should be valid knight jumps.
As the answer may be very large, return the answer modulo 109 + 7.
 
Example 1:
Input: n = 1
Output: 10
Explanation: We need to dial a number of length 1, so placing the knight over any numeric cell of the 10 cells is sufficient.

Example 2:
Input: n = 2
Output: 20
Explanation: All the valid number we can dial are [04, 06, 16, 18, 27, 29, 34, 38, 40, 43, 49, 60, 61, 67, 72, 76, 81, 83, 92, 94]

Example 3:
Input: n = 3
Output: 46

Example 4:
Input: n = 4
Output: 104

Example 5:
Input: n = 3131
Output: 136006598
Explanation: Please take care of the mod.

 
Constraints:

1 <= n <= 5000

Difficulty: interview

Starter code:

class Solution:
    def knightDialer(self, n: int) -> int:
        

Solutions:
class Solution:
    dp = [[1] * 10]
    def knightDialer(self, n: int) -> int:
        MOD = 10 ** 9 + 7
        jump = [[4, 6], [6, 8], [7, 9], [4, 8], [3, 9, 0], [], [0, 1, 7], [2, 6], [1, 3], [2, 4]]
        for i in range(len(self.dp), n):
            new = [0] * 10
            for j in range(10):
                new[j] = sum(self.dp[-1][k] for k in jump[j]) % MOD
            self.dp.append(new)
        return sum(self.dp[n - 1]) % MOD


from functools import lru_cache

mapping = [
            [4, 6], # 0
            [6, 8], # 1
            [7, 9], # 2
            [4, 8], # 3
            [0, 3, 9], # 4
            [], # 5
            [0, 1, 7], # 6
            [2, 6], # 7
            [1, 3], # 8
            [2, 4] # 9
        ]

mod = 1000_000_007

@lru_cache(None)
def dfs(n, i):
        if n == 1:
            return 1
        
        sum_ = 0
        for nei in mapping[i]:
            sum_ = (sum_ + dfs(n -1, nei)) % mod
            
        return sum_    
    
class Solution:            
    def knightDialer(self, N: int) -> int:                
        total = 0
        for i in range(10):
            total = (total + dfs(N, i)) % mod
            
        return total

import numpy as np
class Solution:
    def knightDialer(self, n: int) -> int:
#         d = {1:[6,8],
#              2:[7,9],
#              3:[4,8],
#              4:[3,9,0],
#              5:[],
#              6:[1,7,0],
#              7:[2,6],
#              8:[1,3],
#              9:[2,4],
#              0:[4,6]}
#         @lru_cache(None)
#         def dfs(i, n):
#             if n == 1:
#                 return 1
#             else:
#                 res = 0
#                 for c in d[i]:
#                     res += dfs(c, n-1)
#                 return res % (10**9+7)
            
#         return sum(dfs(i, n) for i in range(10)) % (10**9+7)
    
        mod = 10**9 + 7
        N = n
        if N == 1: return 10
        M = np.matrix([[0, 0, 0, 0, 1, 0, 1, 0, 0, 0],
                       [0, 0, 0, 0, 0, 0, 1, 0, 1, 0],
                       [0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
                       [0, 0, 0, 0, 1, 0, 0, 0, 1, 0],
                       [1, 0, 0, 1, 0, 0, 0, 0, 0, 1],
                       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                       [1, 1, 0, 0, 0, 0, 0, 1, 0, 0],
                       [0, 0, 1, 0, 0, 0, 1, 0, 0, 0],
                       [0, 1, 0, 1, 0, 0, 0, 0, 0, 0],
                       [0, 0, 1, 0, 1, 0, 0, 0, 0, 0]])
        res, N = 1, N - 1
        while N:
            if N % 2: res = res * M % mod
            M = M * M % mod
            N //= 2
        return int(np.sum(res)) % mod

class Solution:
    def knightDialer(self, n: int) -> int:
        # dp[neigh] at step k += dp[curr]
        possibleMoves = [[4,6], [6,8],[9,7],[4,8],[0,3,9],[],[0,1,7],[2,6],[1,3], [2,4]]
        dp = [1]*10
        upper = 10**9 + 7
        for i in range(n-1):
            dp2 = [0]*10
            for j in range(10):
                for adj in possibleMoves[j]:
                    dp2[adj] = (dp2[adj] + dp[j])%upper
            dp = dp2
        return sum(dp)%upper
                    


class Solution:
    def knightDialer(self, N: int) -> int:
        
        
        
        
        table = [[0 for col in range(10)] for row in range(N+1)]
        
        for val in range(10):
            table[1][val] = 1
            
            
        
        for i in range(2,N+1):
            table[i][0] = table[i-1][4] + table[i-1][6]
            table[i][1] = table[i-1][6] + table[i-1][8]
            table[i][2] = table[i-1][7] + table[i-1][9]
            table[i][3] = table[i-1][4] + table[i-1][8]
            table[i][4] = table[i-1][3] + table[i-1][9] + table[i-1][0]
            table[i][5] = 0
            table[i][6] = table[i-1][7] + table[i-1][1] + table[i-1][0]
            table[i][7] = table[i-1][2] + table[i-1][6]
            table[i][8] = table[i-1][1] + table[i-1][3]
            table[i][9] = table[i-1][2] + table[i-1][4]

            
        return sum(table[-1])%(10**9 + 7)

        
        
        
        


class Solution:
    def knightDialer(self, n: int) -> int:
        move = {1:[6,8], 2:[7,9], 3:[4,8], 4:[0,3,9], 5:[], 6:[0,1,7], 7:[2,6], 8:[1,3], 9:[2,4], 0:[4,6]}
        
        curr_dial = [1] * 10
        for _ in range(n-1):
            next_dial = [0] * 10
            for key in range(10):
                for neighbor in move[key]:
                    next_dial[neighbor] = (next_dial[neighbor] + curr_dial[key]) % (10 ** 9 +7)
                
            curr_dial = next_dial
            
        return sum(curr_dial) % (10 ** 9 +7)
    
#         case = set()
        
#         def dfs(curr = \"\", k = 0):
#             if k == n:
#                 case.add(curr)
#                 return
#             if k == 0:
#                 for i in range(10):
#                     dfs(curr + str(i), k+1)
#             else:
#                 for i in move[int(curr[-1])]:
#                     dfs(curr + str(i), k+1)
        
#         dfs()    
            
#         return len(case) % (10 ** 9 +7)


class Solution:
    def knightDialer(self, N: int) -> int:
        # Space O(10)
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],[1,7,0],[2,6],[1,3],[2,4]]
        dp = [1] * 10
        MOD = 10**9 + 7
        for i in range(N - 1):
            next_dp = [0] * 10
            for j in range(10):
                for next_digit in moves[j]:
                    next_dp[j] = (next_dp[j] + dp[next_digit]) % MOD
            dp = next_dp
        return sum(dp) % MOD
        
        # space O(10 * N)
        mapping = {1:[6,8], 
                   2:[7,9], 
                   3:[4,8], 
                   4:[3,9,0],
                   5:[],
                   6:[1,7,0],
                   7:[2,6], 
                   8:[1,3], 
                   9:[2,4], 
                   0:[4,6]}
        dp = [[1] * 10 for _ in range(N)]
        dp[0] = [1] * 10
        for i in range(1, N):
            for j in range(10):
                for k in mapping[j]:
                    dp[i][j] += dp[i - 1][k]
        return sum(dp[-1]) % (10 ** 9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        moves = [
            [4, 6],
            [6, 8],
            [7, 9],
            [4, 8],
            [0, 3, 9],
            [],
            [0, 1, 7],
            [2, 6],
            [1, 3],
            [2, 4],
        ]
        kmod = 10**9 + 7
        dp = [1] * 10
        for k in range(1, n):
            tmp = [0] * 10
            for i in range(10):
                for j in moves[i]:
                    tmp[j] = (tmp[j] + dp[i]) % kmod
            dp = tmp
        res = 0
        for i in range(10):
            res = (res + dp[i]) % kmod
        return res

class Solution:
    def knightDialer(self, n: int) -> int:
        valid_moves = [
            [4, 6], 
            [6, 8], 
            [7, 9],
            [4, 8],
            [0, 3, 9], 
            [],
            [0, 1, 7],
            [2, 6],
            [1, 3],
            [2, 4]
        ]
        
        dp = [1] * 10
        m = 10 ** 9 + 7
        for _ in range(n-1):
            new_dp = [0] * 10
            for i in range(10):
                for j in valid_moves[i]:
                    new_dp[j] += dp[i] % m
            dp = new_dp
        return sum(dp) % m


class Solution:
    def knightDialer(self, N: int) -> int:
        moves = [(4,6),(6,8),(7,9),(4,8),(3,9,0),(),(1,7,0),(2,6),(1,3),(2,4)]
        memo = [1]*10
        maxV = (10**9+7)
        for _ in range(N-1):
            temp = [0]*10
            for i in range(10):
                for dest in moves[i]:
                    temp[i] += memo[dest]
                temp[i] %= (10**9+7)
            memo = temp
                    
        return sum(memo)%(10**9+7)


class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10**9 + 7
        
        
        #dp[i][j] possible answers at step[i], number j
        dp =[0 for _ in range(10)]
        #possible next moves
        move = [[4,6], [6,8], [7,9], [4,8], [3,9,0], [], [1,7,0], [2,6], [1,3], [4,2]]
        #noundary condition, initialization at n = 0, dp[0][j] = 1
        dp = [1  for _ in range(10)]
        #transfer equation
        for i in range(n-1):
            dp2 = [0]*10
            for j in range(10):
                for nei in move[j]:
                    dp2[nei] = (dp2[nei] + dp[j])%MOD
            dp = dp2
        #final answer
        return sum(dp)%MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        movements = {
        0:(4,6),
        1:(6,8),
        2:(7,9),
        3:(4,8),
        4:(0,3,9),
        5:(),
        6:(0,1,7),
        7:(2,6),
        8:(1,3),
        9:(2,4)
        }
        total = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
        for _ in range(n - 1):
            curr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
            for num in range(10):
                for move in movements[num]:
                    curr[move] = (curr[move] + total[num]) % (10 ** 9 + 7)
            total = curr
        return sum(total) % (10**9 + 7)

import numpy as np
class Solution:
    def knightDialer(self, N: int) -> int:
        
        mod = 10**9 + 7
        moves = np.matrix([[0, 0, 0, 0, 1, 0, 1, 0, 0, 0],
                       [0, 0, 0, 0, 0, 0, 1, 0, 1, 0],
                       [0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
                       [0, 0, 0, 0, 1, 0, 0, 0, 1, 0],
                       [1, 0, 0, 1, 0, 0, 0, 0, 0, 1],
                       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                       [1, 1, 0, 0, 0, 0, 0, 1, 0, 0],
                       [0, 0, 1, 0, 0, 0, 1, 0, 0, 0],
                       [0, 1, 0, 1, 0, 0, 0, 0, 0, 0],
                       [0, 0, 1, 0, 1, 0, 0, 0, 0, 0]])
        res = np.matrix([[1]*10])

        N -= 1
        while N:
            if N % 2 != 0: 
                res = res * moves % mod     
                N -= 1
            else:
                moves = moves * moves % mod
                N //= 2
        return int(np.sum(res)) % mod
                
        


class Solution:
    def knightDialer(self, n: int) -> int:
        
        mod = 10**9+7
        next_dic = {}
        next_dic[1] = [8,6]
        next_dic[2] = [7,9]
        next_dic[3] = [4,8]
        
        next_dic[4] = [3,9,0]
        next_dic[5] = []
        next_dic[6] = [7,1,0]
        
        next_dic[7] = [2,6]
        next_dic[8] = [3,1]
        next_dic[9] = [2,4]
        
        next_dic[0] = [6,4]
        
        dp  = [1]*10
        for i in range(n-1):
            dp_new = [0]*10
            for i in range(10):
                for move in next_dic[i]:
                    dp_new[move] = (dp_new[move]+dp[i])%mod
            del dp
            dp = dp_new
        return sum(dp)%mod


class Solution:
    def knightDialer(self, n: int) -> int:
        # Neighbors maps K: starting_key -> V: list of possible destination_keys
        neighbors = {
            0:(4,6),
            1:(6,8),
            2:(7,9),
            3:(4,8),
            4:(0,3,9),
            5:(),
            6:(0,1,7),
            7:(2,6),
            8:(1,3),
            9:(2,4)
        }
        current_counts = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
        for _ in range(n-1):
            next_counts = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
            for src_key in range(10):
                for dst_key in neighbors[src_key]:
                    next_counts[dst_key] = (next_counts[dst_key] + current_counts[src_key]) % (10**9 + 7)
            current_counts = next_counts
        return sum(current_counts) % (10**9 + 7)

class Solution:
    def knightDialer(self, N: int) -> int:
        M = 10 ** 9 + 7
        d = {1: [6, 8], 2: [7, 9], 3:[4, 8], 4: [3, 9, 0], 5: [],
             6: [0, 1, 7], 7: [6, 2], 8: [1, 3], 9: [2, 4], 0: [4, 6]}
        
        out = [1] * 10
        for _ in range(N - 1):
            out1 = [0] * 10
            for j in range(10):
                for k in d[j]:
                    out1[k] += out[j] % M
            out = out1
        return sum(out) % M


class Solution:
    def knightDialer(self, n: int) -> int:
        mod = 10**9+7
        dic = {0:[4,6], 1:[6,8], 2:[7,9], 3:[4,8], 4:[0,3,9], 5:[], 6:[0,1,7], 7:[2,6], 8:[1,3], 9:[4,2]}
        counts = [1,1,1,1,1,1,1,1,1,1]
        for k in range(n-1):
            new = [0,0,0,0,0,0,0,0,0,0]
            for i in range(10):
                for j in dic[i]:
                    new[j] = (new[j]+counts[i])%mod
            counts = new
        return sum(counts)%mod
                


class Solution:
    def knightDialer(self, N: int) -> int:
        # Neighbors maps K: starting_key -> V: list of possible destination_keys
        neighbors = {
            0:(4,6),
            1:(6,8),
            2:(7,9),
            3:(4,8),
            4:(0,3,9),
            5:(),
            6:(0,1,7),
            7:(2,6),
            8:(1,3),
            9:(2,4)
        }
        current_counts = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
        for _ in range(N-1):
            next_counts = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
            for src_key in range(10):
                for dst_key in neighbors[src_key]:
                    next_counts[dst_key] = (next_counts[dst_key] + current_counts[src_key]) % (10**9 + 7)
            current_counts = next_counts
        return sum(current_counts) % (10**9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        d = {1:(6, 8), 2:(7, 9), 3:(4,8), 4: (0, 3, 9), 5:(), 6: (0, 1, 7), 7:(2, 6), 8:(1, 3), 9:(2, 4), 0:(4,6)}
        prev = [1] * 10
        
        for dial in range(n - 1):
            nex = [0] * 10
            for curNum in range(10):
                for nexNum in d[curNum]:
                    nex[nexNum] = (nex[nexNum] + prev[curNum]) % (10**9+ 7)
            prev = nex [:]
        return sum(prev)%(10**9+ 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        moves = [[4, 6],[6, 8],[7, 9],[4, 8]
                 ,[0, 3, 9],[],[0, 1, 7]
                 ,[2, 6],[1, 3],[2, 4]]
        dp = [1] * 10
        for _ in range(n-1):
            dp2 = [0] * 10
            for i, cnt in enumerate(dp):
                for nxt in moves[i]:
                    dp2[nxt] += cnt
            dp = dp2
        return sum(dp) % (10**9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        # time O(n); space O(1)
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[], [1,7,0],[2,6],[1,3],[2,4]]
        
        dp = [1] * 10
        for hop in range(n-1):
            new_dp = [0] * 10
            for node, cnt in enumerate(dp):
                for nei in moves[node]:
                    new_dp[nei] += cnt
            dp = new_dp
        
        return sum(dp) % (10**9+7)

class Solution:
    def knightDialer1(self, N: int) -> int:
        m,n = 4,3
        M = 10**9+7
        def dp(i,j,k):
            if k==0:
                return 1
            out = 0
            for x,y in [(i+2,j+1),(i-2,j+1),(i+2,j-1),(i-2,j-1),
                       (i+1,j+2),(i+1,j-2),(i-1,j+2),(i-1,j-2)]:
                if 0<=x<m and 0<=y<n and (x!=3 or y not in [0,2]):
                    out += dp(x,y,k-1)
            return out
        out = 0
        for i in range(m):
            for j in range(n):
                if i!=m-1 or j not in [0,2]:
                    out+=dp(i,j,N-1)
        return out
    def knightDialer(self, N: int) -> int:
        M = 10**9+7
        d = {1:[6,8],2:[7,9],3:[4,8],4:[3,9,0],5:[],6:[0,1,7],7:[6,2],8:[1,3],9:[2,4],0:[4,6]}
        
        out = [1]*10
        for i in range(N-1):
            out1=[0]*10
            for j in range(10):
                for k in d[j]:
                    out1[k]+=out[j]%M
            out=out1
        return sum(out)%M


class Solution:
    def helper(self,cache,position,num_hops):
        neighbors = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
             [1,7,0],[2,6],[1,3],[2,4]]
        if (position, num_hops) in cache:
            return cache[ (position, num_hops) ]

        if num_hops == 0:
            return 1

        else:
            num_sequences = 0
            for neighbor in neighbors[position]:
                num_sequences += self.helper(cache,neighbor, num_hops - 1)
            cache[ (position, num_hops) ] = num_sequences
        return num_sequences
        
    def knightDialer(self, n: int) -> int:
            neighbors = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
             [1,7,0],[2,6],[1,3],[2,4]]
            prior_case = [1] * 10                                     
            current_case = [1] * 10                                   
            current_num_hops = 1                                    

            while current_num_hops < n:                       
                current_case = [0] * 10                               
                current_num_hops += 1                                 

                for position in range(0, 10):                         
                    for neighbor in neighbors[position]:              
                        current_case[position] += prior_case[neighbor]
                prior_case = current_case                             

            return sum(current_case) % (10**9 + 7)
    



        
        
                    
                    
                    
                


class Solution:
    
    BASE = 10 ** 9 + 7
    
    def knightDialer(self, N: int) -> int:
        if N <= 1:
            return 10
        a, b, c, d = 2, 4, 2, 1
        for _ in range(N - 1):
            a, b, c, d = (b, 2 * (a + c) % self.BASE, (b + 2 * d) % self.BASE, c)
        return (a + b + c + d) % self.BASE

class Solution:
    def knightDialer(self, N: int) -> int:
        dic={0:[4,6],1:[6,8],2:[7,9],3:[4,8],4:[0,3,9],5:[],6:[0,1,7],7:[2,6],8:[1,3],9:[2,4]}
        dp=[1 for i in range(10)]
        for i in range(N-1):
            new_dp=[0 for j in range(10)]
            for j in range(10):
                for k in dic[j]:
                    new_dp[j]+=dp[k]
                new_dp[j]%=(10**9+7)
            dp=new_dp
        return sum(dp)%(10**9+7)


class Solution:
    def knightDialer(self, n: int) -> int:
        moves = [[4, 6],[6, 8],[7, 9],[4, 8]
         ,[0, 3, 9],[],[0, 1, 7]
         ,[2, 6],[1, 3],[2, 4]]
        dp = [1] * 10
        for _ in range(n-1):
            dp2 = [0] * 10
            for i, cnt in enumerate(dp):
                for nxt in moves[i]:
                    dp2[nxt] += cnt
            dp = dp2
        return sum(dp) % (10**9 + 7)
    # time:  O(n)
    # space: O(1)


class Solution:
    def knightDialer(self, n: int) -> int:
        total_jumps = [1] * 10  #base case you can be placed ANYWHERE 
        #These are your neighbors where you jumping to with your knight mover 
        neighbors = { 
            0:(4,6),
            1:(6,8),
            2:(7,9),
            3:(4,8),
            4:(0,3,9),
            5:(),
            6:(0,1,7),
            7:(2,6),
            8:(1,3),
            9:(2,4)
        
        }
        
        #jumps allowed is n - 1 
        for jumps_left in range(n - 1): 
            #our next_jumps 
            next_jumps = [0] * 10 
            for num in range(0, 10): 
                for next_num in neighbors[num]: 
                    next_jumps[next_num] = next_jumps[next_num] + total_jumps[num] % (10 ** 9 + 7)
                    
            total_jumps = next_jumps
            
        return sum(total_jumps) % (10 ** 9 + 7)

                    
# class Solution():            
    # def count_sequences(start_position, num_hops):                
    #     prior_case = [1] * 10                                     
    #     current_case = [0] * 10                                   
    #     current_num_hops = 1                                      

    #     while current_num_hops <= num_hops:                       
    #         current_case = [0] * 10                               
    #         current_num_hops += 1                                 

    #         for position in range(0, 10):                         
    #             for neighbor in neighbors(position):              
    #                 current_case[position] += prior_case[neighbor]
    #         prior_case = current_case                             

    #     return current_case[start_position]              
# class Solution:
#     def knightDialer(self, n: int) -> int:
#         #knight -> up or down (2 steps) and move left or right ( 1step)
#         #knight -> move left or right (2 steps) and move up and down (1 step)
        
#         #We have a Knight as shown above
#         #We also have a numer pad and can ONLY stand on numbers 
        
#         #Given an int -> n move the knight on any numeric cell and then perform n-1 jumps to dial a number of length n 
#         #Return the answer modulo 10^9 + 7 

#         neighbors = { 
#             0:(4,6),
#             1:(6,8),
#             2:(7,9),
#             3:(4,8),
#             4:(0,3,9),
#             5:(),
#             6:(0,1,7),
#             7:(2,6),
#             8:(1,3),
#             9:(2,4)
        
#         }
    
#         cur_numpads = [1] * 10 
        
#         for pos in range(n - 1): 
#             next_numpads_num = [0] * 10
            
#             for cur_key in range(10):
#                 for next_key in neighbors[cur_key]:
#                     next_numpads_num[next_key] = next_numpads_num[next_key] + cur_numpads[cur_key] % (10 ** 9 + 7)
                    
#             cur_numpads = next_numpads_num 
        
#         return sum(cur_numpads) % (10**9 + 7)


class Solution:    
    def knightDialer(self, n: int) -> int:
        dp = [1 for _ in range(10)]
        BASE = 10**9+7
        data = {
            0: [4,6],
            1: [6,8],
            2: [7,9],
            3: [4,8],
            4: [3,9,0],
            5: [],
            6: [1,7,0],
            7: [2,6],
            8: [1,3],
            9: [2,4]
        }
        
        for i in range(n-1):
            dp_tmp = []
            for j in range(10):
                sum_tmp = 0
                for k in data[j]:
                    sum_tmp += (dp[k] % BASE)
                dp_tmp.append(sum_tmp % BASE)
            dp = dp_tmp
        
        return sum(dp) % BASE
        

        
        


class Solution:
    def knightDialer(self, n):
        dmap = [[4, 6], [8, 6], [7, 9], [8, 4], [3, 9, 0], [], [1, 7, 0], [2, 6], [1, 3], [2, 4],[4, 6]]
        mod_val = 10 ** 9 + 7
        ans = 0
        dp1 = [1]*10
        dp2 = [0]*10
        
        for _ in range(2, n+1):
            for j in range(0, 10):
                tv = dmap[j]
                for t in tv:
                    dp2[j] += dp1[t] % mod_val
            dp1 = dp2[:]
            dp2 = [0]*10
        #print(dp)
        ans = sum(dp1) % mod_val
        return ans


class Solution:
    
    def __init__(self):
        self.paths = {1: [8, 6], 2: [7, 9], 3: [4, 8], 4: [3, 9, 0], 5: [], 6: [1, 7, 0], 7: [2, 6], 8: [1, 3], 9: [2, 4], 0: [4, 6]}
    
    def knightDialer(self, n: int) -> int: # 3
        constant = 10**9+7
        if n == 0:
            return 0
        
        # Stream
        prev_cache = [1 for i in range(10)]
        cache = [0 for i in range(10)]
        
        for i in range(n-1):
            # print(prev_cache)
            for j in range(10):
                total_sum = 0
                for adj_num in self.paths[j]:
                    total_sum += prev_cache[adj_num]
                cache[j] = total_sum
                # print(j, total_sum)
            # print(cache)
            prev_cache, cache = cache, prev_cache
            
        return sum(prev_cache) % constant
        
        
        # Below is recur
        # ways(0, 3)
            # ways(4, 2)
                # ways(3, 1)
                    # ways(4, 0)
                        # return 0
                    # ways(8, 0) # 0
                # ways(9, 1)
                # ways(0, 1)
            # ways(6, 2)
        
#         cache = {}
        
#         # @lru_cache
#         def ways(number, turns):
#             if turns < 2:
#                 return turns
            
#             key = (number, turns)
#             if key in cache:
#                 return cache[key]
            
#             total_ways = 0
#             for new_number in self.paths[number]:
#                 total_ways += ways(new_number, turns-1)
            
#             cache[key] = total_ways % (10**9+7)
            
#             return cache[key]
                
#         total_ways = 0 # 0
#         for i in range(10):
#             total_ways += ways(i, n) # 
#         return total_ways % (10**9+7)


class Solution:
    def knightDialer(self, n: int) -> int:
        mod = 10**9 + 7

        d = dict()
        d[0] = {4, 6}
        d[1] = {6, 8}
        d[2] = {7, 9}
        d[3] = {4, 8}
        d[4] = {0, 3, 9}
        d[6] = {0, 1, 7}
        d[7] = {2, 6}
        d[8] = {1, 3}
        d[9] = {2, 4}
        
#         memo = [[0]*10 for i in range(n+1)]
#         memo[1] = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
        
#         for i in range(2, n+1):
#             for key, val in d.items():
#                 for v in val:
#                     memo[i][key] += memo[i-1][v]
        
        # memo = [[0]*10 for i in range(n+1)]
        memo = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
        memo2 = [0]*10
        
        for i in range(2, n+1):
            for key, val in list(d.items()):
                for v in val:
                    memo2[key] += memo[v]
            memo = memo2
            memo2 = [0]*10
        
        return sum(memo)%mod
        
        


class Solution:
    def knightDialer(self, n: int) -> int:
        neighbors = [[4,6],[6,8],[7,9],[4,8],[0,3,9],[],[0,1,7],[2,6],[1,3],[2,4]]
        prior_case = [1] * 10                                     
        current_case = [0] * 10                                   
        current_num_hops = 1                                      
                                                              
        while current_num_hops < n:                       
            current_case = [0] * 10                               
            current_num_hops += 1                                 
                                                              
            for position in range(0, 10):                         
                for neighbor in neighbors[position]:              
                    current_case[position] += prior_case[neighbor]
            prior_case = current_case 
            # print(sum(prior_case))
            
        return sum(prior_case) % (10**9 + 7)
        '''
        moves = [[4,6],[6,8],[7,9],[4,8],[0,3,9],[],[0,1,7],[2,6],[1,3],[2,4]]
        # down up dp appraoch
        prev_level = [1] * 10 # base
        curr_level = [0] * 10
        level = 1
        
        while level < n:
            
            for num in range(10):
                for reachable in moves[num]:
                    curr_level[reachable] += prev_level[reachable]
                    
            level += 1
            prev_level = curr_level
            curr_evel = [0] * 10
            print(sum(prev_level))
            
        return sum(prev_level)
        '''

class Solution:
    def knightDialer(self, n: int) -> int:
        moves = [[4, 6], [6, 8], [7, 9], [4, 8], [0, 3, 9], [], [0, 1, 7], [2, 6], [1, 3], [2, 4]]
        cur_count = [1] * 10 
        for _ in range(n-1):
            next_count = [0] * 10 
            for src_key in range(10):
                for dst_key in moves[src_key]:
                    next_count[dst_key] += cur_count[src_key]
                    
            cur_count = next_count
        
        return sum(cur_count) % 1000000007



class Solution:    
    def knightDialer(self, N: int) -> int:
        MOD = 1000000007
            
        if N == 1:
            return 10
        
        a, b, c, d = 1, 1, 1, 1
        for _ in range(N-1):
            a, b, c, d = (c + b) % MOD, (2*a + d) % MOD, (2*a) % MOD, (2*b) % MOD
            
        return (4 * a + 2 * b + 2 * c + d) % MOD


class Solution(object):
    def knightDialer(self, N):
        MOD = 10**9 + 7
        moves = [[4, 6], [6, 8], [7, 9], [4, 8], [3, 9, 0], [],
                 [1, 7, 0], [2, 6], [1, 3], [2, 4]]

        dp = [1] * 10
        for hops in range(N - 1):
            dp2 = [0] * 10
            for node, count in enumerate(dp):
                for nei in moves[node]:
                    dp2[nei] += count
                    dp2[nei] %= MOD
            dp = dp2
        return sum(dp) % MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 0:
            return 0
        if n == 1:
            return 10
        
        pad = {
            0: (4,6),
            1: (6, 8),
            2: (7,9),
            3: (4,8),
            4: (0, 3, 9),
            5: tuple(),
            6: (0,1,7),
            7: (2,6),
            8: (1,3),
            9: (2,4),
        }
        
        current = [0]*10
        prev = [1]*10

        for _ in range(n-1):
            current = [0]*10

            for key in range(10):
                for bro in pad[key]:
                    current[key] += prev[bro]
            prev = current
        
        return sum(current) %(10**9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        jump = {1:[6,8], 2:[7,9], 3:[4,8], 4:[0,3,9], 5:[],6:[0,1,7], 7:[6,2],8:[1,3],9:[4,2],0:[6,4]}
        dp = [1]*10
        for _ in range(n-1):
            new_dp = [0]*10
            for u in range(10):
                for v in jump[u]:
                    new_dp[v] += dp[u]
            dp = new_dp
        return sum(dp)%(10**9+7)

class Solution:
    def knightDialer(self, n: int) -> int:
        jump = {1:[6,8], 2:[7,9], 3:[4,8], 4:[0,3,9], 5:[],6:[0,1,7], 7:[6,2],8:[1,3],9:[4,2],0:[6,4]}
        dp = [1]*10
        for _ in range(n-1):
            new_dp = [0]*10
            for v in range(10):
                for u in jump[v]:
                    new_dp[v] += dp[u]
            dp = new_dp
        return sum(dp)%(10**9+7)

class Solution:
    def knightDialer(self, n: int) -> int:
        
        if n == 1:
            return 10
        
        transition = {
            0: [4, 6],
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [3, 9, 0],
            5: [],
            6: [1, 7, 0],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4]
        }
        
        vec = [1 for _ in range(10)]
        for n in range(1, n):
            new_vec = [0 for _ in range(10)]
            for i in range(0, 10):
                for j in transition[i]:
                    new_vec[j] = (new_vec[j] + vec[i]) % (1_000_000_000 + 7)
                    # print(new_vec, vec)
            vec = new_vec
        
        return sum(vec) % (1_000_000_000 + 7)

class Solution(object):
    def knightDialer(self, N):
        MOD = 10**9 + 7
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]

        dp = [1] * 10
        for hops in range(N-1):
            dp2 = [0] * 10
            for node, count in enumerate(dp):
                for nei in moves[node]:
                    dp2[nei] += count
                    dp2[nei] %= MOD
            dp = dp2
        return sum(dp) % MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        
        move = {0:[4,6], 1:[6,8], 2:[7,9], 3:[4,8], 4:[0,3,9],5:[],6:[1,7,0],7:[2,6],8:[1,3],9:[4,2]}
        
        pre = [1 for _ in range(10)]
        for i in range(n-1):
            new = [0 for _ in range(10)]
            for j in range(10):
                for k in move[j]:
                    new[k] += pre[j]%(10**9+7)
            pre = new
        
        return sum(pre)%(10**9+7)


class Solution:
    def knightDialer(self, n: int) -> int:
        mod = 10**9 + 7
        moves = [[4,6], [6,8], [7,9], [4,8], [0,3,9], [], [0,1,7], [2,6], [1,3], [2,4]]
        
        dp = [1]*10
        
        for i in range(n-1):
            new_dp = [0]*10
            
            for c, val in enumerate(dp):
                for j in moves[c]:
                    new_dp[j] += val
                    new_dp[j] %= mod
                    
                dp = new_dp
                
        return (sum(dp))%mod
        


class Solution:
    def knightDialer(self, n: int) -> int:
        
        MOD = 10**9 + 7
        # moves: each item is numbers which can move to idx number
        # e.g., 0 can move to 4 and 6
        moves = [(4,6),(6,8),(7,9),(4,8),(3,9,0),(),
                     (1,7,0),(2,6),(1,3),(2,4)]
        
        # dp[start] = f(start, n), n as idx in dp
        # f(start, n): starting from start and dial n times
        dp = [1] * 10 
        for hops in range(n-1):
            dp2 = [0] * 10
            for node, count in enumerate(dp): # node is number
                for nei in moves[node]:
                    dp2[nei] += count
                    dp2[nei] %= MOD
            dp = dp2
        return sum(dp) % MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10**9 + 7
        moves = [[4, 6], [6, 8], [7, 9], [4, 8], [3, 9, 0], [], 
                [1, 7, 0], [2, 6], [1, 3], [2, 4]]
        dp = [1] * 10
        for hops in range(n - 1):
            dp2 = [0] * 10
            for node, count in enumerate(dp):
                for neighbor in moves[node]:
                    dp2[neighbor] += count
                    dp2[neighbor] %= MOD
            dp = dp2
        return sum(dp) % MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10**9 + 7
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]

        dp = [1] * 10
        for hops in range(n-1):
            dp2 = [0] * 10
            for node, count in enumerate(dp):

                for nei in moves[node]:
                    
                    dp2[nei] += count
                    dp2[nei] %= MOD

     
            dp = dp2
        return sum(dp) % MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        dct = {1:[6, 8], 2:[7, 9], 3:[4, 8], 4:[0, 3, 9], 5:[], 6:[0, 1, 7], 7:[2, 6], 8:[1, 3], 9:[2, 4], 0:[4, 6]}
        
        dp = [1] * 10
        for _ in range(n - 1):
            nxt = [0] * 10
            for i in range(10):
                for j in dct[i]:
                    nxt[j] += dp[i]
            dp = nxt
        
        return sum(dp) % (10 ** 9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10**9 + 7
        if n == 1:
            return 10
        next_square = [[4,6], [6,8], [7,9], [4,8], [3, 9, 0], [], [0, 1, 7], [2,6], [1,3], [2,4], [4,6]]
        
        values = [1, 1, 1, 1, 1, 0, 1, 1, 1, 1]
        for i in range(1, n):
            next_values = [0] * 10
            for num in range(10):
                for square in next_square[num]:
                    next_values[square] += values[num]
                    next_values[square] %= MOD

            values = next_values[:]
            
        return sum(values) % MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10**9 + 7
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]

        dp = [1] * 10
        for hops in range(n-1):
            dp2 = [0] * 10
            for node, count in enumerate(dp):
                for nei in moves[node]:
                    dp2[nei] += count
                    dp2[nei] %= MOD
            dp = dp2
        return sum(dp) % MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        jump = {1:[6,8], 2:[7,9], 3:[8,4], 4:[0,9,3], 5:[], 6:[7,1,0], 7:[6,2], 8:[3,1], 9:[4,2], 0:[6,4]}
        
        dp = [1]*10
        for _ in range(n-1):
            nxt = [0]*10
            for i in range(10):
                for j in jump[i]:
                    nxt[j] += dp[i]
            dp = nxt
        return sum(dp)%(10**9+7)
    
    


class Solution:
    def knightDialer(self, n: int) -> int:
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]
        MOD = 10**9+7
        dp = [1]*10
        for jumps in range(n-1):
            temp = [0]*10
            for i in range(10):
                for nei in moves[i]:
                    temp[nei] += dp[i]
                    temp[nei] %= MOD
            dp = temp
        return sum(dp) % MOD


class Solution:
    def knightDialer(self, n: int) -> int:
        # # starting points have 10 possible locations
        # grid = [
        #     [1,2,3],
        #     [4,5,6],
        #     [7,8,9],
        #     [None,0,None]
        # ]
        # # DFS to search through all possibilities
        # X = len(grid)
        # Y = len(grid[0])
        # def dfs(x,y,remain,X=X,Y=Y,grid=grid):
        #     if x < 0 or x >= X or y < 0 or y >= Y or not grid[x][y] or remain == 0:
        #         return -1
        #     temp_step = 8
        #     temp_step += dfs(x-2,y+1,remain-1)
        #     temp_step += dfs(x-1,y+2,remain-1)
        #     temp_step += dfs(x+1,y+2,remain-1)
        #     temp_step += dfs(x+2,y+1,remain-1)
        #     temp_step += dfs(x+2,y-1,remain-1)
        #     temp_step += dfs(x+1,y-2,remain-1)
        #     temp_step += dfs(x-1,y-2,remain-1)
        #     temp_step += dfs(x-2,y-1,remain-1)
        #     self.step *= temp_step
        #     print(temp_step)
        #     return temp_step
        # total = 0
        # for i in range(X):
        #     for j in range(Y):
        #         if grid[i][j]:
        #             self.step = 0
        #             dfs(i,j,n)
        #             total += self.step
        # return total % (10**9+7)
        MOD = 10**9 + 7
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]

        dp = [1] * 10
        for hops in range(n-1):
            dp2 = [0] * 10
            for node, count in enumerate(dp):
                for nei in moves[node]:
                    dp2[nei] += count
                    dp2[nei] %= MOD
            dp = dp2
        return sum(dp) % MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        dp = [1] * 10
        states = {
            0: [4, 6],
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [0, 3, 9],
            5: [],
            6: [0, 1, 7],
            7: [2,6],
            8: [1,3],
            9: [2,4]
        }
        
        mod = int(1e9) + 7
        for i in range(n-1):
            dp1 = [0] * 10
            
            for j, st in list(states.items()):
                for k in st:
                    dp1[k] += dp[j]
                    dp1[k] %= mod
            dp = dp1
        return sum(dp) % mod
        


class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10**9 + 7
        if n == 1:
            return 10
        next_square = [[4,6], [6,8], [7,9], [4,8], [3, 9, 0], [], [0, 1, 7], [2,6], [1,3], [2,4], [4,6]]
        
        values = [1, 1, 1, 1, 1, 0, 1, 1, 1, 1]
        for i in range(1, n):
            next_values = [0] * 10
            for num in range(10):
                for square in next_square[num]:
                    next_values[square] += values[num]  
                    next_values[square] %= MOD

            values = next_values[:]
            
        return sum(values) % MOD

move_map = {
    0: {4,6},
    1: {6,8},
    2: {7,9},
    3: {4,8},
    4: {3, 9, 0},
    5: {},
    6: {1, 0, 7},
    7: {2, 6},
    8: {1, 3},
    9: {2, 4}
}

class Solution:    
    def knightDialer(self, n: int) -> int:
        if n == 1:
            return 10
        old_row = [1 for _ in move_map]
        new_row = [0 for _ in move_map]
        for N in range(2,n+1):
            new_row = [0 for _ in move_map]
            for key in move_map:
                res = 0
                for new_key in move_map[key]:
                    res += old_row[new_key]
                new_row[key] = res
            old_row = new_row
                
        return sum(new_row) % (10**9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        nxt = [[4, 6], [6, 8], [7, 9], [4, 8], [0, 3, 9], [], [0, 1, 7], [2, 6], [1, 3], [2, 4]]
        dp0 = [1] * 10
        
        for _ in range(1, n):
            dp1 = [0]*10
            for i in range(10):
                for j in nxt[i]:
                    dp1[j] += dp0[i]
            dp0[:] = dp1[:]
        
        return sum(dp0)%(10**9+7)


class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10**9 + 7
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]

        dp = [1] * 10
        for hops in range(n-1):
            dp2 = [0] * 10
            for node, count in enumerate(dp):
                for nei in moves[node]:
                    dp2[nei] += count
                    dp2[nei] %= MOD
            dp = dp2
        return sum(dp) % MOD


class Solution:
    def knightDialer(self, n: int) -> int:
        
        dialer_map = {0: [4, 6],
                      1: [6, 8],
                      2: [7, 9],
                      3: [4, 8],
                      4: [0, 3, 9],
                      5: [],
                      6: [0, 1, 7],
                      7: [2, 6],
                      8: [1, 3],
                      9: [2, 4]}

        level = [1 for i in range(10)]

        for i in range(1, n):
            next_level = [0 for i in range(10)]
            for l in range(10):
                for d in dialer_map[l]:
                    next_level[d]+=level[l]
                
            level = next_level
        
        return  sum(level)%(10**9+7)
                    
                    
            
        



#27

class Solution:
    def knightDialer(self, n: int) -> int:
        prev = [1] * 10
        
        fromMap = {1: {8,6}, 2: {7,9}, 3:{4,8}, 4: {0,3,9}, 5:{}, 6:{0,1,7}, 7:{2,6}, 8:{1,3}, 9:{2,4}, 0:{4,6}}
        
        for i in range(1,n):
            dp = [0] * 10
            for k in range(10):
                for j in fromMap[k]:
                    dp[k] += prev[j]
                    dp[k] %= 10**9 + 7
            
            prev = dp
        
        return sum(prev) % (10**9+7)

class Solution:
    def knightDialer(self, n: int) -> int:
        prev = [0] * 10
        dp = [1] * 10
        
        m = {
            0: [4, 6],
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [0, 3, 9],
            5: [],
            6: [0, 1, 7],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4]
        }
        def parents(x):
            return m[x]

        for l in range(1, n + 1):
            for x in range(10):
                for prevX in parents(x):
                    dp[x] = (dp[x] + prev[prevX]) % (10 ** 9 + 7)
            prev, dp = dp, [0] * 10
            

        return sum(prev) % (10 ** 9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        if not n:
            return 0
        if n == 1:
            return 10
        
        steps = [1] * 10
        
        mapping = {1: [6, 8], 2: [7, 9], 3: [4, 8], 4: [3, 9, 0], 5:[], 6:[1,7, 0], 7:[2, 6], 8:[1,3], 9:[2,4], 0:[4,6]}
        
        for i in range(2, n+1):
            newSteps = [0] * 10
            for i in range(10):
                for j in mapping[i]:
                    newSteps[i] += steps[j]
                    newSteps[i] %= 10**9 + 7
                    
                    
            steps = newSteps
            
        return sum(steps) % (10**9 + 7)            

class Solution:
    def knightDialer(self, n: int) -> int:
        mod = 10**9+7
        dc = {(x,1): 1 for x in range(10)}
        
        for i in range(1,n):
            dc[(0,i+1)] = (dc[(4,i)] + dc[(6,i)]) % mod 
            dc[(1,i+1)] = (dc[(6,i)] + dc[(8,i)]) % mod
            dc[(2,i+1)] = (dc[(7,i)] + dc[(9,i)]) % mod 
            dc[(3,i+1)] = (dc[(4,i)] + dc[(8,i)]) % mod 
            dc[(4,i+1)] = (dc[(0,i)] + dc[(3,i)] + dc[(9,i)]) % mod 
            dc[(5,i+1)] = 0 
            dc[(6,i+1)] = (dc[(0,i)] + dc[(1,i)] + dc[(7,i)]) % mod
            dc[(7,i+1)] = (dc[(2,i)] + dc[(6,i)]) % mod
            dc[(8,i+1)] = (dc[(1,i)] + dc[(3,i)]) % mod 
            dc[(9,i+1)] = (dc[(2,i)] + dc[(4,i)]) % mod
            
        res = 0
        for j in range(10):
            res = (res + dc[(j,n)]) % mod
        return res

class Solution:
    def knightDialer(self, n: int) -> int:
        dirs = {(-2, -1), (-1, -2), (1, -2), (2, -1),
                (2, 1), (1, 2), (-1, 2), (-2, 1)}
        prohibited = {(0, 3), (2, 3)}
        
        graph = {}
        result = [0] * (3 * 4)
        for i in range(3 * 4):
            x1 = i % 3
            y1 = i // 3
            graph[i] = []
            if (x1, y1) in prohibited:
                continue
            
            for j in range(3 * 4):
                x2 = j % 3
                y2 = j // 3

                if (x2 - x1, y2 - y1) in dirs and (x2, y2) not in prohibited:
                    graph[i].append(j)
            result[i] = 1
            
        # for k, v in graph.items():
        #     print(k, v)
        M = 10 ** 9 + 7
        for i in range(1, n):
            res_next = [0] * (3 * 4)
            for x in range(3 * 4):
                for adj in graph.get(x, []):
                    res_next[x] = (res_next[x] + result[adj]) % M
                    
            result = res_next
        # print(result)
        return sum(result) % M

class Solution:
    def knightDialer(self, n: int) -> int:
        KMOD = 10 ** 9 + 7
        moves = [[4,6], [8,6], [7,9], [4,8], [3,9,0], [], [1,7,0], [2,6], [1,3], [2,4]]
        # moves represet 4 and 6 can jump to 1 (index position)
        dp = [1 for _ in range(10)] # 10 keys
        for k in range(1, n):
            cur = [0 for _ in range(10)]
            for i in range(10): # for each key
                for from_key in moves[i]:
                    cur[from_key] += dp[i]
            dp = cur
        
        result = 0
        for i in range(10):
            result += dp[i]
        return result % KMOD

class Solution:
    def knightDialer(self, n: int) -> int:
        lis = [10, 20, 46, 104, 240, 544]
        if(n <= 6):
            return lis[n-1]
        for i in range(7, n+1):
            lis.append(6*lis[-2] - 4*lis[-4])
        return lis[-1]%(10**9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        '''
        0: 4,6
        1: 6,8
        2: 7,9
        3: 4,8
        4: 0,3,9
        5: None
        6: 1,7,0
        7: 2,6
        8: 1,3
        9: 2,4
        '''
        mod = 10**9+7
        nxt_pos = [[4,6],[6,8],[7,9],[4,8],[0,3,9],[],[1,7,0],[2,6],[1,3],[2,4]]
        dp = [1 for _ in range(10)] # dp[i] is the number of times of i be the last dialed number at step 1
        res = 10
        for _ in range(1,n):
            cur_dp = [0 for _ in range(10)]
            for val, times in enumerate(dp):
                for nxt in nxt_pos[val]:
                    cur_dp[nxt] += times
                    cur_dp[nxt] %= mod
            dp = cur_dp
            
        return sum(dp)%mod


class Solution:
    def knightDialer(self, n: int) -> int:
        numMoves = {}
        for i in range(10):
            numMoves[1, i] = 1
        for i in range(2,n+1):
            numMoves[i,1] = numMoves[i-1, 6] + numMoves[i-1, 8] % (10**9+7)
            numMoves[i,2] = numMoves[i-1, 7] + numMoves[i-1, 9] % (10**9+7)
            numMoves[i,3] = numMoves[i-1, 4] + numMoves[i-1, 8] % (10**9+7)
            numMoves[i,4] = numMoves[i-1, 3] + numMoves[i-1, 9] + numMoves[i-1,0] % (10**9+7)
            numMoves[i,5] = 0
            numMoves[i,6] = numMoves[i-1, 1] + numMoves[i-1, 7] + numMoves[i-1,0] % (10**9+7)
            numMoves[i,7] = numMoves[i-1, 2] + numMoves[i-1, 6] % (10**9+7)
            numMoves[i,8] = numMoves[i-1, 1] + numMoves[i-1, 3] % (10**9+7)
            numMoves[i,9] = numMoves[i-1, 2] + numMoves[i-1, 4] % (10**9+7)
            numMoves[i,0] = numMoves[i-1, 4] + numMoves[i-1, 6] % (10**9+7)
        totalMoves = 0
        for i in range(10):
            totalMoves += numMoves[n, i]
        return totalMoves % (10**9+7)

move_map = {
    0: {4,6},
    1: {6,8},
    2: {7,9},
    3: {4,8},
    4: {3, 9, 0},
    5: {},
    6: {1, 0, 7},
    7: {2, 6},
    8: {1, 3},
    9: {2, 4}
}

class Solution:    
    def knightDialer(self, n: int) -> int:
        if n == 1:
            return 10
        old_row = [1 for _ in move_map]
        new_row = [0 for _ in move_map]
        for N in range(2,n+1):
            for key in move_map:
                res = 0
                for new_key in move_map[key]:
                    res += old_row[new_key]
                new_row[key] = res
            for idx, n in enumerate(new_row):
                old_row[idx] = n
                
        return sum(new_row) % (10**9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        moves = [[4, 6], [6, 8], [7, 9], [4, 8], [0, 3, 9],
                 [], [0, 1, 7], [2, 6], [1, 3], [2, 4]]
        result = [1] * 10

        hops = 0
        while hops < n - 1:
            nextResult = [0] * 10
            for idx in range(len(result)):
                for step in moves[idx]:
                    nextResult[idx] += result[step]
            result = nextResult
            hops += 1

        return sum(result) % (10**9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        dp = [[1] * 10] + [[0] * 10 for _ in range(n-1)]
        
        for i in range(1, n):
            dp[i][1] += dp[i-1][8] + dp[i-1][6]
            dp[i][3]  = dp[i][1]
            
            dp[i][2] += dp[i-1][7] + dp[i-1][9]
            
            dp[i][4] += dp[i-1][9] + dp[i-1][3] + dp[i-1][0]
            dp[i][6]  = dp[i][4]
            
            dp[i][7] += dp[i-1][6] + dp[i-1][2]
            dp[i][9]  = dp[i][7]
            
            dp[i][8] += dp[i-1][1] + dp[i-1][3]
            
            dp[i][0] += dp[i-1][4] + dp[i-1][6]

        return sum(dp[-1]) % (10 ** 9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 7 + 10**9
        moves = [[4,6],[6,8],[7,9],[4,8],[0,3,9],[],[0,1,7],[2,6],[1,3],[2,4]]
        
        dp = [1] * 10
        
        for i in range(n-1):
            dp2 = [0] * 10
            for node, count in enumerate(dp):
                for neighbor in moves[node]:
                    dp2[neighbor] += count
                    dp2[neighbor] %= MOD
            
            dp = dp2
        
        return sum(dp) % MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        dp=[1]*10
        dic={0:[4,6],1:[8,6],2:[7,9],3:[4,8],4:[3,9,0],6:[1,7,0],7:[2,6],8:[1,3],9:[2,4]}
        
        
        for i in range(1,n):
            temp=dp
            dp=[0]*10
            for j in range(10):
                if j in dic:
                    for k in dic[j]:
                        dp[k]+=temp[j]
                        dp[k]%=(10**9 + 7)
            
                    
        return sum(dp)%(10**9 + 7)

class Solution:
    NEIGHBORS = (
            (4, 6),
            (6, 8),
            (7, 9),
            (4, 8),
            (0, 3, 9),
            (),
            (0, 1, 7),
            (2, 6),
            (1, 3),
            (2, 4)
    )
    
    cache = {}
            
    def get_neighbors(self, n: int) -> Tuple[int]:
        return self.NEIGHBORS[n]
    
    def knightDialer(self, n: int) -> int:
        results = 0
        prior = [1] * 10
        for _ in range(n - 1):
            current = [0] * 10
            for pos in range(10):
                for neighbor in self.get_neighbors(pos):
                    current[pos] += prior[neighbor] % 1000000007
            prior = current
                
        return sum(prior) % 1000000007

#     def traverse(self, pos: int, length: int) -> int:
#         if length == 1:
#             return 1
#         if (pos, length) in self.cache:
#             return self.cache[(pos, length)]
#         jumps = 0
#         for neighbor in self.get_neighbors(pos):
#             jumps += self.traverse(neighbor, length - 1)
            
#         jumps %= 1000000007
#         self.cache[(pos, length)] = jumps
#         return jumps


class Solution:
    def knightDialer(self, n: int) -> int:
        moves = [[4,6],[6,8],[7,9],[4,8],[0,3,9],[],[0,1,7],[2,6],[1,3],[2,4]]
        memo = [1]*10
        for i in range(n-1):
            memonext = [0]*10
            for j in range(10):
                for m in moves[j]:
                    memonext[m] += memo[j]
                    #print(memonext,m)
            for j in range(10):
                memo[j] = memonext[j]
            #print(memo)
        return sum(memo) % (10**9 + 7)

'''
 0. 1. 2. 3. 4. 5. 6. 7. 8. 9
[2, 2, 2, 2, 3, 0, 3, 2, 2, 2]
[6, 5, 0, 0, 0, 0, 0, 0, 0, 0]

[6, 5, 4, 5, 6, 0, 6, 5, 4, 5]


'''
class Solution(object):
    def knightDialer(self, N):
        MOD = 10**9 + 7
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]

        dp = [1] * 10
        for hops in range(N-1):
            dp2 = [0] * 10
            for node, count in enumerate(dp):
                for nei in moves[node]:
                    dp2[nei] += count
            dp = dp2
        print(dp)
        return sum(dp) % MOD

class Solution:
    def knightDialer(self, n: int) -> int:

        mod = 10**9+7
        nxt_pos = [[4,6],[6,8],[7,9],[4,8],[0,3,9],[],[1,7,0],[2,6],[1,3],[2,4]]
        dp = [1 for _ in range(10)]
        for _ in range(1,n):
            new_dp = [0 for _ in range(10)]
            for val,times in enumerate(dp):
                for i in nxt_pos[val]:
                    new_dp[i] += times
                    new_dp[i] %= mod
            dp = new_dp
        return sum(dp)%mod


class Solution:
    def knightDialer(self, N: int) -> int:
        
        moves = {1: {6,8}, 2: {9,7}, 3: {8,4}, 4: {3,9,0}, 5: {}, 6: {1,7,0}, 7: {2,6}, 8: {1,3}, 9:{2,4}, 0: {4,6}}
        # N = 2
        dp = [1] * 10
        
        
        for i in range(2, N+1):
            newDp = [0] * 10
            for j in range(10):
                for conn in moves[j]:
                    newDp[conn] += dp[j] % (10**9 + 7)
            
            dp = newDp
        
        print(dp)
        return sum(dp) % (10**9 + 7)
        


class Solution:
    def knightDialer(self, n: int) -> int:
        res = 0
        path = {0:[4,6], 1:[6,8], 2:[7,9], 3:[4,8], 4:[3,9,0], 5:[], 6:[1,7,0], 7:[2,6], 8:[1,3], 9:[2,4]}
        dp = [1]*10
        MOD = 10**9 + 7
        
        for i in range(2,n+1):
            dp2 = [0]*10
            for j in range(10):
                for p in path[j]:
                    dp2[j] += dp[p]
                # dp[j] %= MOD
            dp = dp2
        res = sum(dp)
        
        return res%MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        reachFrom = {1: [8,6], 2: [7,9], 3: [4,8], 4: [0,9,3], 5:[], 6: [0,1,7], 7: [2,6], 8: [1,3], 9: [2, 4], 0: [4,6]}
        prevdp = [1 for _ in range(10)]
        curdp = [0 for _ in range(10)]
        for iteration in range(1, n):
            curdp = [0 for _ in range(10)]
            for i in range(10): 
                for nbor in reachFrom[i]:
                    curdp[i] += prevdp[nbor]
            prevdp = curdp.copy()
        ans = 0
        for i in range(10):
            ans += prevdp[i]
        return ans%(10**9 + 7)
            


class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10**9 + 7
        if n == 1:
            return 10
        next_square = [[4,6], [6,8], [7,9], [4,8], [3, 9, 0], [], [0, 1, 7], [2,6], [1,3], [2,4], [4,6]]
        
        values = [1, 1, 1, 1, 1, 0, 1, 1, 1, 1]
        for i in range(1, n):
            next_values = [0] * 10
            for num in range(10):
                for square in next_square[num]:
                     
                    next_values[square] %= MOD
                    next_values[square] += values[num] 

            values = next_values[:]
            
        return sum(values) % MOD

class Solution:
    def knightDialer(self, N: int) -> int:
        steps = {1: [6, 8], 2: [7, 9], 3: [4, 8], 4: [3, 9, 0],5: [], 6: [1, 7, 0], 7: [2, 6], 8: [1, 3], 9: [2, 4], 0: [4, 6]}
        ret = set()
        def DFS(cur, i):
            if i == N:
                n = 0
                for c in cur:
                    n = n * 10 +c
                ret.add(n)
                print(n)
                return
            for n in steps[cur[-1]]:
                DFS(cur+[n], i+1)
            return
        for k in list(steps.keys()):
            DFS([k], 1)
        return len(ret)
        
class Solution:
    def knightDialer(self, N: int) -> int:
        steps = {1: [6, 8], 2: [7, 9], 3: [4, 8], 4: [3, 9, 0], 5: [], 6: [1, 7, 0], 7: [2, 6], 8: [1, 3], 9: [2, 4], 0: [4, 6]}
        dp = [1 for _ in range(10)]
        for _ in range(N-1):
            cur = [0 for _ in range(10)]
            for i in range(10):
                for j in steps[i]:
                    cur[j] += dp[i]
            dp = cur
        return sum(dp) % (10**9 +7)
                    


class Solution:
    def knightDialer(self, n: int) -> int:
        '''
        0: 4,6
        1: 6,8
        2: 7,9
        3: 4,8
        4: 0,3,9
        5: None
        6: 1,7,0
        7: 2,6
        8: 1,3
        9: 2,4
        '''
        mod = 10**9+7
        nxt_pos = [[4,6],[6,8],[7,9],[4,8],[0,3,9],[],[1,7,0],[2,6],[1,3],[2,4]]
        dp = [1 for _ in range(10)]
        for _ in range(1,n):
            new_dp = [0 for _ in range(10)]
            for val,times in enumerate(dp):
                for i in nxt_pos[val]:
                    new_dp[i] += times
                    new_dp[i] %= mod
            dp = new_dp
        return sum(dp)%mod


class Solution:
    def knightDialer(self, n: int) -> int:
#         mappings = [[4,6], [6,8], [7,9], [4,8], [0,3,9], [], [1,7,0], [2,6], [1,3], [2,4]]
#         total = 0
#         MOD = 10**9 + 7
        
#         for s in range(0, 10):
#             last = collections.deque([s])
#             for i in range(2, n+1):
#                 length = len(last)
#                 for j in range(length):
#                     number = last.pop()
#                     last.extendleft([] + mappings[number])
#             total+=len(last)

#         return total % MOD

        mappings = [[4,6], [6,8], [7,9], [4,8], [0,3,9], [], [1,7,0], [2,6], [1,3], [2,4]]
        mod = 10**9 + 7
        dp = [1] * 10

        for digit in range(2, n+1):
            dp2 = [0] * 10
            for startNumber, counter in enumerate(dp2):
                for x in mappings[startNumber]:
                    dp2[startNumber] += dp[x]
                    dp2[startNumber]
            dp = dp2
        return sum(dp)%mod
    
            


class Solution:
    def knightDialer(self, n: int) -> int:
        pos_map = {0:[4,6], 1: [6,8], 2:[7,9], 3:[4,8], 4:[0,3,9],5:[], 6:[0,1,7], 7:[2,6], 8:[1,3], 9:[2,4]}
        num_vals = [1 if i != 5 else 0 for i in range(10)]
        mod_val = 10**9+7
        if n == 1:
            return 10
        else:
            for num in range(1,n):
                temp = [0 for i in range(10)]
                for i, count in enumerate(num_vals):
                    for val in pos_map[i]:
                        temp[val] += count
                num_vals = temp
        return sum(num_vals)%mod_val


from collections import deque


class Solution:
    
    def knightDialer(self, n: int) -> int:
        neighborMap = {
            1: (6,8),
            2: (7,9),
            3: (4,8),
            4: (3,9,0),
            5: (),
            6: (1,7,0),
            7: (2,6),
            8: (3,1),
            9: (2,4),
            0: (4,6)
        }
        
        
        def neighbors(pos):
            return neighborMap[pos]
    
        
        def countSeq():
            prevMoves = [1] * 10
            curMoves = [0] * 10
            curN = 1
            
            while curN < n:
                curMoves = [0] * 10
                curN += 1
                
                for pos in range(10):
                    for neighbor in neighbors(pos):
                        curMoves[pos] += prevMoves[neighbor]
                prevMoves = curMoves
                
            curMoves = prevMoves
            # print(curMoves)
            return sum(curMoves)
        
        # totalSeq = 0
        # for curPos in range(10):
        #     totalSeq += countSeq(curPos)
        
        return countSeq() % (10**9 + 7)
        
    
    
# Prev implementation
#     def knightDialer(self, n: int) -> int:
#         def inPad(row, col):
#             if row >= 0 and row < 3 and col >= 0 and col < 3 or (row == 3 and col == 1):
#                 return True
#             return False
            
#         dRows = [1,-1,1,-1,2,-2,2,-2]
#         dCols = [2,2,-2,-2,1,-1,-1,1]
        
#         q = deque()
#         q.append((3,1,n-1))
        
#         for i in range(3):
#             for j in range(3):
#                 q.append((i,j, n-1))
        
#         distinctNums = 0
#         while q:
#             cur = q.popleft()
            
#             if cur[2] == 0:
#                 distinctNums += 1
#                 continue

#             for dRow, dCol in zip(dRows, dCols):
#                 newRow, newCol = cur[0] + dRow, cur[1] + dCol

#                 if inPad(newRow, newCol):
#                     q.append((newRow, newCol, cur[2] - 1))

#         return distinctNums % (10**9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        prev = [0] * 10
        dp = [1] * 10
        
        m = {
            0: [4, 6],
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [0, 3, 9],
            5: [],
            6: [0, 1, 7],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4]
        }
        def parents(x):
            return m[x]

        for l in range(1, n + 1):
            for x in range(10):
                for prevX in parents(x):
                    dp[x] += prev[prevX]
            prev, dp = dp, [0] * 10
            

        return sum(prev) % (10 ** 9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
#         mod = 10**9 + 7

#         d = dict()
#         d[0] = {4, 6}
#         d[1] = {6, 8}
#         d[2] = {7, 9}
#         d[3] = {4, 8}
#         d[4] = {0, 3, 9}
#         d[6] = {0, 1, 7}
#         d[7] = {2, 6}
#         d[8] = {1, 3}
#         d[9] = {2, 4}
        
#         memo = [[0]*10 for i in range(n+1)]
#         memo[1] = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
        
#         for i in range(2, n+1):
#             for key, val in d.items():
#                 for v in val:
#                     memo[i][key] += memo[i-1][v]
        
#         return sum(memo[-1])%mod
    
        MOD = 10**9 + 7
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]

        dp = [1] * 10
        for hops in range(n-1):
            dp2 = [0] * 10
            for node, count in enumerate(dp):
                for nei in moves[node]:
                    dp2[nei] += count
                    dp2[nei] %= MOD
            dp = dp2
        return sum(dp) % MOD
        
        


# deem the jumps as path from a dummy starting node to each level of a tree. Count the number of nodes in each level

# method 1
# dynamic programming
# time complexity: O(n)
class Solution:
    def knightDialer(self, n: int) -> int:
        d = {0:(4,6),
             1:(6,8), 
             2:(7,9),
             3:(4,8),
             4:(0,3,9),
             5:(),
             6:(0,1,7),
             7:(2,6),
             8:(1,3),
             9:(2,4)}
        
        # start from a dummy node, from which we can reach every node 0-9
        # count the number of nodes in each level
        # if prev_level[i] = freq, then there {freq} nodes that equals {i} in that level
        prev_level = {i:1 for i in range(10)} # level 1
        for j in range(1,n):
            curr_level = defaultdict(int)
            for i,freq in list(prev_level.items()):
                for child in d[i]:
                    curr_level[child] += freq
            prev_level = curr_level
        
        return sum(prev_level.values()) % (10**9 + 7)
            


class Solution:
    def knightDialer(self, n: int) -> int:
        possible_paths = {1: [6, 8], 2: [7, 9], 3: [4,8], 4: [0, 3, 9], 5: [],
                          6: [0, 1,7], 7: [2, 6], 8: [1, 3], 9: [2, 4], 0: [4, 6]}
        dp = [1] * 10
        for i in range(n-1):
            temp = [0] * 10
            for start_num in range(10):
                for target_num in possible_paths[start_num]:
                    temp[target_num] += dp[start_num]
            dp = temp

        return sum(dp) % (7 + 10**9)

class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 1:
            return 10
        
        graph = {0: [4, 6], 1: [6, 8], 2: [7, 9], 3: [4, 8], 4: [0, 3, 9], 5: [], 6: [0, 1, 7], 7: [2, 6], 8: [1, 3], 9: [2, 4]}
        MOD = 1000000007
        prev = [1,1,1,1,1,0,1,1,1,1]
        for _ in range(n-1):
            val = [0] * 10
            for i in range(10):
                for x in graph[i]:
                    val[x] += prev[i]
            prev = val
        return sum(prev) % MOD


class Solution:
    def knightDialer(self, n):
        dmap = [[4, 6], [8, 6], [7, 9], [8, 4], [3, 9, 0], [], [1, 7, 0], [2, 6], [1, 3], [2, 4],[4, 6]]
        mod_val = 10 ** 9 + 7
        ans = 0
        dp = [[0]*10 for _ in range(n+1)]
        for i in range(10):
            dp[1][i] = 1
        for i in range(2, n+1):
            for j in range(0, 10):
                tv = dmap[j]
                for t in tv:
                    dp[i][j] += dp[i-1][t] % mod_val
        #print(dp)
        ans = sum(dp[n]) % mod_val
        return ans


class Solution:
    def knightDialer(self, n: int) -> int:
        mod = 1000000007
        if n == 0:
            return 0
        dict = {}
        dict[1] = [6, 8]
        dict[2] = [7, 9]
        dict[3] = [4, 8]
        dict[4] = [3, 9, 0]
        dict[5] = []
        dict[6] = [1, 7, 0]
        dict[7] = [2, 6]
        dict[8] = [1, 3]
        dict[9] = [2,4]
        dict[0] = [4,6]
        dp = [0] * 10
        for i in range(10):
            dp[i] = [0] * (n + 1)
        for i in range(10):
            dp[i][0] = 0
            dp[i][1] = 1
        sum = 0
        for j in range(2, n+1):
            for i in range(10):
                for k in dict[i]:
                    dp[i][j] = (dp[i][j] + dp[k][j - 1]) % mod
                
        for i in range(0, 10):
            sum = (sum + dp[i][n]) % mod
        return sum % mod
            


import numpy as np
class Solution:
    def knightDialer(self, N: int) -> int:
        
        mod = 10**9 + 7
        moves = np.matrix([[0, 0, 0, 0, 1, 0, 1, 0, 0, 0],
                       [0, 0, 0, 0, 0, 0, 1, 0, 1, 0],
                       [0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
                       [0, 0, 0, 0, 1, 0, 0, 0, 1, 0],
                       [1, 0, 0, 1, 0, 0, 0, 0, 0, 1],
                       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                       [1, 1, 0, 0, 0, 0, 0, 1, 0, 0],
                       [0, 0, 1, 0, 0, 0, 1, 0, 0, 0],
                       [0, 1, 0, 1, 0, 0, 0, 0, 0, 0],
                       [0, 0, 1, 0, 1, 0, 0, 0, 0, 0]])
        
        res = [[1]*10]

        N -= 1
        while N:
            if N % 2 != 0: 
                res = res * moves % mod     
                N -= 1
            else:
                moves = moves * moves % mod
                N //= 2
        return int(np.sum(res)) % mod
                
        


class Solution:
    def knightDialer(self, n: int) -> int:
        # dp[i, j] = # of distinct phone numbers of length j that can be dialed starting at i
        # dp[i, 1] = 1
        # dp[i, j] = sum(dp[i-1, k]) where k are all the possible numbers the knight can jump to
        if n == 1:
            return 10
        dp_old = [1 for _ in range(10)]
        dp_new = [0 for _ in range(10)]
        possible_next_digits = {
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [0, 3, 9],
            5: [],
            6: [0, 1, 7],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4],
            0: [4, 6]
        }
        for _ in range(n-1):
            
            for j in range(10):
                dp_new[j] = 0
                for digit in possible_next_digits[j]:
                    dp_new[j] += dp_old[digit]
            for j in range(10):
                dp_old[j] = dp_new[j]

        total = 0
        for num in dp_new:
            total += num
        return total % (10**9 + 7)
        
# 1 1 1 1 1 1 1 1 1
#


class Solution:
    def knightDialer(self, N):
    # Neighbors maps K: starting_key -> V: list of possible destination_keys
        neighbors = {
            0:(4,6),
            1:(6,8),
            2:(7,9),
            3:(4,8),
            4:(0,3,9),
            5:(),
            6:(0,1,7),
            7:(2,6),
            8:(1,3),
            9:(2,4)
        }
        current_counts = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
        for _ in range(N-1):
            next_counts = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
            for src_key in range(10):
                for dst_key in neighbors[src_key]:
                    next_counts[dst_key] = (next_counts[dst_key] + current_counts[src_key]) % (10**9 + 7)
            current_counts = next_counts
        return sum(current_counts) % (10**9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        # dp[i, j] = # of distinct phone numbers of length j that can be dialed starting at i
        # dp[i, 1] = 1
        # dp[i, j] = sum(dp[i-1, k]) where k are all the possible numbers the knight can jump to
        if n == 1:
            return 10
        possible_next_digits = {
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [0, 3, 9],
            5: [],
            6: [0, 1, 7],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4],
            0: [4, 6]
        }
        dp = [1 for _ in range(10)]
        dp_next = [0 for _ in range(10)]

        for _ in range(n-1):
            for j in range(10):
                dp_next[j] = 0
                for digit in possible_next_digits[j]:
                    dp_next[j] += dp[digit]
            for j in range(10):
                dp[j] = dp_next[j]

        total = 0
        for num in dp:
            total += num
        return total % (10**9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 1:
            return 10
        
        mod = 10**9+7
        dc = {
              (0,1): 1,
              (1,1): 1,
              (2,1): 1,
              (3,1): 1,
              (4,1): 1,
              (5,1): 1,
              (6,1): 1,
              (7,1): 1,
              (8,1): 1,
              (9,1): 1,
             }
        
        for i in range(n-1):
            dc[(0,i+2)] = (dc[(4,i+1)] + dc[(6,i+1)]) % mod 
            dc[(1,i+2)] = (dc[(6,i+1)] + dc[(8,i+1)]) % mod
            dc[(2,i+2)] = (dc[(7,i+1)] + dc[(9,i+1)]) % mod 
            dc[(3,i+2)] = (dc[(4,i+1)] + dc[(8,i+1)]) % mod 
            dc[(4,i+2)] = (dc[(0,i+1)] + dc[(3,i+1)] + dc[(9,i+1)]) % mod 
            dc[(5,i+2)] = 0 
            dc[(6,i+2)] = (dc[(0,i+1)] + dc[(1,i+1)] + dc[(7,i+1)]) % mod
            dc[(7,i+2)] = (dc[(2,i+1)] + dc[(6,i+1)]) % mod
            dc[(8,i+2)] = (dc[(1,i+1)] + dc[(3,i+1)]) % mod 
            dc[(9,i+2)] = (dc[(2,i+1)] + dc[(4,i+1)]) % mod
            
        res = 0
        for j in range(10):
            res = (res + dc[(j,n)]) % mod
        return res

class Solution:
    def knightDialer(self, n: int) -> int:
        prev = [0] * 10
        dp = [1] * 10
        
        m = {
            0: [4, 6],
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [0, 3, 9],
            5: [],
            6: [0, 1, 7],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4]
        }
        def parents(x):
            return m[x]

        for l in range(1, n + 1):
            for x in range(10):
                for prevX in parents(x):
                    dp[x] += prev[prevX]
                    dp[x] = dp[x] % (10 ** 9 + 7)
            prev, dp = dp, [0] * 10
            

        return sum(prev) % (10 ** 9 + 7)

class Solution:
    moveMap = {
        0: [4, 6],
        1: [8,6],
        2: [7,9],
        3: [8,4],
        4: [3,9,0],
        5: [],
        6: [1,7,0],
        7: [2,6],
        8: [1,3],
        9: [2,4]
    }
    
    def nextMoves(self, n: int):
        return self.moveMap[n]
        
    def knightDialer(self, n: int) -> int:
        modulo = 1000000007
        if n<0:
            return 0
        counts = [1]*10
        moves = len(self.moveMap)
        while n>1:
            newCounts = [0]*10
            for i in range(moves):
                for m in self.nextMoves(i):
                    newCounts[m] += counts[i]
            counts = newCounts
            n -= 1
        return sum(counts) % modulo
        


class Solution:
    def knightDialer(self, n: int) -> int:
        num_map = {
            0: [4, 6],
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [0, 3, 9],
            5: [],
            6: [0, 1, 7],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4]
        }
        table = [[0 for _ in range(10)] for _ in range(2)]
        for j in range(10):
            table[0][j] = 1
            
        for i in range(1, n):
            for j in range(10):
                sum_d = 0
                for d in num_map[j]:
                    sum_d += table[(i-1)%2][d]
                table[i%2][j] = sum_d
        
        
        return sum(table[(n-1)%2]) % (1000000007)
        


class Solution:
    # 5 can only show up as the last number
    def knightDialer(self, n: int) -> int:
        from collections import defaultdict
        dct = {1:[6,8], 2:[7,9], 3:[4,8], 4:[3,9,0], 5:[], 6:[1,7,0], 7:[2,6], 8:[1,3], 9:[2,4], 0:[4,6]}
        dp = {1:1, 2:1, 3:1, 4:1, 5:1, 6:1, 7:1, 8:1, 9:1, 0:1}   # number: curr_sum
        n -= 1
        
        while n > 0:
            new_dp = defaultdict(int)
            for num1 in dp:
                for num2 in dct[num1]:
                    new_dp[num2] += dp[num1]
            dp = new_dp
            n -= 1
        
        ans = 0
        for key in dp:
            ans += dp[key]
        return ans % (10**9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        M = 10**9 + 7
        moves = {0: [4,6], 1: [6,8], 2: [7,9], 3: [4,8], 4: [3,9,0],
                 5: [], 6: [1,7,0], 7: [2,6], 8: [1,3], 9: [2,4]}
        
        # f(start, n) = number of ways to build an n-digit number starting
        # at number start
        # prior_n[i] = number of ways to build a 1-digit no. starting at i
        prior_n = [1] * 10
        
        # repeat process to generate array that gives number of 
        # ways to build 2, 3, ... , n digit numbers starting at i
        for hops in range(2, n + 1):
            curr_n = [0] * 10
            # build on prior n results
            for num, count in enumerate(prior_n):
                # looking at numbers generated when we move nbr --> num --> ...
                for nbr in moves[num]:
                    curr_n[nbr] += count
                    curr_n[nbr] %= M
                    
            # curr n becomes prior n
            prior_n = curr_n
        # return the sum of all n digit phone nums that can be created
        # by starting at num 0, 1, ... , 9
        return sum(prior_n) % M

class Solution:
    def knightDialer(self, n: int) -> int:
        validJumps = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]
        memo = [[0 for _ in range(n + 1)] for _ in range(10)]
        
        for i in range(len(memo)):
            memo[i][1] = 1
            
        for j in range(2, n + 1):
            for i in range(len(memo)):
                for k in validJumps[i]:
                    memo[i][j] = (memo[i][j] + memo[k][j - 1]) % (10**9 + 7)
            
        ans = 0
        for i in range(10):
            ans = (ans + memo[i][n]) % (10**9 + 7)
        return ans

from functools import lru_cache

mapping = [
            [4, 6], # 0
            [6, 8], # 1
            [7, 9], # 2
            [4, 8], # 3
            [0, 3, 9], # 4
            [], # 5
            [0, 1, 7], # 6
            [2, 6], # 7
            [1, 3], # 8
            [2, 4] # 9
        ]

mod = 1000_000_007

@lru_cache(None)
def f(n: int, d: int) -> int:
    if n == 1: return 1
    s = 0
    
    for d1 in mapping[d]:
        s = (s + f(n - 1, d1)) % mod
    return s
        
class Solution:        
    def knightDialer(self, N: int) -> int:                
        tot = 0
        for d in range(10):
            tot = (tot + f(N, d)) % mod
            
        return tot

class Solution:
    def knightDialer(self, n: int) -> int:
        # dp[i, j] = # of distinct phone numbers of length j that can be dialed starting at i
        # dp[i, 1] = 1
        # dp[i, j] = sum(dp[i-1, k]) where k are all the possible numbers the knight can jump to
        if n == 1:
            return 10
        dp = [1 for _ in range(10)]
        possible_next_digits = {
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [0, 3, 9],
            5: [],
            6: [0, 1, 7],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4],
            0: [4, 6]
        }
        for _ in range(n-1):
            dp_next = [0] * 10
            for j in range(10):
                dp_next[j] = 0
                for digit in possible_next_digits[j]:
                    dp_next[j] += dp[digit]
            for j in range(10):
                dp[j] = dp_next[j]

        total = 0
        for num in dp:
            total += num
        return total % (10**9 + 7)


'''
'''
class Solution:
    def knightDialer(self, n: int) -> int:
        adj_lists = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],[1,7,0],[2,6],[1,3],[2,4]] #adj_lists[i] are the neighbors of digit i
        table = [[1]*10 for i in range(n)] #table[n][digit] is the number of solutions for length `n+1` starting at digit
        #table is already initialized for n=1
        
        for n0 in range(1,n):
            for digit in range(10):
                acc = 0
                for adj in adj_lists[digit]:
                    acc += table[n0-1][adj]
                table[n0][digit] = acc
        
        return sum(table[n-1]) % (10**9+7)


from collections import defaultdict
class Solution:
    def knightDialer(self, n: int) -> int:
        _nextMove = {0 : [4 ,6], 1: [6, 8], 2: [7, 9], 3: [4, 8], 4: [0, 3, 9], 5:[],
                    6: [0, 1, 7], 7: [2, 6], 8:[1, 3], 9: [2, 4]}
        
        moves = {i : 1 for i in range(10)}
        
        while n > 1:
            newmoves = defaultdict(int)
            for k, v in moves.items():
                for _next in _nextMove[k]:
                    newmoves[_next] += v
            moves = newmoves
            n -= 1
        
        
        
        
        
        return sum(moves.values()) % (10 ** 9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        positions = [
            [4, 6],
            [6, 8],
            [7, 9],
            [4, 8],
            [0, 3, 9],
            [],
            [0, 1, 7],
            [2, 6],
            [1, 3],
            [2, 4]
        ]
        
        dp = [[0 for i in range(n + 1)] for i in range(10)]
        
        for i in range(10):
            dp[i][1] = 1
        
        for j in range(2, n + 1):
            for i in range(10):
                for pos in positions[i]:
                    dp[i][j] = (dp[i][j] + dp[pos][j - 1]) % 1000000007
        
        result = 0
        
        for i in range(10):
            result = (result + dp[i][n]) % 1000000007
        
        return result

class Solution:
    def knightDialer(self, n: int) -> int:
        if n==0:
            return 0
        dic = {0: (4, 6),
               1: (8, 6),
               2: (7, 9),
               3: (4, 8),
               4: (3, 9, 0),
               5: (),
               6: (1, 7, 0),
               7: (2, 6),
               8: (1, 3),
               9: (2, 4)}
        dp = [1]*10
        for _ in range(n-1):
            new = [0]*10
            for i in range(10):
                for nei in dic[i]:
                    new[i] += dp[nei]
                    new[i] %= (10**9+7)
            dp = new
        
        return sum(dp)%(10**9+7)

MOD = 10**9 + 7

num_to_next = {
    1: [6, 8],
    2: [7, 9],
    3: [4, 8],
    4: [3, 9, 0],
    5: [],
    6: [1, 7, 0],
    7: [2, 6],
    8: [1, 3],
    9: [2, 4],
    0: [4, 6],
}


class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 0:
            return 0
        
        dp = [1 for _ in range(10)]
        for _ in range(n-1):
            next_dp = [0 for _ in range(10)]
            for current in range(10):
                for next_pos in num_to_next[current]:
                    next_dp[next_pos] += dp[current]
                    next_dp[next_pos] = next_dp[next_pos] % MOD
            dp = next_dp
            
        return sum(dp) % MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10**9 + 7
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]

        dp = [1] * 10
        for hops in range(n-1):
            dp2 = [0] * 10
            for node, count in enumerate(dp):
                for nei in moves[node]:
                    dp2[nei] += count
                    dp2[nei] %= MOD
            dp = dp2
        return sum(dp) % MOD
    
        '''
        1  2  3
        4  5  6
        7  8  9
        -1 0 -1
        
        def dfs(d, x, y):
            if d == n:
                ans.append()
            # check x, y
            x + 2, y + 1, y - 1
            x - 2, y + 1, y - 1
            y + 2, x + 1, x - 1
            y - 2, x + 1, x - 1
            (2, 1), (2, -1), (-2, 1), (-2, -1), (1, 2), (-1, 2), (1, -2), (-1, -2)
            dfs(d + 1, nx, ny)
        
        '''
#         def dfs(d, x, y):
#             nonlocal ans
#             if d == n:
#                 ans += 1
#                 return 
#             for dx, dy in directions:
#                 nx, ny = x + dx, y + dy
#                 if nx < 0 or nx > M - 1 or ny < 0 or ny > N - 1 or matrix[nx][ny] == -1:
#                     continue
#                 dfs(d + 1, nx, ny)
                    
#         matrix = [[1, 2, 3], 
#                   [4, 5, 6],
#                   [7, 8, 9],
#                   [-1, 0, -1]]
#         M, N = len(matrix), len(matrix[0])
#         directions = [(2, 1), (2, -1), (-2, 1), (-2, -1), (1, 2), (-1, 2), (1, -2), (-1, -2)]
#         ans = 0
#         for i in range(M):
#             for j in range(N):
#                 if matrix[i][j] != -1:
#                     dfs(1, i, j)
#         return ans % (10**9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        
        MOD = 10**9 + 7
        dp = [1] * 10
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]
        
        for hop in range(n - 1):
            dp2 = [0] * 10
            for i, move in enumerate(moves):
                count = dp[i]
                for pos in move:
                    dp2[pos] += count
                    dp2[pos] %= MOD
            dp = dp2
        return sum(dp) % MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        if n==1:
            return 10
        numpad = {'0':['4','6'],'1':['6','8'],'2':['7','9'],'3':['4','8'],'4':['0','3','9'],'6':['0','1','7'],'7':['2','6'],'8':['1','3'],'9':['4','2']}
        dp={}
        for i in ['0','1','2','3','4','6','7','8','9']:
            dp[i]=[]
            dp[i].append(1)
        for i in range(1,n):
            for j in ['0','1','2','3','4','6','7','8','9']:
                dp[j].append(0)
                for k in numpad[j]:
                    dp[j][i]+=dp[k][i-1]
                dp[j][i]%=(1000000007)
        res=0
        for i in ['0','1','2','3','4','6','7','8','9']:
            res+=dp[i][n-1]
            res%=(1000000007)
        return res

import collections
class Solution:
    def knightDialer(self, m: int) -> int:
        MOD=10**9+7
        n={0:[4,6], 1:[6,8], 2:[7,9],3:[4,8],4:[0,3,9] ,5:[] ,6:[0,1,7] ,7:[2,6],8:[1,3],9:[2,4]}
        
        end={}
        for ab in range(10):
            end[ab]=1
        for a in range(1,m):
            
            end2={}
            for ab in range(10):
                end2[ab]=0
            
            
            for key in range(10):
                val=n[key]
                # print(val)
                for c in val:
                    end2[key]+=end[c]
                # print(end2)
            end=end2
        return (sum(end.values()))%MOD


import logging

LOG = logging.getLogger(__name__)
MODULO = 10**9 + 7

class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 1:
            return 10

        counts = [2, 2, 3, 2]
        for _ in range(n-2):
            next_counts = [
                (counts[1] + counts[2]),
                (2 * counts[0]),
                (2 * counts[0] + counts[3]),
                (2 * counts[2])
            ]

            counts= next_counts

        return (4 * counts[0] + 2 * counts[1]  + 2 * counts[2]  + counts[3]) % MODULO


class Solution:
   
        
        
    
    def knightDialer(self, n: int) -> int:
        MOD = 10**9 + 7
        if n==1:
            return 10
        neighbors={
            0: (4,6),
            1: (6,8),
            2: (7,9),
            3: (8,4),
            4: (3,9,0),
            5: tuple(),
            6: (7,1,0),
            7: (2,6),
            8: (1,3),
            9: (4,2),
        }
            
        prev_jump=[1]*10
        curr_jump=[0]*10
        jump=0
        
        for jump in range(0,n-1):
            curr_jump=[0]*10
            for num in range(0,10):
                for i in neighbors[num]:
                    curr_jump[i]+=prev_jump[num]
                    curr_jump[i]%=MOD
            prev_jump=curr_jump
 
        return sum(curr_jump)%MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        num_map = {
            0: [4, 6],
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [0, 3, 9],
            5: [],
            6: [0, 1, 7],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4]
        }
        table = [[0 for _ in range(10)] for _ in range(n)]
        for j in range(10):
            table[0][j] = 1
            
        for i in range(1, n):
            for j in range(10):
                sum_d = 0
                for d in num_map[j]:
                    sum_d += table[i-1][d]
                table[i][j] = sum_d
        
        
        return sum(table[n-1]) % (1000000007)
        


class Solution:
    def knightDialer(self, N: int) -> int:
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                 [1,7,0],[2,6],[1,3],[2,4]]
        
        
        # dp[i] denotes the number of combinations starting from i
        dp = [1] * 10
        
        for n in range(N-1):
            newdp = [0] * 10
            for i in range(10):
                for j in moves[i]:
                    newdp[i] += dp[j] 
                    newdp[i] %= (10**9 + 7)
            dp = newdp
            
        return sum(dp) % (10**9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 1: return 10
        d = {0:[4, 6],
             1:[6, 8],
             2:[7, 9],
             3:[4, 8],
             4:[0, 3, 9],
             5:[],
             6:[0, 1, 7],
             7:[2, 6],
             8:[1, 3],
             9:[2, 4]
             }
        dp = [1] * 10
        for i in range(1, n):
            dp_l = [0] * 10
            for sq, count in enumerate(dp):
                for neigh in d[sq]:
                    dp_l[neigh] += count
                    dp_l[neigh] %= (10**9 + 7)
                    
            dp = dp_l
        return sum(dp) % (10**9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        d = {
            0: [4,6],
            1: [6,8],
            2: [9,7],
            3: [4,8],
            4: [3,9,0],
            5: [],
            6: [1,7,0],
            7: [6,2],
            8: [3,1],
            9: [4,2]
        }
        res = 0
        dp = [1]*10
        for x in range(1,n):
            temp = [0]*10
            for i in range(10):
                for j in d[i]:
                    temp[j] += dp[i]
            dp = temp 
        return sum(dp) % ((10**9)+7) 


class Solution:
    def knightDialer(self, n: int) -> int:
        moves = [[] for x in range(10)]
       
        moves[0] = [4,6]
        moves[1] = [6,8]
        moves[2] = [7,9]
        moves[3] = [4,8]
        moves[4] = [3,9,0]
        moves[5] = []
        moves[6] = [0,1,7]
        moves[7] = [2,6]
        moves[8] = [1,3]
        moves[9] = [2,4]
        
        dp = {}

        def dialer(start,n):
            if (start,n) in dp:
                return dp[(start,n)]
            if n==1:
                dp[(start,n)] = 1
                return 1
            xmoves = 0
            for move in moves[start]:
                xmoves += dialer(move,n-1)
            xmoves %= (10**9+7)
            dp[(start,n)] = xmoves 
            return xmoves
        xmoves = 0
        for i in range(0):
            xmoves += dialer(i,n)
            print(('i ',i,'moves',dialer(i,n),'tot ',xmoves))
        #return xmoves % (10**9+7)

    
        prev = [1] * 10
        for hop in range(2,n+1):
            #print('zzzzzzzzzz')
            #print('prev ',prev)
            #print('curr ',curr)
            curr = [0] * 10
            for i in range(10):
                for move in moves[i]:
                    curr[i] += prev[move]
                    
                    #print('i ',i,'curr[i] ',curr[i],'prev ',prev[i],'move')
            #print('prev ',prev)
            #print('curr ',curr)
            prev = curr
        return sum(prev) % (10**9 +7)
        
                
            


class Solution:
    def knight(self, n, current, memo):
        knight_mp = {1: {8, 6},
                    2: {9, 7},
                    3: {4, 8},
                    4: {3, 9, 0}, # 0 also
                    5: {},
                    6: {7, 1, 0}, # 0 also
                    7: {2, 6},
                    8: {3, 1},
                    9: {2, 4},
                    0: {6, 4}}        

        if n==1:
            return 1
        if (current, n) in memo:
            return memo[(current, n)]
        res = 0
        for item in knight_mp.get(current, set()):
            res+=self.knight(n-1, item, memo)
            
            
        memo[(current, n)] = res
        return res
        
    def knightDialer(self, n: int) -> int:
#         res = 0
#         mod = 10**9+7
#         memo = {}
#         for i in range(0, 10):
#             res+=self.knight(n, i, memo)%mod
#         return res%mod
    
    
        knight_mp = {1: {8, 6},
                    2: {9, 7},
                    3: {4, 8},
                    4: {3, 9, 0}, # 0 also
                    5: {},
                    6: {7, 1, 0}, # 0 also
                    7: {2, 6},
                    8: {3, 1},
                    9: {2, 4},
                    0: {6, 4}}        

#         dp = [[0 if i!=0 else 1 for _ in range(0, 10)] for i in range(n)]
#         mod = 10**9+7

#         for step in range(1, n):
#             for cell in range(0, 10):
#                 for neighbor in knight_mp.get(cell, set()):
#                     dp[step][cell] += dp[step-1][neighbor]
#         return sum(dp[n-1])%mod
    
        prev = [1 for _ in range(0, 10)]
        mod = 10**9+7

        for step in range(1, n):
            curr = [0 for _ in range(0, 10)]
            for cell in range(0, 10):
                for neighbor in knight_mp.get(cell, set()):
                    curr[cell] += prev[neighbor]
            prev = curr
        return sum(prev)%mod


class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10 ** 9 + 7
        jump = [[4, 6], [6, 8], [7, 9], [4, 8], [3, 9, 0], [], [0, 1, 7], [2, 6], [1, 3], [2, 4]]
        dp = [1] * 10
        for i in range(1, n):
            new = [0] * 10
            for j in range(10):
                new[j] = sum(dp[k] for k in jump[j]) % MOD
            dp = new
        return sum(dp) % MOD


#https://leetcode-cn.com/problems/knight-dialer/solution/4zhuang-tai-dong-tai-gui-hua-pythonjie-kong-jian-f/ markov chain, 这个解法神了
class Solution:
    def knightDialer(self, N: int) -> int:
        if N ==1 : return 10
        
        nums = [1,1,1,1]
        
        for _ in range(N-1):
            nums = [nums[1] + nums[2], 2 * nums[0], 2 * nums[0] + nums[3], 2 * nums[2]]
        
        return (4 * nums[0] + 2 * nums[1] + 2 * nums[2] + nums[3]) % (10**9+7)


class Solution:
    def knightDialer(self, n: int) -> int:
        el=[[] for i in range(10)]
        el[0]=[4,6]
        el[1]=[6,8]
        el[2]=[7,9]
        el[3]=[4,8]
        el[4]=[3,9,0]
        el[5]=[]
        el[6]=[1,7,0]
        el[7]=[2,6]
        el[8]=[1,3]
        el[9]=[2,4]
        a=[[0 for i in range(10)] for j in range(n)]
        for i in range(10):
            a[0][i]=1
        for i in range(1,n):
            for j in range(10):
                for x in el[j]:
                    a[i][j]=(a[i][j]+a[i-1][x])%(10**9+7)
        c=0
        for i in range(10):
            c+=a[-1][i]
        return c%(10**9+7)

class Solution:
    def knightDialer(self, n: int) -> int:
        adj = {}
        adj[0] = [4, 6]
        adj[1] = [6, 8]
        adj[2] = [7, 9]
        adj[3] = [4, 8]
        adj[4] = [0, 3, 9]
        adj[5] = []
        adj[6] = [0, 1, 7]
        adj[7] = [2, 6]
        adj[8] = [1, 3]
        adj[9] = [2, 4]
        
        p = 10**9 + 7
        f = [None] * n
        f[0] = [1] * 10
        for i in range(1, n):
            f[i] = [0] * 10
            for v in range(0, 10):
                for u in adj[v]:
                    f[i][v] += f[i-1][u]
        
        total = 0
        for d in range(0, 10):
            total = (total % p + f[n-1][d] % p) % p
        return total

class Solution:
    def knightDialer(self, n: int) -> int:
        possibilities = {2: {9, 7}, 1: {8, 6}, 3: {4, 8}, 4: {3, 9, 0}, 5: {}, 6: {1, 7, 0}, 7: {6, 2}, 8:{1,3}, 9:{4,2}, 0:{4,6}}
        
        def dp(n):
            result = {i:1 for i in range(10)}
            for i in range(2, n+1):
                temp = defaultdict(int)
                for curr_position in result:
                    for next_position in possibilities[curr_position]:
                        temp[next_position] += result[curr_position]
                result = temp
            return sum(result.values()) % (pow(10, 9) + 7)
        
        return dp(n)


class Solution:
    def knightDialer(self, n: int) -> int:
        cur_state = [1 for _ in range(10)]
        mod = 10 ** 9 + 7
        edges = [(1, 6), (1, 8), (2, 7), (2, 9), (3, 4), (3, 8), (4, 9), (4, 0), (6, 7), (6, 0)]
        edge_dic = { i: [] for i in range(10) }
        for i, j in edges:
            edge_dic[i].append(j)
            edge_dic[j].append(i)

        for _ in range(1, n):
            new_state = [0 for _ in range(10)]
            for i in range(10):
                new_state[i] = sum([cur_state[j] for j in edge_dic[i]]) % mod
            cur_state = new_state
        
        return sum(cur_state) % mod


class Solution:
    def knightDialer(self, n: int) -> int:
        d = [[4, 6], [6, 8], [7, 9], [4, 8], [0, 3, 9], [], [0, 1, 7], [2, 6], [1, 3], [2, 4]]
        dp = [[1] * 10]
        dp += [[0] * 10 for i in range(n-1)]
        for i in range(n-1):
            for j in range(10):
                for k in d[j]:
                    dp[i+1][k] = (dp[i+1][k] + dp[i][j]) % 1000000007
        return sum(dp[-1]) % 1000000007

class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10**9 + 7
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]

        dp = [1] * 10  # dp[i, N] = dp[nei, N-1] + dp[nei1, N-1] => dp[i] = 
        for i_n in range(n-1):
            dp2 = [0] * 10
            for i in range(10):
                for nei in moves[i]:
                    dp2[nei] += dp[i]
                    dp2[nei] %= MOD
            dp = list(dp2)
        return sum(dp) % MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = int(1e9 + 7)
        adj = [
            [4, 6],
            [6, 8],
            [7, 9],
            [4, 8],
            [3, 9, 0],
            [],
            [0, 1, 7],
            [2, 6],
            [1, 3],
            [2, 4],
        ]
        dp = [[0] * 10 for _ in range(n + 1)]
        dp[1] = [1] * 10
        for i in range(2, n + 1):
            for j in range(10):
                for child in adj[j]:
                    dp[i][j] += dp[i - 1][child]
                    dp[i][j] %= MOD
        ans = 0
        for v in dp[n]:
            ans += v
            ans %= MOD
        return ans


from collections import Counter

class Solution:
    def knightDialer(self, n: int) -> int:
        moves = {1 : [6, 8],
                 2 : [7, 9],
                 3 : [4, 8],
                 4 : [3, 9, 0],
                 6 : [1, 7, 0],
                 7 : [2, 6],
                 8 : [1, 3],
                 9 : [2, 4],
                 0 : [4, 6],
                }
        if n == 1:
            return 10
        
        starts = dict([(i, 1) for i in moves])
        for _ in range(n - 1):
            next = dict([(i, 0) for i in moves])
            for i in starts:
                for j in moves[i]:
                    next[j] += starts[i]
            starts = next
            
        return sum(starts.values()) % (10 ** 9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 1:
            return 10
        # [# of 0, # of 4/6, # of 2/8, # of corners]
        c = [1,2,2,4]
        nx = [0,0,0,0]
        for i in range(n-1):
            nx[0] = c[1]
            nx[1] = 2*c[0] + c[3]
            nx[2] = c[3]
            nx[3] = 2*(c[1] + c[2])
            c = nx[:]
        return sum(c) % (10**9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        moves = [[4, 6], [6, 8], [9, 7], [8, 4], [3, 9, 0], [], [7, 1, 0], [6, 2], [1, 3], [2, 4]]
        count = [[0] * 10 for _ in range(n + 1)]
        for i in range(10):
            count[1][i] = 1
        for i in range(1, n + 1):
            for num in range(10):
                for nei in moves[num]:
                    count[i][num] += count[i - 1][nei]
                    count[i][num] %= 10 ** 9 + 7
        return sum(count[-1]) % (10 ** 9 + 7)

class Solution:
    neighbors = {1: (6, 8),
                 2: (7, 9),
                 3: (4, 8),
                 4: (3, 9, 0),
                 5: tuple(),
                 6: (1, 7, 0),
                 7: (2, 6),
                 8: (1, 3),
                 9: (2, 4),
                 0: (4, 6)
                }
    
    def knightDialer(self, n: int) -> int:
        if n == 0:
            return 0
        if n == 1:
            return 10
        prev_moves = [1] * 10
        current_moves = [0] * 10
        
        for i in range(n - 1):
            for j in range(10):
                current_moves[j] = sum(prev_moves[k] for k in self.neighbors[j]) % (10**9 + 7)
            prev_moves = current_moves[:]
        
        return sum(prev_moves) % (10**9 + 7)


class Solution:
    neighbors = {1: (6, 8),
                 2: (7, 9),
                 3: (4, 8),
                 4: (3, 9, 0),
                 5: tuple(),
                 6: (1, 7, 0),
                 7: (2, 6),
                 8: (1, 3),
                 9: (2, 4),
                 0: (4, 6)
                }
    
    def knightDialer(self, n: int) -> int:
        if n == 0:
            return 0
        if n == 1:
            return 10
        prev_moves = [1] * 10
        current_moves = [0] * 10
        
        for i in range(n - 1):
            for j in range(10):
                current_moves[j] = sum(prev_moves[k] for k in self.neighbors[j]) % (10**9 + 7)
            prev_moves = current_moves.copy()
        
        return sum(prev_moves) % (10**9 + 7)


MODULE = 10 ** 9 + 7


class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 1:
            return 10

        MOVEMENTS = {
            0: [4, 6],
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [3, 9, 0],
            5: [],
            6: [1, 7, 0],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4]
        }

        dp = [2, 2, 2, 2, 3, 0, 3, 2, 2, 2]
        for idx in range(2, n):
            new_dp = [0] * 10
            for jdx in range(10):
                for next_jdx in MOVEMENTS[jdx]:
                    new_dp[next_jdx] += dp[jdx]
            dp = new_dp

        print(dp)
        return sum(dp) % MODULE


class Solution:
    def knightDialer(self, n: int) -> int:
        adj = [
            [4, 6],
            [8, 6],
            [7, 9],
            [4, 8],
            [3, 9, 0],
            [],
            [1, 7, 0],
            [2, 6],
            [1, 3],
            [2, 4]
        ]
        m = 10 ** 9 + 7
        
        memo = [1] * 10
        for i in range(1, n):
            memo = [sum(memo[e] for e in adj[d]) % m for d in range(10)]
        
        return sum(memo) % m

class Solution:
    def knightDialer(self, n: int) -> int:
        mod = 10**9+7
        moves = {1:[6,8], 2:[7,9], 3:[4,8],
                4: [0,3,9], 5:[], 6:[0,1,7],
                7:[2,6], 8:[1,3], 9:[2,4], 0:[4,6]}
        curr = [1]*10
        for _ in range(n-1):
            nex = [0]*10
            for i in range(10):
                nex[i] = sum(curr[j] for j in moves[i])%mod
            curr = nex
        return sum(curr)%mod

class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10 ** 9 + 7 
        res = 0 
        mappings = {
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [0, 3, 9], 
            5: [], 
            6: [0, 1, 7], 
            7: [2, 6], 
            8: [1, 3], 
            9: [2, 4], 
            0: [4, 6],
        }        
        
        dp = [[0 for i in range(10)] for i in range(n+1)]
        dp[0] = [1 for i in range(10)]
        dp[1] = [len(mappings[i]) for i in range(10)]
        
        for i in range(1, n-1):
            for j in range(10):
                pos = mappings[j]
                # dp[i + 1][j] += dp[i-1][j] * dp[1][j]
                for k in pos:
                    dp[i + 1][k] += dp[i][j]
                   
        # print(dp)
        return sum(dp[n - 1]) % MOD

'''
use DP instead of BFS, becasue only finite many states
2D DP:
DP[l][s] = number of unique path of length l, starting with state s
DP[l][1] = DP[l-1][6] + DP[l-1][8], becasue 1 can move to 6, 8
'''

class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10**9 + 7
        movedict = {0:[4,6], 1:[6,8], 2:[7,9], 3:[4,8], 4:[3,9,0],
                    5:[], 6:[1,7,0], 7:[2,6], 8:[1,3], 9:[2,4]}
        DP = [[0]*10 for _ in range(n)]
        DP[0] = [1]*10
        for l in range(1, n):
            for s in range(10):
                for moveto in movedict[s]:
                    DP[l][s] += DP[l-1][moveto]
                    DP[l][s] %= MOD
        ans = sum(DP[-1]) % MOD
        return ans

class Solution:
    def knightDialer(self, n: int) -> int:
        nextMove = [(4,6), (6,8), (7,9), (4,8), (0,3,9), (),(0,1,7), (2,6), (1,3), (2,4)]
        dp = [[0]*10 for _ in range(n)]
        
        if n ==1: return 10
        MOD = 10**9 + 7
        for i in range(10):
            dp[0][i] = 1
        
        for r in range(1,n):
            for i in range(10):
                for m in nextMove[i]:
                    # print(r,i,m)
                    dp[r][m] = dp[r][m] + dp[r-1][i]
                    # dp[r][m] %= MOD
        return sum(dp[-1])  % MOD
        


class Solution(object):
    def knightDialer(self, N):
        # Use This Code
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]
        MOD = 10**9 + 7
        table = [1] * 10
        
        for _ in range(N-1):
            temp = [0] * 10
            for k in range(10):
                temp[k] = sum(table[i] for i in moves[k])
                temp[k] %= MOD
            table = temp

        return sum(table)%MOD
        


class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 1:
            return 10
        # [# of 0, # of 4/6, # of 2/8, # of corners]
        a,b,c,d = [1,2,2,4]
        for i in range(n-1):
            a,b,c,d = [b, 2*a+d, d, 2*(b+c)]
        return sum([a,b,c,d]) % (10**9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:     
        graph = {
            0: [4, 6],
            1: [6,8],
            2: [7,9],
            3: [4,8],
            4:[9, 3, 0],
            5: [],
            6: [7, 1, 0], 
            7: [6, 2],
            8: [1, 3],
            9: [2,4]
        }
        
        prev_dp = [1] * 10
        for i in range(n-1):
            dp = [0] * 10
            for j in range(10):
                dp[j] = sum(prev_dp[k] for k in graph[j]) % (10**9 + 7)
            prev_dp = dp
        return sum(prev_dp) % (10**9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10**9 + 7
        
        #dp[i][j] possible answers at step[i], number j
        dp =[[0 for _ in range(10)] for _ in range(n)]
        #possible next moves
        move = [[4,6], [6,8], [7,9], [4,8], [3,9,0], [], [1,7,0], [2,6], [1,3], [4,2]]
        #initialization at n = 0, dp[0][j] = 1
        dp[0] = [1  for _ in range(10)]
        #transition funciton
        for i in range(1, n):
            for j in range(10):
                for nei in move[j]:
                    dp[i][j] = (dp[i][j] + dp[i-1][nei])%MOD
        #final answer
        return sum(dp[-1])%MOD

class Solution():
  def knightDialer(self, n):
    max_val = 10**9 + 7
    mem = {(1,1):1,
           (1,2):1,
           (1,3):1,
           (1,4):1,
           (1,5):1,
           (1,6):1,
           (1,7):1,
           (1,8):1,
           (1,9):1,
           (1,0):1,
          }

    fields = {0:(4,6),
              1:(6,8),
              2:(7,9),
              3:(4,8),
              4:(3,9,0),
              5:(),
              6:(0,1,7),
              7:(2,6),
              8:(3,1),
              9:(2,4),
             }
    
    new_mem = {}

    for length in range(1,n):
      for num in range(10):
        possible_jumps = fields[num]
        possible_paths = 0
        for jump in possible_jumps:
          possible_paths = (possible_paths + mem[(length, jump)]) % max_val
        new_mem[(length+1, num)] = possible_paths
      mem = new_mem
      new_mem = {}
    
    result = 0
    for key in list(mem.keys()):
      result = (result + mem[key]) % max_val
    return result % max_val


class Solution:
    neighbors = {1: (6, 8),
                 2: (7, 9),
                 3: (4, 8),
                 4: (3, 9, 0),
                 5: tuple(),
                 6: (1, 7, 0),
                 7: (2, 6),
                 8: (1, 3),
                 9: (2, 4),
                 0: (4, 6)
                }
    
    def knightDialer(self, n: int) -> int:
        if n == 0:
            return 0
        if n == 1:
            return 10
        prev_moves = [1] * 10
        
        for i in range(n - 1):
            current_moves = [sum(prev_moves[k] for k in self.neighbors[j]) % (10**9 + 7) for j in range(10)]
            prev_moves = current_moves
        
        return sum(prev_moves) % (10**9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10**9 + 7

        moves = [
            [4,6],[6,8],[7,9],[4,8],[3,9,0],[],
            [1,7,0],[2,6],[1,3],[2,4]
        ]
        
        dp = [[0] * 10 for _ in range(n + 1)]
        for i in range(10):
            dp[1][i] = 1
        
        for i in range(2, n + 1):
            for j in range(10):
                for move in moves[j]:
                    dp[i][move] += dp[i - 1][j]
                    dp[i][move] %= MOD
        
        return sum(dp[n]) % MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        mod = 10**9 + 7

        d = dict()
        d[0] = {4, 6}
        d[1] = {6, 8}
        d[2] = {7, 9}
        d[3] = {4, 8}
        d[4] = {0, 3, 9}
        d[6] = {0, 1, 7}
        d[7] = {2, 6}
        d[8] = {1, 3}
        d[9] = {2, 4}
        
        memo = [[0]*10 for i in range(n+1)]
        memo[1] = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
        # print(memo)
        
        for i in range(2, n+1):
            for key, val in list(d.items()):
                for v in val:
                    memo[i][key] += memo[i-1][v]
        
        # print(memo[-3:-1])
        return sum(memo[-1])%mod
        
        


class Solution:
    def knightDialer(self, N: int) -> int:
        #OPT(i, j) = number of numbers you can dial with j hops reaching i
        #k - possible places I could have come from
        #OPT(i, j) = SUM(OPT(k, j-1))
        #base cases
        #if j = 0, then 0
        #if i = 5, j = j, then OPT(i, j) = 0
        jumps = dict({1:[8,6], 2:[7,9], 3:[4,8], 4:[0,3,9], 5:[], 6:[0,1,7], 7:[2,6], 8:[1,3],9:[2,4], 0:[4,6]})
        table = [[0] * N for i in range(10)]
        for j in range(N):
            for i in range(10):
                if j == 0:
                    table[i][0] = 1
                elif j == 1:
                    table[i][j] = len(jumps[i])
                else:
                    kList = jumps[i]
                    for k in kList:
                        table[i][j] += table[k][j-1]
        res = 0
        for i in range(len(table)):
            res = (res +table[i][-1])%(10**9 + 7)
        return res
        


class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10**9 + 7
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]
        dp = [[0 for _ in range(n+1)] for _ in range(10)]  #dp[i][j] --> f(i, j) start from i and take j steps
        for i in range(10):
            dp[i][1] = 1
        
        for j in range(2,n+1):
            for i in range(10):
                for move in moves[i]:
                    dp[i][j] += dp[move][j-1]
                    dp[i][j] %= MOD
                
        sum_ = 0
        for i in range(10):
            sum_ += dp[i][n]
            sum_ %= MOD
            
        return sum_        

class Solution:
    def knightDialer(self, n: int) -> int:
        d = {
            0:(4, 6),
            1:(6, 8),
            2:(7, 9),
            3:(4, 8),
            4:(3, 9, 0),
            5:(),
            6:(1, 7, 0),
            7:(2, 6),
            8:(1, 3),
            9: (2, 4)
        }
        dp = [1] * 10
        for _ in range(n-1):
            temp = [0] * 10
            for i in range(10):
                for j in d[i]:
                    temp[j] = dp[i] + temp[j]
            dp = temp
        
      
        return sum(dp) % (10 ** 9 + 7)

# class Solution:
#     def knightDialer(self, N: int) -> int:
#         steps = {1: [6, 8], 2: [7, 9], 3: [4, 8], 4: [3, 9, 0],5: [], 6: [1, 7, 0], 7: [2, 6], 8: [1, 3], 9: [2, 4], 0: [4, 6]}
#         ret = set()
#         def DFS(cur, i):
#             if i == N:
#                 n = 0
#                 for c in cur:
#                     n = n * 10 +c
#                 ret.add(n)
#                 print(n)
#                 return
#             for n in steps[cur[-1]]:
#                 DFS(cur+[n], i+1)
#             return
#         for k in steps.keys():
#             DFS([k], 1)
#         return len(ret)
        
class Solution:
    def knightDialer(self, N: int) -> int:
        steps = {1: [6, 8], 2: [7, 9], 3: [4, 8], 4: [3, 9, 0], 5: [], 6: [1, 7, 0], 7: [2, 6], 8: [1, 3], 9: [2, 4], 0: [4, 6]}
        dp = [1 for _ in range(10)]
        for _ in range(N-1):
            cur = [0 for _ in range(10)]
            for i in range(10):
                for j in steps[i]:
                    cur[j] += dp[i]
            dp = cur
        return sum(dp) % (10**9 +7)
                    


class Solution:
    d = [(4,6),(6,8),(7,9),(4,8),(3,9,0),(),(1,7,0),(2,6),(1,3),(2,4)]       # Create a graph, index is the vertex and values are the edges
    cache = {}
    def dfs(self, i, n):
        if n == 0: return 1
        elif (i, n) not in self.cache:
            self.cache[i, n] = sum(self.dfs(val, n-1) for val in self.d[i])  # Memoization
            if i in [1,4,7]: self.cache[i+2, n] = self.cache[i, n]           # Symmetry
            elif i in [3,6,9]: self.cache[i-2, n] = self.cache[i, n]
        return self.cache[i, n]
    
    def knightDialer(self, n: int) -> int:
        return sum(self.dfs(i, n-1) for i in range(10)) % (int(1e9)+7)  
            


class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 1:
            return 10
        mod = 10**9 + 7
        dp = [[0 for i in range(n+1)] for j in range(10)]
        for i in range(10):
            dp[i][1] = 1
        d = {0:[4, 6], 1:[6, 8], 2:[7, 9], 3:[4, 8], 4:[0, 3, 9], 6:[0, 1, 7], 7:[2, 6], 8:[1, 3], 9:[2, 4]}
        for j in range(2, n+1):
            for i in range(10):
                if i != 5:
                    for ele in d[i]:
                        dp[i][j] += dp[ele][j-1]
                        dp[i][j] %= mod
        # print(dp)
        ans = 0
        for i in range(10):
            ans += dp[i][n]
            ans %= mod
        return ans

class Solution:
    def knightDialer(self, n: int) -> int:
        dp = [[0 for _ in range(10)] for _ in range(n+1)]
        prevs = {0: [4, 6], 1: [8, 6], 2: [7, 9], 3: [8, 4], 4: [3, 9, 0], 5: [], 6: [1, 7, 0], 7: [6, 2], 8: [1, 3], 9: [4, 2]}
        
        for i in range(10):
            dp[1][i] = 1
        
        for i in range(2, n+1):
            for j in range(10):
                for prev in prevs[j]:
                    dp[i][j] += dp[i-1][prev]
        
        return sum(dp[-1]) % 1000000007

class Solution:
    def knightDialer(self, n: int) -> int:
        if n==1:
            return 10
        numpad = {'0':['4','6'],'1':['6','8'],'2':['7','9'],'3':['4','8'],'4':['0','3','9'],'6':['0','1','7'],'7':['2','6'],'8':['1','3'],'9':['4','2']}
        dp={}
        for i in ['0','1','2','3','4','6','7','8','9']:
            dp[i]=[1,0]
        for i in range(1,n):
            for j in ['0','1','2','3','4','6','7','8','9']:
                dp[j][i%2]=0
                for k in numpad[j]:
                    dp[j][i%2]+=dp[k][1-i%2]
                dp[j][i%2]%=(1000000007)
        res=0
        for i in ['0','1','2','3','4','6','7','8','9']:
            res+=dp[i][(n-1)%2]
            res%=(1000000007)
        return res

class Solution:
    def knightDialer(self, n: int) -> int:
        dp = [ [1]*10 for _ in range(n+1) ]
        
        d = {
            0:(4,6),
            1:(6,8),
            2:(7,9),
            3:(8,4),
            4:(3,9,0),
            5:(),
            6:(1,7,0),
            7:(6,2),
            8:(1,3),
            9:(2,4)
        }
        
        for i in range(2, n+1):            
            for j in range(0,10):
                dp[i][j] = 0
                for k in d[j]:
                    dp[i][j] += dp[i-1][k]
                    
        
        return sum(dp[n]) % (10**9 + 7)
            
                


class Solution:
    def knightDialer(self, n: int) -> int:
        if n==0:
            return 0
        dic = {0: (4, 6),
               1: (8, 6),
               2: (7, 9),
               3: (4, 8),
               4: (3, 9, 0),
               5: (),
               6: (1, 7, 0),
               7: (2, 6),
               8: (1, 3),
               9: (2, 4)}
        dp = [1]*10
        for _ in range(n-1):
            new = [0]*10
            for i in range(10):
                for nei in dic[i]:
                    new[i] += dp[nei]
            dp = new
        
        return sum(dp)%(10**9+7)

class Solution:
    def knightDialer(self, n: int) -> int:
        arr = [[0 for i in range(10)] for i in range(n)]
        mappings = {
            0: [4,6],
            1: [6,8],
            2: [7,9],
            3: [4,8],
            4: [0,3,9],
            5: [],
            6: [0,1,7],
            7: [2,6],
            8: [1,3],
            9: [2,4]
        }
        mod = 10**9+7
        arr[0] = [1 for i in range(10)]
        for i in range(1,n):
            for j in range(10):
                for k in mappings[j]:
                    arr[i][j] += arr[i-1][k]
        return sum(arr[n-1])%mod

class Solution:
    def knightDialer(self, n: int) -> int:
        
        N=n
        l=10
        dp=[1]*l
        m={1:[6,8],2:[7,9],3:[4,8],4:[0,3,9],5:[],6:[0,1,7],7:[2,6],8:[1,3],9:[2,4],0:[4,6]}
        
        for _ in range(2,N+1):
            dp2=[0]*l
            for i in range(l):
                for j in m[i]:
                    dp2[i]+=dp[j]
            dp=dp2
        
        return sum(dp)%(10**9+7)

class Solution:
    def knightDialer(self, n: int) -> int:
        nextMove = [(4,6), (6,8), (7,9), (4,8), (0,3,9), (),(0,1,7), (2,6), (1,3), (2,4)]
        dp = [[0]*10 for _ in range(n)]
        
        if n ==1: return 10
        MOD = 10**9 + 7
        for i in range(10):
            dp[0][i] = 1
        
        for r in range(1,n):
            for i in range(10):
                for m in nextMove[i]:
                    # print(r,i,m)
                    dp[r][m] = dp[r][m] + dp[r-1][i]
                    dp[r][m] %= MOD
        return sum(dp[-1])  % MOD
        


class Solution:
    def knightDialer(self, n: int) -> int:
        next_move = {0: [4, 6], 1: [6, 8], 2: [7, 9], 3: [4, 8], 4: [0, 3, 9], 5: [], 6: [0, 1, 7], 7: [2, 6], 8: [1, 3], 9: [2, 4]}
        
        memo = defaultdict(int)
        for i in range(10):
            memo[i] = 1
            
        for _ in range(n-1):
            next_memo = defaultdict(int)
            for i in range(10):
                for next_step in next_move[i]:
                    next_memo[next_step] += memo[i]
                    next_memo[next_step] %= 10**9 + 7
            memo = next_memo
        return sum(memo.values()) % (10**9 + 7)

MOVES = [
    [4, 6], # 0
    [6, 8], # 1
    [7, 9], # 2
    [4, 8], # 3
    [3, 9, 0], # 4
    [], # 5
    [1, 7, 0], # 6
    [2, 6], # 7
    [1, 3], # 8
    [2, 4], # 9
]

modulus = 10**9 + 7

class Solution:
    def knightDialer(self, n: int) -> int:
        dp = [1] * 10  # dp[i] = number of ways to get to digit in n moves, for n = 1, 2, ...
        dp2 = [0] * 10  # second copy of dp2 to avoid mutating dp while iterating over it
        for _ in range(1, n):
            for digit in range(10):
                dp2[digit] = 0
                for next_digit in MOVES[digit]:
                    dp2[digit] += dp[next_digit]
                    dp2[digit] %= modulus
            dp2, dp = dp, dp2  # swap out current dp
        
        result = 0
        for ways in dp:
            result += ways
            result %= modulus
        
        return result

class Solution:
    d = [(4,6),(6,8),(7,9),(4,8),(3,9,0),(),(1,7,0),(2,6),(1,3),(2,4)]
    cache = {}
    def dfs(self, i, n):
        if n == 0: return 1
        if (i, n) not in self.cache:
            self.cache[i, n] = sum(self.dfs(val, n-1) for val in self.d[i])
            if i in [1,4,7]: self.cache[i+2, n] = self.cache[i, n]
            elif i in [3,6,9]: self.cache[i-2, n] = self.cache[i, n]
        return self.cache[i, n]
    
    def knightDialer(self, n: int) -> int:
        mod = int(1e9)+7
        return sum(self.dfs(i, n-1) for i in range(10)) % mod

class Solution:
    def knightDialer(self, n: int) -> int:
        ### f[i][j]: # of different codes with length i and with j as the last number
        ### f[i][j] = sum(f[i-1][l]), where l can be achieved from j on the map
        ### f[1][j] = 1, 0<=j<=9
        
        achievable = {}
        achievable[0] = [ 4,6 ]
        achievable[1] = [ 6,8 ]
        achievable[2] = [ 7,9 ]
        achievable[3] = [ 4,8 ]
        achievable[4] = [ 0,3,9 ]
        achievable[5] = [ ]
        achievable[6] = [ 0,1,7 ]
        achievable[7] = [ 2,6 ]
        achievable[8] = [ 1,3 ]
        achievable[9] = [ 2,4 ]
        
        f1 = [1 for _ in range(10)]
        
        m = 10 ** 9 + 7
        
        for i in range(1, n):
            f2 = [0 for _ in range(10)]
            for j in range(10):
                f2[j] = sum( f1[l] for l in achievable[j]) % m
            f1 = f2.copy()
        
        return sum(f1) % m
        


class Solution:
    def knightDialer(self, n: int) -> int:
        
        moves = {0:[4,6], 1:[6,8], 2:[7,9], 3:[4,8], 4:[0,3,9], 
                 5:[], 6:[0,1,7], 7:[2,6], 8:[1,3], 9:[2,4]}
        
        mem = [[0 for i in range(n)] for i in range(10)]
        
        for i in range(10):
            mem[i][0] = 1
            
        for col in range(1,n):
            for row in range(10):
                for move in moves[row]:
                    mem[row][col] += mem[move][col-1]
                    mem[row][col] %= (10**9) + 7
        
        tot_sum = 0
        for row in range(10):
            tot_sum += mem[row][n-1]
            tot_sum %= (10**9) + 7
            
        return tot_sum


class Solution:
    def knightDialer(self, n: int) -> int:
        d = {
            0: [4,6],
            1: [6,8],
            2: [9,7],
            3: [4,8],
            4: [3,9,0],
            5: [],
            6: [1,7,0],
            7: [6,2],
            8: [3,1],
            9: [4,2]
        }
        res = 0
        dp = [1]*10
        for x in range(1,n):
            temp = [0]*10
            for i in range(10):
                for j in d[i]:
                    temp[j] += dp[i]
            dp = temp 
        for i in dp:
            res += i
        return res % ((10**9)+7)


class Solution:
    def knightDialer(self, n: int) -> int:
        
        tab = [[0 for i in range(n + 1)] for i in range(10)]
        
        for i in range(10):
            tab[i][1] = 1
            
        for i in range(2, n + 1):
            for j in range(10):
                if j == 0:
                    tab[j][i] = tab[4][i - 1] + tab[6][i - 1]
                if j == 1:
                    tab[j][i] = tab[6][i - 1] + tab[8][i - 1]
                if j == 2:
                    tab[j][i] = tab[7][i - 1] + tab[9][i - 1]
                if j == 3:
                    tab[j][i] = tab[4][i - 1] + tab[8][i - 1]
                if j == 4:
                    tab[j][i] = tab[3][i - 1] + tab[9][i - 1] + tab[0][i - 1]
                if j == 5:
                    tab[j][i] = 0
                if j == 6:
                    tab[j][i] = tab[1][i - 1] + tab[7][i - 1] + tab[0][i - 1]
                if j == 7:
                    tab[j][i] = tab[2][i - 1] + tab[6][i - 1]
                if j == 8:
                    tab[j][i] = tab[1][i - 1] + tab[3][i - 1]
                if j == 9:
                    tab[j][i] = tab[2][i - 1] + tab[4][i - 1]
                    
                tab[j][i] = tab[j][i] % (10**9 + 7)
                
        s = 0
                
        for i in range(10):
            s += tab[i][n]
            
        s = s % (10**9 + 7)
        
        return s

class Solution:
    def knightDialer(self, n: int) -> int:
        dp=[[4,6],[6,8],[7,9],[4,8],[0,3,9],[],[0,1,7],[2,6],[1,3],[4,2]]
        ct=[1]*10

        while n-1:           

            ct=[sum(ct[j] for j in i) for i in dp]
                   
            n-=1

        return sum(ct)%(10**9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        dic = {0:(4,6),1:(6,8),2:(7,9),3:(4,8),4:(0,3,9),5:(),6:(1,0,7),7:(2,6),8:(1,3),9:(2,4)}
        prev_dic = {}
        for i in range(10):
            prev_dic[i] = 1
        for i in range(n-1):
            cur_dic = collections.defaultdict(int)
            for j in prev_dic:
                for k in dic[j]:
                    cur_dic[k] += prev_dic[j]
            prev_dic = cur_dic
        return sum(prev_dic.values())%(10**9+7)

class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10**9 + 7                        
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],[1,7,0],[2,6],[1,3],[2,4]]
        dp = [1] * 10
        for cell in range(n - 1):
            dp2 = [0] * 10
            for num_cell, count in enumerate(dp):
                for knight in moves[num_cell]:
                    dp2[knight] += count
                    dp2[knight] %= MOD
                dp = dp2
        return sum(dp) % MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        moves = {1: [6, 8], 2: [7, 9], 3: [4, 8], 4: [0, 3, 9], 5: [], 6: [0, 1, 7], 7: [2, 6], 8: [1, 3], 9: [2, 4], 0: [4, 6]}
        
        
        # dp[i][j] = x
        # x possible calls of length i when knight is placed on j
        
        dp = [[0 for j in range(10)] for i in range(n)]
        
        for i in range(n):
            for j in range(10):
                if i == 0:
                    dp[i][j] = 1
                else:
                    for move in moves[j]:
                        dp[i][j] += dp[i-1][move] 
        
        return sum(dp[n-1]) % (10 ** 9 + 7)
                
            
        


class Solution:
    d = [(4,6),(6,8),(7,9),(4,8),(3,9,0),(),(1,7,0),(2,6),(1,3),(2,4)]       # Create a graph, index is the vertex and values are the edges
    cache = {}
    def dfs(self, i, n):
        if n == 0: return 1
        elif (i, n) not in self.cache:
            self.cache[i, n] = sum(self.dfs(val, n-1) for val in self.d[i])  # Memoization
            if i in [1,4,7]: self.cache[i+2, n] = self.cache[i, n]           # Symmetry
            elif i in [3,6,9]: self.cache[i-2, n] = self.cache[i, n]
        return self.cache[i, n]
    
    def knightDialer(self, n: int) -> int:
        return sum(self.dfs(i, n-1) for i in range(10)) % (int(1e9)+7)

class Solution:
    def knightDialer(self, n: int) -> int:
        arr = [[0 for i in range(10)] for i in range(n)]
        mappings = {
            0: [4,6],
            1: [6,8],
            2: [7,9],
            3: [4,8],
            4: [0,3,9],
            5: [],
            6: [0,1,7],
            7: [2,6],
            8: [1,3],
            9: [2,4]
        }
        mod = 10**9+7
        arr[0] = [1 for i in range(10)]
        for i in range(1,n):
            for j in range(10):
                for k in mappings[j]:
                    arr[i][j] = (arr[i][j]%mod + arr[i-1][k]%mod)%mod
        return sum(arr[n-1])%mod

import numpy as np

class Solution:
    def knightDialer(self, n: int) -> int:
        
        memo, dp = [[4,6],[8,6],[7,9],[4,8],[3,9,0],[],[0,1,7],[2,6],[1,3],[2,4]], [1] * 10
        for i in range(n - 1):
            dp = [sum([dp[j] for j in memo[i]]) for i in range(10)]
        return sum(dp) % (10 ** 9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        #recursive + memo
#         next_map = {0:[4,6],1:[6,8],2:[7,9],3:[4,8],4:[0,3,9],5:[],6:[0,1,7],7:[2,6],8:[1,3],9:[2,4]}
       
#         def dfs(cur_num,n):
#             if (cur_num,n) in memo.keys():
#                 return memo[(cur_num,n)]
#             if n == 0:
#                 return 1
#             ans = 0
#             for next_num in next_map[cur_num]:                
#                 ans += dfs(next_num,n-1)
#             memo[(cur_num,n)] = ans
#             return ans
        
#         ans = 0
#         MOD = pow(10,9)+7
#         memo = {}
#         for i in range(10):            
#             ans += dfs(i,n-1)%MOD
#             ans = ans%MOD
#         #    print (\"i:{}, ans={}\".format(i,ans))
            
#         return ans

          #dp[numr][n]: represent the total combinations when start with number :num with n steps
          dp = [ [0 for _ in range(n+1)] for _ in range(10)]
          next_map = [[4,6],[6,8],[7,9],[4,8],[0,3,9],[],[0,1,7],[2,6],[1,3],[2,4]]
          MOD = pow(10,9)+7
        
          for i in range(10):
              dp[i][1] = 1
            
          for k in range(2,n+1):
              for i in range(10):
                  for next_num in next_map[i]:
                      dp[i][k] += dp[next_num][k-1]%MOD
                      dp[i][k] %= MOD
          ans  = 0  
          for i in range(10):
              ans += dp[i][n]
              ans %= MOD
            
          return ans
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            



class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10**9 + 7
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]
        
        dp = [[0]*10  for _ in range(n)]
        for i in range(n):
            for j in range(10):
                dp[i][j] = 0
                
        for i in range(10):
            dp[0][i] = 1
            
        for t in range(1, n):
            for num in range(10):
                for move in moves[num]:
                    dp[t][num] += dp[t - 1][move]
                    dp[t][num] %= MOD
        return sum(dp[n-1])%MOD


class Solution:
    
    def knightDialer(self, k: int) -> int:
        self.dirs = [
            [1, 2], [1, -2], [-1, 2], [-1, -2],
            [2, 1], [2, -1], [-2, 1], [-2, -1]
        ]
    
        self.mod = 10 ** 9 + 7

        self.n = 4
        self.m = 3
        if k == 1:
            return 10
        
        self.forbidden = set([(3, 0), (3, 2)])
        self.next_pos = self.build_pos()
        # print(self.next_pos)
        self.dp = [1] * 10
        self.helper(k - 1)
        return sum(self.dp) % self.mod
    
    
    def helper(self, k):
        if k == 0:
            return
        # print(self.dp)
        next_dp = [0] * 10
        for i in range(10):
            for j in self.next_pos[i]:
                next_dp[j] += (self.dp[i] % self.mod)
                next_dp[j] %= self.mod
        # print(next_dp)
        self.dp = next_dp
        self.helper(k - 1)
    
    def build_pos(self):
        res = {}
        for i in range(10):
            next_num = []
            x, y = self.get_pos(i)
            for d in self.dirs:
                nx, ny = d
                if self.is_valid(x + nx, y + ny):
                    
                    num = self.get_num(x + nx, y + ny)
                    # print(i, x + nx, y + ny, num)
                    next_num.append(num)
            res[i] = next_num
        return res
                    
    
    def is_valid(self, x, y):
        return 0 <= x < self.n and 0 <= y < self.m and (x, y) not in self.forbidden
        
    
    def get_num(self,x, y):
        if x == 3 and y == 1:
            return 0
        if self.is_valid(x, y):
            return x * 3 + y + 1
        


    def get_pos(self, num):
        if num == 0:
            return (3, 1)
        num -= 1
        row = num // 3
        col = num % 3
        return (row, col)

class Solution:
    def knightDialer(self, n: int) -> int:
        '''
        0->[4,6]->[1,3,7,9]->
        
        2 20 (3, 6), (2, 14)
        
        '''
        if n == 1: return 10
        
        m = {
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [0, 3, 9],
            5: [],
            6: [0, 1, 7],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4],
            0: [4, 6]
        }
        
        cnt = defaultdict(int)
        for k in m:
            for v in m[k]:
                cnt[v] += 1
        
        for _ in range(n-2):
            cnt2 = defaultdict(int)
            for k in cnt:
                for v in m[k]:
                    cnt2[v] += cnt[k]
            cnt = cnt2
        
        return sum(cnt[k] for k in cnt) % (10**9+7)

class Solution:
    def knightDialer(self, N: int) -> int:
        MOD = 10**9 + 7
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]

        dp = [1] * 10
        for hops in range(N-1):
            dp2 = [0] * 10
            for node, count in enumerate(dp):
                for nei in moves[node]:
                    dp2[nei] += count
                    dp2[nei] %= MOD
            dp = dp2
        return sum(dp) % MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        dp = [[1] * 10 for _ in range(n)]
        moves = {0: [4, 6],
                 1: [6, 8],
                 2: [7, 9],
                 3: [4,  8],
                 4: [0, 3, 9],
                 5: [],
                 6: [0, 1, 7],
                 7: [2, 6],
                 8: [1, 3],
                 9: [2, 4]}
        for i in range(1, n):
            for j in range(10):
                count = 0
                for digit in moves[j]:
                    count += dp[i-1][digit]
                dp[i][j] = count
        return sum(dp[-1]) % (10**9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        moves = [
            [4, 6],
            [6, 8],
            [7, 9],
            [4, 8],
            [3, 9, 0],
            [],
            [1, 7, 0],
            [2, 6],
            [1, 3],
            [2, 4]
        ]
        dp = [1] * 10
        for _ in range(n - 1):
            prevDp = copy.copy(dp)
            for i in range(10):
                dp[i] = sum([prevDp[move] for move in moves[i]])
        return sum(dp) % (10**9 + 7)
            
            


class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 1:
            return 10
        LARGEINT = 10**9 + 7
        moves = {1:2, 2:1, 4:2, 7:2, 8:1, 0:1}
        while n > 1:
            new_moves = {
                1: (moves[4] + (2*moves[8])) % LARGEINT,
                2: moves[7],
                4: (moves[1] + moves[7] + (2*moves[0])) % LARGEINT,
                7: (moves[4] + (2*moves[2])) % LARGEINT,
                8: moves[1],
                0: moves[4]
            }
            moves = new_moves
            n -= 1
        return sum(moves.values()) % LARGEINT


class Solution:
    def knightDialer(self, n: int) -> int:
        neighbors = {
            1 : (6, 8),
            2 : (7, 9),
            3 : (4, 8),
            4: (3, 9, 0),
            5 : tuple(),
            6 : (1, 7, 0),
            7 : (2, 6),
            8 : (1, 3),
            9 : (2, 4),
            0 : (4, 6) 
        }
        
        dp = [[0 for _ in range(10)] for _ in range(n+1)]
        
        for r in range(n+1):
            for c in range(10):
                if r == 0:
                    dp[r][c] = 0
                elif r == 1:
                    dp[r][c] = 1
                else:
                    for ne in neighbors[c]:
                        dp[r][c] += dp[r-1][ne]
        
        return sum(dp[-1]) % (10**9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        d = {1:[6,8],
             2:[7,9],
             3:[4,8],
             4:[3,9,0],
             5:[],
             6:[1,7,0],
             7:[2,6],
             8:[1,3],
             9:[2,4],
             0:[4,6]}
        @lru_cache(None)
        def dfs(i, n):
            if n == 1:
                return 1
            else:
                res = 0
                for c in d[i]:
                    res += dfs(c, n-1)
                return res % (10**9+7)
            
        return sum(dfs(i, n) for i in range(10)) % (10**9+7)

class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 1: return 10
        
        MOD = 1000000007
        graph = {1: [6, 8], 2: [7, 9], 3: [4, 8], 4: [3, 9, 0], 5: [], 6: [1, 7, 0], 7: [2, 6], 8: [1, 3], 9: [2, 4], 0: [4, 6]}
        prev = [1,1,1,1,1,0,1,1,1,1]
        for _ in range(n-1):
            val = [0] * 10
            for i in range(10):
                for x in graph[i]:
                    val[x] += prev[i]
            prev = val
        return sum(prev) % MOD


class Solution:
    def _knightDialer(self, n: int, curr_n: int, moves_map: dict, cache: dict) -> int:
        if n == 0:
            return 1
        
        if (curr_n,n) in cache:
            return cache[(curr_n,n)]
        
        distinct_nums = 0
        for next_n in moves_map[curr_n]:
            distinct_nums += self._knightDialer(n-1, next_n, moves_map, cache)
        
        cache[(curr_n, n)] = distinct_nums
        return cache[(curr_n,n)]
    
    def knightDialer(self, n: int) -> int:
        # TLE, let's take care of some symmetry
        # 1 == 3 == 9 == 7, 4 == 6, 2 == 8, 0
        if n == 1:
            return 10

        mod = 10 ** 9 + 7
        moves_map = {
            1: [6,8],
            2: [7,9],
            3: [4,8],
            4: [0,3,9],
            5: [],
            6: [0,1,7],
            7: [2,6],
            8: [1,3],
            9: [2,4],
            0: [4,6],
        }

        # Bottom-up
        dp_curr = [1] * 10
        dp_next = [0] * 10

        for _ in range(1, n):
            for start, poss_moves in list(moves_map.items()):
                dp_next[start] = sum(dp_curr[poss_move] for poss_move in poss_moves)
            dp_curr = dp_next
            dp_next = [0] * 10
            
        return sum(dp_curr) % mod
        
#         nums = 0
#         for m, weight in [(1,4),(2,2),(4,2),(0,1)]:
#             nums += weight * self._knightDialer(n-1, m, moves_map, cache)
        
#         return nums % mod


class Solution:
    def knightDialer(self, n: int) -> int:
        
        k = {
            0: [4, 6],
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [0, 3, 9],
            5: [],
            6: [0, 1, 7],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4],
        }
        
        
        dp = [[1] * 10, [0] * 10]
        
        turn = 0
        
        for t in range(n-1):
            turn = 1 - turn
            for i in range(10):
                dp[turn][i] = sum(dp[1-turn][j] for j in k[i]) % (10 ** 9 + 7)
                     
        
        return sum(dp[turn]) % (10 ** 9 + 7)
        


class Solution:

    adjacency = {
            0: {4, 6},
            1: {8, 6},
            2: {7, 9},
            3: {8, 4},
            4: {3, 9, 0},
            5: {},
            6: {1, 7, 0},
            7: {2, 6},
            8: {1, 3},
            9: {2, 4}
        }

    def knightDialer(self, n: int):
        count = [1 for _ in range(10)]

        for _ in range(n - 1):
            count = [sum(count[next_digit] for next_digit in Solution.adjacency[digit]) for digit in range(10)]

        return sum(count) % (10 ** 9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        next_move = { 0: [4,6], 1: [6,8], 2: [7,9], 3: [4,8], 4: [0,3,9], 5: [], 6: [0,1,7], 7:[2,6], 8: [1,3], 9: [2,4]}
        mod_num = 10**9 + 7
        dp_prev = [1] * 10
        
        for i in range(n-1):
            dp_new = [0] * 10
            for num in range(10):
                phones_for_num = sum((dp_prev[x] for x in next_move[num]))
                dp_new[num] = phones_for_num
            dp_prev = dp_new

        return sum(dp_prev) % mod_num


# class Solution:
#     def knightDialer(self, n: int) -> int:
#         possible_moves = {1:[6,8], 2:[7,9], 3:[4,8], 4:[3,9,0], 5:[],
#                           6:[1,7,0], 7:[2,6], 8:[1,3], 9:[2,4], 0:[4,6]}
        
#         self.memo = {}
#         def dfs(cur_point, count, n):
#             if count == n:
#                 return 1
#             if (cur_point, count) not in self.memo:
#                 self.memo[(cur_point, count)] = sum(dfs(nxt_point, count + 1, n) for nxt_point in possible_moves[cur_point])
#                 if cur_point in [1,4,7]: 
#                     self.memo[(cur_point+2, count)] = self.memo[(cur_point, count)]         
#                 elif cur_point in [3,6,9]: 
#                     self.memo[(cur_point-2, count)] = self.memo[(cur_point, count)]
#             return self.memo[(cur_point, count)]
                
        
#         return sum(dfs(i, 1, n) for i in range(10)) % (10**9 + 7)

class Solution:
    d = [(4,6),(6,8),(7,9),(4,8),(3,9,0),(),(1,7,0),(2,6),(1,3),(2,4)]       # Create a graph, index is the vertex and values are the edges
    cache = {}
    def dfs(self, i, n):
        if n == 0: return 1
        elif (i, n) not in self.cache:
            self.cache[i, n] = sum(self.dfs(val, n-1) for val in self.d[i])  # Memoization
            if i in [1,4,7]: self.cache[i+2, n] = self.cache[i, n]           # Symmetry
            elif i in [3,6,9]: self.cache[i-2, n] = self.cache[i, n]
        return self.cache[i, n]
    
    def knightDialer(self, n: int) -> int:
        return sum(self.dfs(i, n-1) for i in range(10)) % (int(1e9)+7)

class Solution:
    neighbors = {1: (6, 8),
                 2: (7, 9),
                 3: (4, 8),
                 4: (3, 9, 0),
                 5: tuple(),
                 6: (1, 7, 0),
                 7: (2, 6),
                 8: (1, 3),
                 9: (2, 4),
                 0: (4, 6)
                }
    
    def knightDialer(self, n: int) -> int:
        if n == 0:
            return 0
        if n == 1:
            return 10
        prev_moves = [1] * 10
        
        for i in range(n - 1):
            current_moves = [sum(prev_moves[k] for k in self.neighbors[j]) for j in range(10)]
            prev_moves = current_moves
        
        return sum(prev_moves) % (10**9 + 7)


class Solution:
    
    def __init__(self):
        self.mem = dict()
    
    def knightDialer(self, n: int) -> int:
        reach = [ [4,6], [6,8], [7,9], [4,8], [0,3,9], [], [0,1,7], [2,6], [1,3], [2,4] ]
        
        counts = [1] * 10
        for i in range(n-1):
            counts2 = [ sum(counts[k] for k in reach[j] ) for j in range(10) ]
            # print(i,counts2)
            counts = counts2
        return sum(counts) % (10**9 + 7)
        
        
#         def doit(start, hopsLeft):
#             key = (start,hopsLeft)
#             if key in self.mem:
#                 return self.mem[key]
#             if hopsLeft == 0:
#                 count = 1
#             else:
#                 count = sum(doit(z,hopsLeft-1) for z in reach[start])
#             self.mem[key] = count
#             return count

#         return sum(doit(z,n-1) for z in range(10)) % (10**9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        jumps = [[4,6],[6,8],[7,9],[4,8],[0,3,9],[],[0,1,7],[2,6],[1,3],[2,4]]
        mod = 10**9 + 7
        
        if n == 1:
            return 10
        curr_total = []
        last_step_totals = [1 for _ in range(10)]
        
        for i in range(n - 1):
            curr_total = [0 for _ in range(10)]
            
            for i in range(10):
                for jump_location in jumps[i]:
                    curr_total[i] += last_step_totals[jump_location]
            last_step_totals = curr_total
        return sum(curr_total) % mod
        
        
        
        
        


class Solution:
    def knightDialer(self, n: int) -> int:
        #recursive + memo
#         next_map = {0:[4,6],1:[6,8],2:[7,9],3:[4,8],4:[0,3,9],5:[],6:[0,1,7],7:[2,6],8:[1,3],9:[2,4]}
       
#         def dfs(cur_num,n):
#             if (cur_num,n) in memo.keys():
#                 return memo[(cur_num,n)]
#             if n == 0:
#                 return 1
#             ans = 0
#             for next_num in next_map[cur_num]:                
#                 ans += dfs(next_num,n-1)
#             memo[(cur_num,n)] = ans
#             return ans
        
#         ans = 0
#         MOD = pow(10,9)+7
#         memo = {}
#         for i in range(10):            
#             ans += dfs(i,n-1)%MOD
#             ans = ans%MOD
#         #    print (\"i:{}, ans={}\".format(i,ans))
            
#         return ans

          #dp[numr][n]: represent the total combinations when start with number :num with n steps
          dp = [ [0 for _ in range(n+1)] for _ in range(10)]
          next_map = {0:[4,6],1:[6,8],2:[7,9],3:[4,8],4:[0,3,9],5:[],6:[0,1,7],7:[2,6],8:[1,3],9:[2,4]}
          MOD = pow(10,9)+7
          for i in range(10):
              dp[i][1] = 1
            
          for k in range(2,n+1):
              for i in range(10):
                  for next_num in next_map[i]:
                      dp[i][k] += dp[next_num][k-1]%MOD
                      dp[i][k] =  dp[i][k]%MOD
          ans  = 0  
          for i in range(10):
              ans += dp[i][n]
              ans = ans%MOD
            
          return ans
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            


move_map = {
    0: {4,6},
    1: {6,8},
    2: {7,9},
    3: {4,8},
    4: {3, 9, 0},
    5: {},
    6: {1, 0, 7},
    7: {2, 6},
    8: {1, 3},
    9: {2, 4}
}

class Solution:    
    def knightDialer(self, n: int) -> int:
        table = {}
        for key in move_map:
            table[key, 1] = 1
            
        for N in range(2,n+1):
            for key in move_map:
                val = 0
                for new_key in move_map[key]:
                    val += table[new_key, N-1]
                table[key, N] = val
                
        res = 0
        for key in move_map:
            res += table[key, n]
        return res % (10**9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        # dp(0, digit) = 0
        # dp(n steps, digit) = sum(dp(n - 1, f) for f in digit's friends)
        if n == 0:
            return 0
        
        friends = [0] * 10
        friends[0] = [4, 6]
        friends[1] = [6, 8]
        friends[2] = [7, 9]
        friends[3] = [8, 4]
        friends[4] = [0, 3, 9]
        friends[5] = []
        friends[6] = [0, 1, 7]
        friends[7] = [2, 6]
        friends[8] = [1, 3]
        friends[9] = [2, 4]
        
        dp = [[0 for _ in range(10)] for _ in range(n + 1)]
        dp[1] = [1] * 10
        for steps in range(2, n + 1):
            for digit in range(10):
                dp[steps][digit] = sum([dp[steps - 1][f] for f in friends[digit]]) % (10**9 + 7)
        
        return sum(dp[-1]) % (10**9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        next_move = { 0: [4,6], 1: [6,8], 2: [7,9], 3: [4,8], 4: [0,3,9], 5: [], 6: [0,1,7], 7:[2,6], 8: [1,3], 9: [2,4]}
        mod_num = 10**9 + 7
        dp_prev = [1] * 10
        
        for i in range(n-1):
            dp_new = [0] * 10
            for num in range(10):
                phones_for_num = sum((dp_prev[x] for x in next_move[num])) % mod_num
                dp_new[num] = phones_for_num
            dp_prev = dp_new

        return sum(dp_prev) % mod_num

class Solution:
    def knightDialer(self, n: int) -> int:
        
        if n == 1:
            return 10
        maps = {
            0: {4, 6},
            1: {6, 8},
            2: {7, 9},
            3: {4, 8},
            4: {3, 9, 0},
            5: {},
            6: {1, 7, 0},
            7: {2, 6},
            8: {1, 3},
            9: {4, 2}
        }
        prev = [1]*10
        for i in range(1, n):
            curr = [0]*10
            for j in range(0, 10):
                curr[j] = sum(prev[k] for k in maps[j])
            prev = curr
        return sum(prev)%(10**9+7)
                
        


class Solution:
    def knightDialer(self, n: int) -> int:
        dp=[[4,6],[6,8],[7,9],[4,8],[0,3,9],[],[0,1,7],[2,6],[1,3],[4,2]]
        ct=[1]*10

        while n-1:
            tmp=[]
            for i in range(10):
                tmp+=[sum(ct[j] for j in dp[i])]
            ct=tmp
            n-=1

        return sum(ct)%(10**9 + 7)


possible = {
    -1: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
    0: [4, 6],
    1: [6, 8],
    2: [7, 9],
    3: [4, 8],
    4: [0, 3, 9],
    5: [],
    6: [0, 1, 7],
    7: [2, 6],
    8: [1, 3],
    9: [2, 4]
}

cache = {}

class Solution:
    def knightDialer(self, n: int) -> int:
        total = self.helper(-1, n, 0) % 1000000007
        return total
    
    
    def helper(self, num, n, total):
        if (num, n) in cache:
            total += cache[(num, n)]
            return total
            
        nxt = possible[num]
        total_begin = total
        if n == 1:
            total += len(nxt)
        else:
            for num_next in nxt:
                total = self.helper(num_next, n-1, total) % 1000000007
        cache[(num, n)] = total - total_begin
        return total

from collections import deque

class Solution:
    
    cache = {}
    d = [(4,6),(6,8),(7,9),(4,8),(3,9,0),(),(1,7,0),(2,6),(1,3),(2,4)] 

    def dfs(self, i, n):
        if n == 0: return 1
        elif (i, n) not in self.cache:
            self.cache[i, n] = sum(self.dfs(val, n-1) for val in self.d[i])  # Memoization
            if i in [1,4,7]: self.cache[i+2, n] = self.cache[i, n]           # Symmetry
            elif i in [3,6,9]: self.cache[i-2, n] = self.cache[i, n]
        return self.cache[i, n]
    
    def knightDialer(self, n: int) -> int:
        return sum(self.dfs(i, n-1) for i in range(10)) % (int(1e9)+7)
                


class Solution:
    def knightDialer(self, n: int) -> int:
        d = {
            0: [4,6],
            1: [6,8],
            2: [9,7],
            3: [4,8],
            4: [3,9,0],
            5: [],
            6: [1,7,0],
            7: [6,2],
            8: [3,1],
            9: [4,2]
        }
        res = 0
        dp = [1]*10
        for x in range(1,n):
            temp = [0]*10
            for i in range(10):
                for j in d[i]:
                    temp[j] += dp[i]
            dp = temp 
        res = sum(dp) % ((10**9)+7)
        return res 


class Solution:
    def knightDialer(self, n: int) -> int:
        moveable = {
        1: [6, 8],
        2: [7, 9],
        3: [4, 8],
        4: [0, 3, 9],
        5: [],
        6: [0, 1, 7],
        7: [2, 6],
        8: [1, 3],
        9: [2, 4],
        0: [4, 6]
        }
        MOD = 7 + 1e9
        @lru_cache(maxsize=None)
        def helper(step, num=-1):
            if step == n:
                return 1

            result = 0
            if num == -1:
                for i in range(10):
                    result = (result + helper(step + 1, i)) % MOD
            else:
                for move in moveable[num]:
                    result = (result + helper(step + 1, move)) % MOD
            return result

        return int(helper(0))

class Solution:
    def knightDialer(self, n: int) -> int:
        d = {1:[6,8],2:[7,9],3:[8,4],4:[0,3,9],5:[],6:[0,1,7],7:[2,6],8:[1,3],9:[2,4],0:[4,6]}
        f = [[0]*10 for i in range(2)]
        f[1&1] = [1]*10
        for i in range(2,n+1):
            f[i&1] = [0]*10
            for j in range(10):
                for v in d[j]:
                    f[i&1][v] += f[(i-1)&1][j] % (10**9+7)
            # print(f[i&1])
        return sum(f[n&1]) % (10**9+7)

class Solution:
    def knightDialer(self, n: int) -> int:
        # recursive backtracking:
        # you have 4 options: 
        #     (2 right, 1 down)
        #     (2 right, 1 up)
        #     (2 left, 1 down)
        #     (2 left, 1 up)
        # we have a grid, 4 by 3
        if n == 1:
            return 10
        # grid = [
        #     [1, 2, 3],
        #     [4, 5, 6],
        #     [7, 8, 9],
        #     [-1,0,-1]
        # ]
        # # append the number after reaching node
        # # we could do dynamic programming and remember how many we can reach if 
        # # we are at a specific n
        # # at 0,0:
        # # we can create a graph of things we can connect,
        # # ie how many things can we reach from where we are right now
        
        # 0 - 9 are the connections
        maps = {
            0: {4, 6},
            1: {6, 8},
            2: {7, 9},
            3: {4, 8},
            4: {3, 9, 0},
            5: {},
            6: {1, 7, 0},
            7: {2, 6},
            8: {1, 3},
            9: {4, 2}
        }
        prev = [1]*10
        for i in range(1, n):
            curr = [0]*10
            for j in range(0, 10):
                curr[j] = sum(prev[k] for k in maps[j])
            prev = curr
        return sum(prev)%(10**9+7)
                
        
        '''
            this index is the sum of all previous possibilities
            we see when we reach at index 1, there are 2 places we could have came from
            we have n total moves and 9 total numbers
            we start at number 1, number 1 is connected to 6 and 8
            now we go to 6 and 8,
                6 connected to 1, 0, 7
                8 connected to 1, 3
                
                can we some how sum for each n?
                opt(i, j) = sum(opt(i-1, j) for j in connected )
                return the sum of the top part of the array
                
                
                
                n=2 [1= arr[i-1][6]+arr[i-1][[8] ... ]]
                n=1 [1:1, 2:1, 3:1 ... 0:1]
            
        
        '''
        
        
        
        
        
        
#         count = 0
#         numbers = set()
#         def recursion(x, y, number, depth):
#             nonlocal count, numbers
#             if depth > n:
#                 return
#             if not(0<= x < 4 and 0<=y<3 and grid[x][y]!=-1):
#                 return
#             if depth == n:
#                 numbers.add(number)
#                 return
#             else:
#                 number+=grid[x][y]*(10**depth)
#                 recursion(x+2, y-1, number, depth+1)
#                 recursion(x+2, y+1, number, depth+1)
                
#                 recursion(x-2, y-1, number, depth+1)
#                 recursion(x-2, y+1, number, depth+1)
                
#                 recursion(x+1, y+2, number, depth+1)
#                 recursion(x+1, y-2, number, depth+1)
                
#                 recursion(x-1, y+2, number, depth+1)
#                 recursion(x-1, y-2, number, depth+1)
                
#                 return
#         for x in range(0, 4):
#             for y in range(0, 3):
#                 recursion(x, y, 0, 0)
#         print(numbers)
#         return len(numbers)%(10**9+7)


possibilities = {
    1: [6,8],
    2: [7,9],
    3: [8,4],
    4: [9,3,0],
    5: [],
    6: [1,7,0],
    7: [6,2],
    8: [1,3],
    9: [2,4],
    0: [4,6],
}


class Solution:
    def knightDialer(self, N: int) -> int:
        if N == 1:
            return 10
        
        counter = 0
        num_ways = [1,1,1,1,1,0,1,1,1,1]
        for i in range(N-1):
            updated = [0]*10
            for digit in range(10):
                updated[digit] = sum([num_ways[previous] % int(10e8+7) for previous in possibilities[digit]]) 
            num_ways = updated
        return sum(num_ways) % int(10e8+7)
        
        
        
        
        
        




class Solution:
    def knightDialer(self, N: int) -> int:
        res = [1] * 10  # 每个位置出现的次数
        next_move = [[4,6],[6,8],[7,9],[4,8],[0,3,9],[],[0,1,7],[2,6],[1,3],[2,4]]
        i = 1
        while i < N:
            res2 = [0] * 10
            for k, v in enumerate(res):
                for j in next_move[k]:  # 对于跳到的下一个位置，更新出现的次数
                    res2[j] += v
            res = res2  # 更新结果
            i += 1
        return sum(res) % (10**9 +7)  # 不要忘记取余
#https://www.jianshu.com/p/caa2c35321a7


class Solution:
    def knight(self, n, current, memo):
        knight_mp = {1: {8, 6},
                    2: {9, 7},
                    3: {4, 8},
                    4: {3, 9, 0}, # 0 also
                    5: {},
                    6: {7, 1, 0}, # 0 also
                    7: {2, 6},
                    8: {3, 1},
                    9: {2, 4},
                    0: {6, 4}}        

        if n==1:
            return 1
        if (current, n) in memo:
            return memo[(current, n)]
        res = 0
        for item in knight_mp.get(current, set()):
            res+=self.knight(n-1, item, memo)
            
            
        memo[(current, n)] = res
        return res
        
    def knightDialer(self, n: int) -> int:
#         res = 0
#         mod = 10**9+7
#         memo = {}
#         for i in range(0, 10):
#             res+=self.knight(n, i, memo)%mod
#         return res%mod
    
    
        knight_mp = {1: {8, 6},
                    2: {9, 7},
                    3: {4, 8},
                    4: {3, 9, 0}, # 0 also
                    5: {},
                    6: {7, 1, 0}, # 0 also
                    7: {2, 6},
                    8: {3, 1},
                    9: {2, 4},
                    0: {6, 4}}        

        dp = [[0 if i!=0 else 1 for _ in range(0, 10)] for i in range(n)]
        mod = 10**9+7

        for step in range(1, n):
            for cell in range(0, 10):
                for neighbor in knight_mp.get(cell, set()):
                    dp[step][cell] += dp[step-1][neighbor]
        return sum(dp[n-1])%mod
    
    


class Solution:
    def knightDialer(self, N: int) -> int:
        possible_moves = [
            [4, 6],
            [6, 8],
            [7, 9],
            [4, 8],
            [3, 9, 0],
            [],
            [1, 7, 0],
            [2, 6],
            [1, 3],
            [2, 4]
        ]
        
        dp = [1 for _ in range(10)]
        for _ in range(1, N):
            dp1 = [0 for _ in range(10)]
            for i in range(10):
                for m in possible_moves[i]:
                    dp1[i] += dp[m]
            dp = dp1
        
        return sum(dp) % (pow(10, 9) + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 1: return 10
        
        move_dict = {0: [4, 6], 1: [6, 8], 2: [7, 9], 3: [4, 8], 4: [0, 3, 9], 
                     5: [], 6: [0, 1, 7], 7: [2, 6], 8: [1, 3], 9: [2, 4]}
        MOD = 10**9+7
        # dp[i] suggests how many ways we can move to i on the phone pad
        dp = [2, 2, 2, 2, 3, 0, 3, 2, 2, 2]
        
        # the first two moves are done
        for i in range(n-2):
            new_dp = [2, 2, 2, 2, 3, 0, 3, 2, 2, 2]
            for d in range(10):
                new_dp[d] = sum(dp[move] for move in move_dict[d]) % MOD
            dp = new_dp
            
        return sum(dp) % MOD
        
        


class Solution(object):
    def knightDialer(self, N):
        MOD = 10**9 + 7
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]

        dp = [1] * 10
        for hops in range(N-1):
            dp2 = [0] * 10
            for i, c in enumerate(dp):
                for nei in moves[i]:
                    dp2[i] += dp[nei]
                    dp2[i] %= MOD
            dp = dp2
        return sum(dp) % MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        # DP 每次要加上那个格的DP值
        #{4, 6}, {6, 8}, {7, 9}, {4, 8}, {3, 9, 0}, {}, {1, 7, 0}, {2, 6}, {1, 9}, {4, 2}
        # 二维数组 表示第i次跳到j上有多少种方法
        # 比如到4的时候 那么可能是从3,9,0 来的 那么i,4 = i,4 + i-1 (3,9,0)
        stack = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],[1,7,0],[2,6],[1,9],[4,2]]
        dp = [[0 for _ in range(10)] for __ in range(n)]
        for i in range(10):     # 随便放  所有按键都初始为1 因为n是跳的次数 放的不算
            dp[0][i] = 1
        for i in range(1,n):
            for j in range(10):
                for k in stack[j]:
                    dp[i][j] = (dp[i][j] + dp[i-1][k]) % (10**9 + 7)
        return sum(dp[-1][i] for i in range(10))  % (10**9 + 7)

class Solution:
    def initMoveTable(self):
        moveTable = dict()
        moveTable[0] = [4, 6]
        moveTable[1] = [6, 8]
        moveTable[2] = [7, 9]
        moveTable[3] = [4, 8]
        moveTable[4] = [0, 3, 9]
        moveTable[5] = []
        moveTable[6] = [0, 1, 7]
        moveTable[7] = [2, 6]
        moveTable[8] = [1, 3]
        moveTable[9] = [2, 4]
        
        return moveTable
        
    def knightDialer(self, n: int) -> int:
        if n == 0:
            return 0
        if n == 1:
            return 10
        
        moveTable = self.initMoveTable()
        dp = []
        for i in range(n+1):
            newRow = []
            for j in range(10):
                newRow.append(None)
            dp.append(newRow)
            
        for i in range(10):
            dp[1][i] = 1
            
    
        for i in range(2, n+1):
            for j in range(10):
                localNumWays = 0
                moves = moveTable[j]
                for move in moves:
                    localNumWays += dp[i-1][move]
                dp[i][j] = localNumWays % (pow(10,9) + 7)
                
        return sum(dp[i]) % (pow(10,9) + 7)


class Solution:
    main_dic = {}
    
    def __init__(self):
        dic = {}
        for i in range(4):
            for j in range(3):
                if i==3 and (j==0 or j==2): continue
                dic[(i,j)] = self.get_ind(i,j)
        self.main_dic = dic
    
    def get_ind(self,i,j):
        lst = []
        lst.append((i+2,j-1))
        if not self.check_ind(lst[-1]): lst.pop()
        lst.append((i+2,j+1))
        if not self.check_ind(lst[-1]): lst.pop()
        lst.append((i-2,j-1))
        if not self.check_ind(lst[-1]): lst.pop()
        lst.append((i-2,j+1))
        if not self.check_ind(lst[-1]): lst.pop()
        lst.append((i+1,j+2))
        if not self.check_ind(lst[-1]): lst.pop()
        lst.append((i-1,j+2))
        if not self.check_ind(lst[-1]): lst.pop()
        lst.append((i+1,j-2))
        if not self.check_ind(lst[-1]): lst.pop()
        lst.append((i-1,j-2))
        if not self.check_ind(lst[-1]): lst.pop()
        return lst
        
    def check_ind(self,t):
        i,j = t
        if i<0 or j<0: return False
        if i>3 or j>2: return False
        if i==3 and (j==0 or j==2): return False
        return True
    
    def knightDialer(self, n: int) -> int:
        if n==1: return 10;
        
        old = [[1]*3 for i in range(4)]
        old[3][0],old[3][2]=0,0
        
        for k in range(n-1):
            new = []
            for i in range(4):
                temp = []
                for j in range(3):
                    if i==3 and (j==0 or j==2): 
                        temp.append(0)
                        continue
                    lst,res = self.main_dic[(i,j)],0
                    for m,n in lst:
                        res+=old[m][n]
                    temp.append(res)
                new.append(temp)
            old = new
        res = sum([sum(l) for l in old])
        return res%(10**9 + 7)
            


class Solution:
    def knightDialer(self, N: int) -> int:
        
        
        hop_map = {1:[6,8],
                  2:[7,9],
                  3:[4,8],
                  4:[0,3,9],
                  6:[0,1,7],
                  7:[2,6],
                  8:[1,3],
                  9:[2,4],
                  0:[4,6]}
        
        memo = {(i,1): 1 for i in range(10)}
        
        def num_hops(key:int, N:int):

            if N == 1:
                return 1
            
            if key in [1,4,7]:
                key += 2
            elif key == 5:
                return 0
            
            if (key, N) in memo:
                return memo[(key, N)]
            
            sum_ = 0
            for v in hop_map[key]:
                sum_ += num_hops(v, N-1)
            
            memo[(key, N)] = sum_ % (10**9 + 7)
            return sum_
    
        sum_ = 0
        for i in range(10):
            sum_ += num_hops(i, N)  % (10**9 + 7)
        return sum_  % (10**9 + 7)


from collections import deque

MOD = 10 ** 9 + 7

class Solution:
    def knightDialer(self, n: int) -> int:
        m = {
            0: [4, 6],
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [3, 9, 0],
            5: [],
            6: [1, 7, 0],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4]
        }
        
        curt = {i: 1 for i in range(0, 10)}
        n -= 1        
        
        while n > 0:
            next_set = {}
            for key in curt:
                for nei in m[key]:
                    next_set[nei] = (next_set.get(nei, 0) + curt[key]) % MOD
                    
            curt = next_set
            n -= 1
        
        return sum(curt.values()) % MOD
        
            
        


class Solution:
    def knightDialer(self, n: int) -> int:
        x0, x1, x2, x3, x4, x5, x6, x7, x8, x9 = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
        mod = pow(10, 9) + 7
        for i in range(n - 1):
            t0 = (x4 + x6) % mod
            t1 = (x6 + x8) % mod
            t2 = (x7 + x9) % mod
            t3 = (x4 + x8) % mod
            t4 = (x0 + x3 + x9) % mod
            t5 = 0
            t6 = (x0 + x1 + x7) % mod
            t7 = (x2 + x6) % mod
            t8 = (x1 + x3) % mod
            t9 = (x2 + x4) % mod
            x0, x1, x2, x3, x4, x5, x6, x7, x8, x9 = t0, t1, t2, t3, t4, t5, t6, t7, t8, t9
            
        return (x0 + x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9) % mod

class Solution:
    def knightDialer(self, n: int) -> int:
        dct={0:[4,6],1:[6,8],2:[7,9],3:[4,8],4:[0,3,9],5:[],6:[0,1,7],7:[2,6],8:[1,3],9:[2,4]}
        
        def func(k):
            
            if k==1:
                return {i:1 for i in range(10)}
                        
            res=func(k-1)
            
            counts={i:0 for i in range(10)}
            
            for i in range(10):
                for t in dct[i]:
                    counts[t]+=res[i]
                    
            return counts
        
        
        res=func(n)
        
        return sum(res.values())%(10**9+7)

from functools import lru_cache
class Solution:
    def knightDialer(self, n: int) -> int:
        @lru_cache(None)
        def jumps(start, n):
            if n == 0:
                return 1
            ans = 0
            for neighbor in neighbors[start]:
                ans = (ans + jumps(neighbor, n-1)) % MOD
            return ans % MOD
        
        neighbors = {
            1: [6,8],
            2: [7,9],
            3: [4,8],
            4: [0,3,9],
            5: [],
            6: [0,1,7],
            7: [2,6],
            8: [1,3],
            9: [2,4],
            0: [4,6]
        }
        MOD = pow(10, 9) + 7
        res = 0
        for i in range(10):
            res = (res + jumps(i, n-1)) % MOD
        return res

class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10**9 + 7
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]
        
        dp = [[None]*10 for _ in range(n)]
        for i in range(10):
            dp[0][i] = 1
            
        def helper(node, jumpsLeft):
            if dp[jumpsLeft][node]:
                return dp[jumpsLeft][node]
            cnt = 0
            for nextJump in moves[node]:
                cnt += helper(nextJump, jumpsLeft - 1)
                cnt %= MOD
            dp[jumpsLeft][node] = cnt
            return cnt
        
        for i in range(10):
            helper(i, n-1)
            
        return sum(dp[n-1]) % MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        mod = 10 ** 9 + 7
        nei = {0: [4, 6,], 1: [6, 8], 2: [7, 9], 3: [4, 8], 4: [0, 3, 9], 5: [], 6: [0, 1, 7], 7: [2, 6], 8: [1, 3], 9: [2, 4]}
        
        @lru_cache(None)
        def dfs(i, pre):
            if i == n:
                return 1
            cand = nei[pre] if pre != None else range(10)
            ans = 0
            for k in cand:
                ans += dfs(i + 1, k) % mod
            return ans % mod
        
        return dfs(0, None)

class Solution:
    def knightDialer(self, n: int) -> int:
        # dp[i][move] = [dp[neighbor][move - 1]for neighbor in neighbors]
        neighbors = {1:[6,8], 2:[7,9],3:[4,8],4:[0,3,9],5:[],6:[0,1,7],7:[2,6],8:[1,3],9:[2,4],0:[4,6]}
        if n == 0:
            return 0
        dp = [[1 for i in range(n)] for i in range(10)]
        for move in range(1,n):
            for num in range(10):
                dp[num][move] = sum([dp[neighbor][move - 1] for neighbor in neighbors[num]]) % 1000000007
        return sum([dp[num][n-1] for num in range(10)]) % 1000000007


class Solution:
    def knightDialer(self, n: int) -> int: 
        w = [1]
        x = [1]
        y = [1]
        z = [1]
        
        for i in range(n-1):
            w_n = 2*x[-1]
            x_n = w[-1] + 2*y[-1]
            y_n = x[-1] + z[-1]
            z_n = 2*y[-1]
            w.append(w_n)
            x.append(x_n)
            y.append(y_n)
            z.append(z_n)
            
        return (w[-1] + 2*x[-1] + 4*y[-1] + 2*z[-1] + (1 if n == 1 else 0)) % (10**9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        path={
            0:[4,6],
            1:[6,8],
            2:[7,9],
            3:[4,8],
            4:[0,3,9],
            5:[],
            6:[0,1,7],
            7:[2,6],
            8:[1,3],
            9:[2,4]
        }
        M=10**9+7
        dp=[[None for _ in range(n) ] for _ in range(10)]
        def paths(i,n):
            if dp[i][n]:
                return dp[i][n]
            #number of ways to jump from i n times          
            if n==1:
                return len(path[i])
            if n==0:
                return 1
            s=0
            for v in path[i]:
                s+=paths(v,n-1)
            dp[i][n]=s%M
            return dp[i][n]
        ans=0
        for k in path:
            ans+=paths(k,n-1)
        return ans%(M)
                
            


class Solution:
    def knightDialer(self, n: int) -> int:
        h = {
            0: [4, 6],
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [0, 3, 9],
            5: [],
            6: [0, 1, 7],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4]
        }
        
        if n == 1:
            return 10
        
        o = []
        le = 0
        
        oTrack = [0] * 10
        track = [0] * 10
        
        for loops in range(n - 1):
            track = [0] * 10
            for k,v in enumerate(track):
                #print(\"k: \", k, track)
                hg = h.get(k)
                for i in hg:
                    track[i] += max(oTrack[k], 1)
                    
            
            #print(\"loop: \", loops, p, track, oTrack)
            oTrack = track.copy()
            
        
        return sum(track) % (10 ** 9 + 7)


class Solution:
        
    def knightDialer(self, n: int) -> int:
        MOD = 10**9 + 7
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]

        dp = [1] * 10
        for hops in range(n-1):
            dp2 = [0] * 10
            for node, count in enumerate(dp):
                for nei in moves[node]:
                    dp2[nei] += count
                    dp2[nei] %= MOD
            dp = dp2
        return sum(dp) % MOD


class Solution:
    def knightDialer(self, n: int) -> int:
        prior_case = [1]*10
        current_case = [1]*10
        paths = {1: [6, 8], 2: [7, 9], 3: [4, 8], 4: [3, 9, 0], 5: [], 6: [1, 7, 0], 7: [2,6], 8: [1,3], 9: [2, 4], 0: [4,6]}
        curr_hop = 1
        
        while curr_hop < n:
            curr_hop += 1
            current_case = [0]*10
            
            for num in range(10):
                for neighbor in paths[num]:
                    current_case[num] += prior_case[neighbor]
                    
            prior_case = current_case
            
        return sum(current_case) % (10**9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        
        mm = {
            1: [6, 8],
            2: [7, 9],
            3: [8, 4],
            4: [3, 9, 0],
            5: [],
            6: [1, 7, 0],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4],
            0: [6, 4]
        }
        
        ans = 0
        
        @lru_cache(maxsize=None)
        def dfs(val, rem):
            if rem == 0:
                return 1
            
            res = 0
            for adj in mm[val]:
                res += dfs(adj, rem - 1)
                
            return res
        
        for key in list(mm.keys()):
            ans += dfs(key, n - 1)
            
        return ans % 1000000007


class Solution:
    def knightDialer(self, N: int) -> int:
        
        
        hop_map = {1:[6,8],
                  2:[7,9],
                  3:[4,8],
                  4:[0,3,9],
                  6:[0,1,7],
                  7:[2,6],
                  8:[1,3],
                  9:[2,4],
                  0:[4,6]}
        
        memo = {(i,1): 1 for i in range(10)}
        
        def num_hops(key:int, N:int):

            if N == 1:
                return 1
            
            if key in [1,4,7]:
                key += 2
            elif key == 5:
                return 0
            
            if (key, N) in memo:
                return memo[(key, N)]
            
            sum_ = 0
            for v in hop_map[key]:
                sum_ += num_hops(v, N-1)
            
            memo[(key, N)] = sum_ 
            return sum_
    
        sum_ = 0
        for i in range(10):
            sum_ += num_hops(i, N) 
        return sum_  % (10**9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 0 or not n:
            return 0
        
        graph = {0:[4,6],
                 1:[6,8],
                 2:[7,9],
                 3:[4,8],
                 4:[3,9,0],
                 5:[],
                 6:[1,7,0],
                 7:[2,6],
                 8:[1,3],
                 9:[2,4]}
        @lru_cache(maxsize=None)
        def helper(left, curr): 
            
            if left == 1:
                return 1
            
            cnt = 0
            for nei in graph[curr]:
                cnt += helper(left-1, nei)
            return cnt
        #n = 3
        ans = 0
        for i in range(10):
            ans += helper(n, i)
        return ans %(10**9+7)
        


class Solution:
    def knightDialer(self, n: int) -> int:
        neighbors = {
            0: [4, 6], 
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [0, 3, 9],
            5: [],
            6: [0, 1, 7],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4]
        }

        count = 0
        num_each_digit = {
            0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 1, 8: 1, 9: 1
        } 
        for i in range(1, n+1):
            count = sum(num_each_digit.values()) 
            temp_dict = {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0}
            for digit in num_each_digit: 
                num_digit = num_each_digit[digit]
                digit_neighbors = neighbors[digit]
                for neighbor in digit_neighbors: 
                    temp_dict[neighbor] += num_digit 
            num_each_digit = temp_dict
        return count % (10**9 + 7)
            


class Solution:
    def knightDialer(self, n: int) -> int:
        def matmul(A, B):
            BT = list(zip(*B))
            res = [[sum((x*y) for x, y in zip(row, col))%M for col in BT] for row in A]
            return res
        
        def pow(A, n):
            
            l = n.bit_length()
            res = [[1 if i==j else 0 for j in range(len(A[0]))] for i in range(len(A))]
            tmp = A
            
            for i in range(l):
                
                mask = 1 << i
                
                if mask & n != 0:
                    res = matmul(res, tmp)
                    
                tmp = matmul(tmp, tmp)
                
            return res
        
        M = 10**9+7
        A = [[0,0,0,0,1,0,1,0,0,0],
             [0,0,0,0,0,0,1,0,1,0],
             [0,0,0,0,0,0,0,1,0,1],
             [0,0,0,0,1,0,0,0,1,0],
             [1,0,0,1,0,0,0,0,0,1],
             [0,0,0,0,0,0,0,0,0,0],
             [1,1,0,0,0,0,0,1,0,0],
             [0,0,1,0,0,0,1,0,0,0],
             [0,1,0,1,0,0,0,0,0,0],
             [0,0,1,0,1,0,0,0,0,0]]
        
        res = matmul([[1,1,1,1,1,1,1,1,1,1]], pow(A,n-1))
        
        return sum(res[0]) % M


class Solution:
    def knightDialer(self, N: int) -> int:
        numpad = [[1,2,3],[4,5,6],[7,8,9],['*',0,'#']]
        dp = [1,1,1,1,1,1,1,1,1,1]
        square = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],[7,0,1],[2,6],[1,3],[2,4]]
        mod = 10**9+7
        for i in range(2,N+1):
            temp=[0,0,0,0,0,0,0,0,0,0]
            for row in range(4):
                for col in range(3):
                    if numpad[row][col] == '*' or numpad[row][col] == '#':
                        continue
                    else:
                        num = numpad[row][col]
                        for j in square[num]:
                            temp[num] += dp[j]%mod
            dp=temp
        return sum(dp)%mod
                                


class Solution:
    def knightDialer(self, n: int) -> int:
        
        moves = {1:[6, 8], 2:[7, 9], 3:[4, 8], 4:[0, 3, 9], 5:[], 6:[0, 1, 7], 7:[2, 6], 8:[1, 3], 9:[2, 4], 0:[4, 6]}
        
        from functools import lru_cache
        @lru_cache(maxsize = None)
        def dfs(i, length):
            if n == length:
                return 1
            
            total = 0
            for newI in moves[i]:
                total += dfs(newI, length + 1)
            return total
        
        bound = 10**9+7
        
        ans = 0
        for i in range(0, 10):
            ans += dfs(i, 1)
            if ans >= bound:
                ans = ans%bound
        return ans

class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10**9 + 7
        
        next_moves = defaultdict(list)
        next_moves[1] = [6, 8]
        next_moves[2] = [7, 9]
        next_moves[3] = [4, 8]
        next_moves[4] = [0, 3, 9]
        next_moves[5] = []
        next_moves[6] = [0, 1, 7]
        next_moves[7] = [2, 6]
        next_moves[8] = [1, 3]
        next_moves[9] = [2, 4]
        next_moves[0] = [4, 6]
        
        solutions = [1 for _ in range(10)]
        while n > 1:
            next_solutions = []
            for last_num in range(0, 10):
                count = sum(solutions[prev] for prev in next_moves[last_num])
                if count >= MOD: count %= MOD
                next_solutions.append(count)
            solutions = next_solutions
            n -= 1
                
        return sum(solutions) % MOD
        
        
        memo = dict()
        
        def count(size, at):
            if size == 0: return 1
            if (size, at) in memo: return memo[(size, at)]
            
            c = sum(count(size - 1, next_at) for next_at in next_moves[at])
            if c >= MOD: c %= MOD
            
            memo[(size, at)] = c
            return c
        
        total_possible = sum(count(n - 1, at) for at in range(0, 10))
        return total_possible % MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        mod = pow(10, 9) + 7
        maps = {
            0: [4, 6],
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [0, 3, 9],
            5: [],
            6: [0, 1, 7],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4],
        }
        
        dp = [[0] * n for _ in range(10)]
        for i in range(10):
            dp[i][0] = 1
            
        for i in range(1, n):
            for digit in range(10):
                dp[digit][i] = sum(dp[j][i-1] for j in maps[digit])
                
        return sum(dp[digit][-1] for digit in range(10)) % mod


class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 1:
            return 10
        D = []
        modulo = 10**9 + 7
        
        movesDict = { 0: [4, 6], 1: [6, 8], 2: [7,9], 3: [4,8], 4: [3,9,0],
                      5: [], 6: [1,7 ,0],  7: [2,6], 8: [1,3], 9: [2,4]}
        
        for i in range(10):
            D.append([-1]*(n+1))
        
        def help(start, length):
            if length == 1:
                return 1
            if D[start][length] != -1:
                return D[start][length]
            moves = movesDict[start]
            total = 0
            for newStart in moves:
                total += help(newStart, length - 1)
                total %= modulo
            D[start][length] = total
            # print(f'start: {start}, length: {length}, total: {total}')
            return total
        
        res = 0
        for i in range(10):
            res += help(i, n)
        return res % modulo 
        
        
'''
1 -> 6, 8
2 -> 7, 9
3 -> 4, 8
4 -> 3, 9, 0
5 -> n/a
6 -> 1, 7, 0
7 -> 2, 6
8 -> 1, 3
9 -> 2, 4
dp - solve how many for n - 1 starting at some index then ?
array [start][length]
init with [10][n+1]



'''


class Solution:
    def knightDialer(self, n: int) -> int:
        def knight_dailer(n):
            paths = {0: [4, 6], 1: [6, 8], 2: [9, 7], 3: [4, 8], 4: [3, 9, 0], 5: [], 6: [1, 7, 0], 7: [6, 2], 8: [1, 3],
                     9: [4, 2]}
            count = 0
            import sys, functools
            sys.setrecursionlimit(10**9)

            @functools.lru_cache(None)
            def traverse(i, rem):
                if rem == 0:
                    return 1
                ans = 0
                for p in paths[i]:
                    res = traverse(p,rem-1)
                    ans += res
                return ans
            for i in range(10):
                count += (traverse(i,n-1))
            return count % ((10**9) + 7)
        return knight_dailer(n)

class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10 ** 9 + 7
        map = [[4, 6], [6, 8], [7, 9], [4, 8], [0, 3, 9], [], [0, 1, 7], [2, 6], [1, 3], [2, 4]]
        
        dp = [1] * len(map)
        for hops in range(n - 1):
            dp2 = [0] * len(map)
            for node, cnt in enumerate(dp):
                for nei in map[node]:
                    dp2[nei] += cnt
                    dp2[nei] %= MOD
            dp = dp2
        return sum(dp) % MOD


class Solution:
    def knightDialer(self, n: int) -> int:

    
        dp = [ [0] * 10 for _ in range(n)]
        
        pad_map = {
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [0, 3, 9],
            5: [],
            6: [0, 1, 7],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4],
            0: [4, 6]
        }
        mod = 10**9 + 7
        
        for i in range(10):
            dp[0][i] = 1
            
        for i in range(n - 1):
            for j in range(10):
                
                dsts = pad_map[j]
                
                for dst in dsts:
                    dp[i + 1][dst] = (dp[i][j] + dp[i + 1][dst]) % mod
                
                
        
            
        return sum(dp[-1])%mod

class Solution:
    def knightDialer(self, N: int) -> int:
        
        d = {1: [6, 8], 2: [7, 9], 3: [4, 8], 4: [3, 9, 0], 6: [1, 7, 0], 7: [2, 6], 8: [1, 3], 9: [4, 2], 5: [], 0: [4, 6]}
        
        @lru_cache(None)
        def helper(k, i):
            if k == 0:
                return 1
            r = 0
            for n in d[i]:
                r += helper(k - 1, n)
            return r
        ans = 0
        
        for n in list(d.keys()):
            ans += helper(N - 1, n)
            
        return ans % (10 ** 9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        mod = int(1e9)+7
        d = {1: [6, 8], 2: [7, 9], 3: [4, 8], 4: [0, 3, 9], 5: [], 6: [0, 1, 7], 7:[2,6], 8: [1,3], 9:[2, 4], 0: [4,6]}
        ans = {}
        # 1,3; 4,6; 7,9
        @lru_cache(maxsize=None)
        def dfs(i, n):
            nonlocal d
            if n == 0: return 1
            ans = 0
            for val in d[i]:
                ans += dfs(val, n-1)
            return ans    
        for i in range(10):
            if i in [3,6,9]:
                ans[i] = ans[i-2]
            else:    
                ans[i] = dfs(i, n-1)
        #print(ans)                
        return sum(ans.values()) % mod
        # mod = int(1e9)+7
        # d = {1: [6, 8], 2: [7, 9], 3: [4, 8], 4: [0, 3, 9], 5: [], 6: [0, 1, 7], 7:[2,6], 8: [1,3], 9:[2, 4], 0: [4,6]}
        # cache = collections.defaultdict(int)
        # #@lru_cache(maxsize=None)
        # def dfs(i, n):
        #     if i in [3,6,9] and cache[i-2, n] != 0: return cache[i-2, n]
        #     if i in [1,4,7] and cache[i+2, n] != 0: return cache[i+2, n]
        #     nonlocal d
        #     if not n: return 1
        #     s = sum(dfs(val, n-1) for val in d[i])
        #     cache[i, n] = s
        #     return s
        # 
        # return sum(dfs(i, n-1) for i in range(10)) % mod


class Solution:
    def knightDialer(self, n: int) -> int:
        mod = 10**9 + 7
        dp = [[0 for _ in range(10)] for _ in range(n)]
        for i in range(10):
            dp[0][i] = 1
        
        def check(k):
            if k == 0:
                return [4, 6]
            elif k == 1:
                return [6,8]
            elif k == 2:
                return [7, 9]
            elif k == 3:
                return [4, 8]
            elif k == 4:
                return [0, 3, 9]
            elif k == 5:
                return []
            elif k == 6:
                return [0, 1, 7]
            elif k == 7:
                return [2, 6]
            elif k == 8:
                return [1, 3]
            else:
                return [2, 4]
        for i in range(1, n):
            for j in range(10):
                for k in check(j):
                    dp[i][j] = (dp[i][j] + dp[i - 1][k]) % mod
                    
        ans = 0
        for i in range(10):
            ans = (ans + dp[n - 1][i])%mod
        return ans
        


from collections import Counter

class Solution:
    def knightDialer(self, n: int) -> int:
        moves = {1 : [6, 8],
                 2 : [7, 9],
                 3 : [4, 8],
                 4 : [3, 9, 0],
                 6 : [1, 7, 0],
                 7 : [2, 6],
                 8 : [1, 3],
                 9 : [2, 4],
                 0 : [4, 6],
                }
        if n == 1:
            return 10
        
        starts = Counter([i for i in moves])
        for _ in range(n - 1):
            next = Counter()
            for i in starts:
                for j in moves[i]:
                    next[j] += starts[i]
            starts = next
            
        return sum(starts.values()) % (10 ** 9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        dic = {1: [6, 8], 2: [7, 9], 4: [0, 3, 9], 5: [], 7: [2, 6], 8: [1, 3], 0: [4, 6]}
        #1 = 3, 4 = 6, 7 = 9
        pair = {3: 1, 6: 4, 9: 7}
        
        @lru_cache(None)
        def dp(i, n):
            if n == 1: return 1
            if i in pair: i = pair[i]
            res = 0
            for j in dic[i]:
                res += dp(j, n - 1)
            return res
        
        return (2 * (dp(1, n) + dp(4, n) + dp(7, n)) + dp(0, n) + dp(2, n) + dp(5, n) + dp(8, n))%(10 **9 + 7)


class Solution:
    
    def knightDialer(self, n: int) -> int:
        
        valid_moves = {0: (4, 6), 
                       1:(8, 6), 
                       2:(7,9),
                       3:(4,8),
                       4:(0, 3, 9),
                       5:(),
                       6:(0, 1, 7),
                       7:(2, 6),
                       8:(1, 3),
                       9:(2, 4),
                      }
        
        dp = [[0]*10 for _ in range(n)]
        for c in range(10):
            dp[0][c] = 1
        if n > 1:
            for c in range(10):            
                dp[1][c] = len(valid_moves[c])
            
        
        for i in range(2, n):
            for j in range(10):
                valid = valid_moves[j]
                #print (\"computing i: {0}, j:{1} with valid:{2}\".format(i, j, valid))
                dp[i][j] = sum([dp[i-1][r] for r in valid])
        # print (dp)        
        # print (  sum(dp[n-1]) % (10**9+7))
        
        return sum(dp[n-1]) % (10**9+7)


class Solution:
    legal_moves = {
            0: [4, 4],
            1: [6, 8],
            2: [7, 7],
            3: [4, 8],
            4: [0, 1, 7],
            # 5: [],
            6: [0, 1, 7],
            7: [2, 4],
            8: [1, 1],
            9: [2, 4]
        }
    
    def knightDialer(self, n: int) -> int:
        total = 0 if n != 1 else 1
        memo = {}
        for i in range(0, 10):
            if i is not 5:
                total = total + self.num_jumps(i, n - 1, memo)
                
        return total % (pow(10, 9) + 7)
            
    def num_jumps(self, start, jumps_left, memo):
        
        # If we have no moves left we have completed a number
        if jumps_left == 0:
            return 1
        
        # Check if we have done this calculation before
        if (start, jumps_left) not in memo:
            
            # Calculate total number of numbers from this starting position
            total = 0
            for legal_move in self.legal_moves[start]:
                total = total + self.num_jumps(legal_move, jumps_left - 1, memo)
        
            # Save result
            memo[(start, jumps_left)] = total
        
        # Return calculated or retreived result
        return memo[(start, jumps_left)]

from functools import lru_cache

class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 1:
            return 10
        
        '''
        build the neighbors dictionary
        
        neighbors to a key are the keys reachable to itself from a key
        '''
        neighbors = {0 : (4,6), 1: (6,8), 2: (7,9), 3: (4,8), 4: (3,9,0),
                     5 : (), 6: (1,7,0), 7: (2,6), 8: (1,3), 9: (2,4)}
        
        @lru_cache(maxsize=None)
        def num_ways(key, n):
            if n == 0:
                return 0
            if n == 1:
                return len(neighbors[key])
            
            w = 0
            for neighbor in neighbors[key]:
                w += num_ways(neighbor, n-1)
            return w
        
        answer = 0
        for i in range(10):
            answer += num_ways(i, n-1)
            #print(num_ways.cache_info())
        
        answer %= (pow(10, 9) + 7)
        return answer
            


class Solution:
    def knightDialer(self, n: int) -> int:
        if n==1:
            return 10
        ret=0
        dp=[[0]*10 for i in range(n)]
        for i in range(10):
            dp[0][i]=1
        graph={0:[4,6],1:[6,8],2:[7,9],3:[4,8],4:[0,3,9],5:[],6:[0,1,7],7:[2,6],8:[1,3],9:[2,4]}
        
        for i in range(1,n):
            for j in range(10):
                for neighbor in graph[j]:
                    dp[i][j]+=dp[i-1][neighbor]
        ret=sum(dp[n-1][i] for i in range(10))
        return ret%(10**9+7)
#1 dp需要二维的来表示才行，一维的话，值很容易被覆盖，比如dp[1]在第二步的时候更新了，但是后面又用到dp[1]的话，就会用这个更新的值，而不是第一步的dp值
#1 这里我开始写成10^9+7了，^在python里是异或呀，幂要写成**
#https://www.jianshu.com/p/5a588aab3ae5


class Solution:
    def knightDialer(self, n: int) -> int:
        knight_graph = {
            1:(8,6),
            2:(7,9),
            3:(8,4),
            4:(3,9,0),
            5:(),
            6:(7,1,0),
            7:(2,6),
            8:(1,3),
            9:(4,2),
            0:(4,6)
        }
        memo = {}
        MOD = pow(10,9)+7
        def btHelper(coordinate, n):
            if n == 0:
                return 1
            possibility = 0
            for avail_node in knight_graph[coordinate]:
                if (avail_node,n-1) in memo:
                    possibility += memo[(avail_node, n-1)]
                else:
                    possibility += btHelper(avail_node,n-1)
            memo[(coordinate, n)] = possibility % MOD
            return possibility
        ans = 0  
        for i in range(10):
            ans += btHelper(i,n-1)
        #print(memo)
        return ans%MOD


class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 1:
            return 10
        x0,x1,x2,x3,x4,x5,x6,x7,x8,x9 = 1,1,1,1,1,0,1,1,1,1
        for i in range(1, n):
            x0,x1,x2,x3,x4,x6,x7,x8,x9 = x4+x6,x6+x8,x7+x9,x4+x8,x0+x3+x9,x0+x1+x7,x2+x6,x1+x3,x2+x4
        return (x1+x2+x3+x4+x5+x6+x7+x8+x9+x0)%(10**9+7)

class Solution:
    def knightDialer(self, n: int) -> int:
        
        cell2jump = dict()
        cell2jump[1] = [6, 8]
        cell2jump[2] = [7, 9]
        cell2jump[3] = [4, 8]
        cell2jump[4] = [3, 9, 0]
        cell2jump[5] = []
        cell2jump[6] = [1, 7, 0]
        cell2jump[7] = [2, 6]
        cell2jump[8] = [1, 3]
        cell2jump[9] = [2, 4]
        cell2jump[0] = [4, 6]
        
#         # dp[n, i] = helper(n, i)
#         dp = defaultdict()
        
#         def helper(num_jumps, cell):
#             # return number of jumps if place at cell and have num_jumps remaining
#             if num_jumps == 1:
#                 return 1
#             elif num_jumps == 2:
#                 return len(cell2jump[cell])
    
#             if (num_jumps, cell) in dp:
#                 return dp[num_jumps, cell]
            
#             res = 0
#             for nei in cell2jump[cell]:
#                 res += helper(num_jumps-1, nei)
            
#             dp[num_jumps, cell] = res
#             return res
        
#         total = []
#         for i in range(10):
#             total.append(helper(n, i))
        

        dp = [1]*10
        for _ in range(n-1):
            new_dp = [0]*10
            for i in range(10):
                new_dp[i] = sum(dp[nxt] for nxt in cell2jump[i])
    
            dp = new_dp

        return sum(dp) % (10**9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        moves = [[4,6], [6,8], [7,9], [4,8], [0,3,9], [], [1,7,0], [2,6], [1,3], [2,4]]
        
        dp = [1] * 10
        for _ in range(n-1):
            dp2 = [0] * 10
            for i in range(10):
                dp2[i] = sum(dp[j] for j in moves[i]) % (10**9+7)
                
            dp = dp2
            
        return sum(dp) % (10**9 + 7)
    
    # def knightDialer(self, N: int) -> int:
    #     pad, cnt = [[4, 6], [6, 8], [7, 9], [4, 8], [0, 3, 9], [], [0, 1, 7], [2, 6], [1, 3], [2, 4]], [1]*10
    #     for _ in range(N-1):
    #         next_cnt = [1]*10
    #         for i in range(10):
    #             next_cnt[i] = sum(cnt[j] for j in pad[i]) % (10**9+7)
    #         cnt = next_cnt
    #     return sum(cnt) % (10**9+7)


class Solution:
    def knightDialer(self, n: int) -> int:
        kd_key = [[4, 6], [6, 8], [7, 9], [4, 8], [3, 9, 0], [], [1, 7, 0], [2, 6], [1, 3], [2, 4]]
        # kd_key[start] = [ends]
        memo = dict()
        
        out = 0
        # all starting pos
        for i in range(10):
            out += self.dial(i, n, kd_key, memo)
        
        # print(int(1e9+7))
        return out % int(1e9 +7)
    
    def dial(self, pos, n, kd_key, memo):
        if n == 1:
            return 1
        
        out = 0
        for next_pos in kd_key[pos]:
            if (next_pos, n-1) in memo:
                out += memo[(next_pos, n-1)]
            else:
                out += self.dial(next_pos, n-1, kd_key, memo)
        
        memo[(pos, n)] = out
        return out

class Solution:
    def knightDialer(self, n: int) -> int:
        jump = {
            1: [6,8],
            2: [7,9],
            3: [4,8],
            4: [3,9,0],
            5: [],
            6: [1,7,0],
            7: [6,2],
            8: [1,3],
            9: [2,4],
            0: [4,6]
        }
        memo = {}
        
        def helper(cur, k):
            if (cur,k) in memo:
                return memo[(cur,k)]
            if k == 0:
                return 0
            elif k == 1:
                return 1
            res = 0
            for item in jump[cur]:
                res += helper(item, k-1)
            memo[(cur,k)] = res % (10**9+7)
            return res
            
        res = 0
        for i in range(10):
            res += helper(i, n)
        return res % (10**9+7)


class Solution:
    def knightDialer(self, n: int) -> int:
        if n==1: return 10
        p=math.pow(10,9)+7
        c={}
        c[1]=[6,8]
        c[2]=[7,9]
        c[3]=[4,8]
        c[4]=[3,9,0]
        c[5]=[]
        c[6]=[1,7,0]
        c[7]=[2,6]
        c[8]=[1,3]
        c[9]=[2,4]
        c[0]=[4,6]
        dp=[[None for _ in range(n+1)]for _ in range(10)]
        for i in range(10):
            dp[i][1]=1
            dp[i][2]=len(c[i])
        def find(i,x):
            if dp[i][x]is not None:
                return dp[i][x]
            dp[i][x]=0
            for j in c[i]:
                dp[i][x]+=find(j,x-1)%p
            return dp[i][x]
        res=0
        for i in range(10):
            res+=find(i,n)%p
        return int(res%p)
            


class Solution:
    def knightDialer(self, N: int) -> int:
        numpad = [[1,2,3],[4,5,6],[7,8,9],['*',0,'#']]
        dp = [1]*10
        square = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],[7,0,1],[2,6],[1,3],[2,4]]
        mod = 10**9+7
        for i in range(2,N+1):
            temp=[0]*10
            for num in range(10):
                for j in square[num]:
                    temp[num] += dp[j]%mod
            dp=temp
        return sum(dp)%mod
                                


class Solution:
    def knightDialer(self, n: int) -> int:
        neighbors = {
            1: [6,8],
            2: [7,9],
            3: [4,8],
            4: [3,9,0],
            5: [],
            6: [1,7,0],
            7: [2,6],
            8: [1,3],
            9: [2,4],
            0: [6,4]          
        }
        p = 10**9 + 7
        
        dp = defaultdict(lambda:1)
        for t in range(n-1):
            for i in range(10):
                dp[i,t&1] = sum(dp[j,(t+1)&1] for j in neighbors[i]) % p
                
        return sum(dp[i,n&1] for i in range(10)) % p

class Solution:
    def knightDialer(self, n: int) -> int:
        moves = [[] for x in range(10)]
       
        moves[0] = [4,6]
        moves[1] = [6,8]
        moves[2] = [7,9]
        moves[3] = [4,8]
        moves[4] = [3,9,0]
        moves[5] = []
        moves[6] = [0,1,7]
        moves[7] = [2,6]
        moves[8] = [1,3]
        moves[9] = [2,4]
        dp = {}

        def dialer(start,n):
            if (start,n) in dp:
                return dp[(start,n)]
            if n==1:
                dp[(start,n)] = 1
                return 1
            xmoves = 0
            for move in moves[start]:
                xmoves += dialer(move,n-1)
            xmoves %= (10**9+7)
            dp[(start,n)] = xmoves 
            return xmoves
        xmoves = 0
        for i in range(10):
            xmoves += dialer(i,n)
        return xmoves % (10**9+7)
                
            


class Solution:
    def knightDialer(self, n: int) -> int:
        @lru_cache(None)
        def dp(i, k):
            if k == 0:
                return 1
            result = 0
            for j in jump[i]:
                result = (result + dp(j, k - 1)) % MOD
            return result
        MOD = 10 ** 9 + 7
        jump = [[4, 6], [6, 8], [7, 9], [4, 8], [3, 9, 0], [], [0, 1, 7], [2, 6], [1, 3], [2, 4], list(range(10))]
        return dp(10, n)


class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 1:
            return 10
        list_old = [1] * 10
        for t in range(2, n+1):
            list_new = [0] * 10
            for i in range(0, 10):
                temp = Solution().map(i)
                for j in range(len(temp)):
                    list_new[i] = list_new[i] + list_old[temp[j]]
            list_old = list_new[0:10]
        return sum(list_old) % (10**9 + 7)

    def map(self, d: int) -> List[int]:
        if d == 0:
            return [4, 6]
        elif d == 1:
            return [6, 8]
        elif d == 2:
            return [7, 9]
        elif d == 3:
            return [4, 8]
        elif d == 4:
            return [0, 3, 9]
        elif d == 5:
            return []
        elif d == 6:
            return [0, 1, 7]
        elif d == 7:
            return [2, 6]
        elif d == 8:
            return [1, 3]
        else:
            return [2, 4]

class Solution:
    def knightDialer(self, n: int) -> int:
        G = {5:set(), 1:set([6,8]), 3:set([4,8]), 7:set([2,6]),
            9:set([2,4]), 4:set([3,9,0]),6:set([1,7,0]), 2:set([7,9]), 8:set([1,3]),0:set([4,6])}
        
        mem = dict()
        
        def dfs(val,rem):
            if (val, rem) in mem:
                return mem[(val,rem)]
            if rem == 1:
                return 1
            ans = 0
            for n in G[val]:
                ans += dfs(n,rem-1)
            mem[(val,rem)] = ans
            return ans%(10**9+7)
        
        ans = 0
        for i in range(10):
            ans += dfs(i,n)
        return ans%(10**9+7)

from collections import defaultdict
move_map = {
    0: {4,6},
    1: {6,8},
    2: {7,9},
    3: {4,8},
    4: {3, 9, 0},
    5: {},
    6: {1, 0, 7},
    7: {2, 6},
    8: {1, 3},
    9: {2, 4}
}

class Solution:    
    def knightDialer(self, n: int) -> int:
        table = defaultdict(int)
        for key in move_map:
            table[key, 1] = 1
            
        for N in range(2,n+1):
            for key in move_map:
                for new_key in move_map[key]:
                    table[key, N] += table[new_key, N-1]
                
        res = 0
        for key in move_map:
            res += table[key, n]
        return res % (10**9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        map = [[4, 6], [6, 8], [7, 9], [4, 8], [0, 3, 9], [], [0, 1, 7], [2, 6], [1, 3], [2, 4]]
        memo = [[-1] * n for i in range(len(map))]
        
        def recur(num, hops, memo):
            if hops < 0:
                return 0
            elif hops == 0:
                return 1
            
            if memo[num][hops] == -1:
                s = 0
                for move in map[num]:
                    s += recur(move, hops - 1, memo)

                memo[num][hops] = s
            return memo[num][hops]
        
        s = 0
        for key in range(len(map)):
            s += recur(key, n - 1, memo)
        
        return s % (10 ** 9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        knight_graph = {
            1:(8,6),
            2:(7,9),
            3:(8,4),
            4:(3,9,0),
            5:(),
            6:(7,1,0),
            7:(2,6),
            8:(1,3),
            9:(4,2),
            0:(4,6)
        }
        memo = {}
        MOD = pow(10,9)+7
        def btHelper(coordinate, n):
            if (coordinate, n) in memo:
                return memo[(coordinate, n)]
            if n == 0:
                return 1
            possibility = 0
            for avail_node in knight_graph[coordinate]:
                possibility += btHelper(avail_node,n-1)
            memo[(coordinate, n)] = possibility % MOD
            return possibility
        ans = 0  
        for i in range(10):
            ans += btHelper(i,n-1)
        #print(memo)
        return ans%MOD


class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 1:return 10
        R = int (math.pow(10,9) + 7)
        memo = {}
        
        options = {
            1:[6,8],
            2:[7,9],
            3:[8,4],
            4:[3,9,0],
            6:[1,7,0],
            7:[2,6],
            8:[1,3],
            9:[4,2],
            0:[4,6]
        }
        
        def dfs(step, dig):
            if (step, dig) in memo :
                return memo[(step, dig)]
            
            if step==1:
                return 1
        
            res = 0
            for d in options[dig]:
                res = (res + dfs(step-1, d)) %R
            memo[(step,dig)] = res
            return res
        
        res = 0
        for d in range(0,10,1):
            if d == 5 : continue
            res =(res + dfs(n, d))%R

        return res
    
            
        


class Solution:
    def knightDialer(self, N: int) -> int:
        dp = {}
        MOD = 10**9+7
        def moveOnce(num0, N0):
            if (num0, N0) in dp:
                return dp[(num0, N0)]
            if N0 == 0:
                return 1
            if N0 < 0 :
                return 0
            subAns = 0
            if num0 == 1:
                subAns = moveOnce(6, N0-1) + moveOnce(8, N0-1)
            elif num0 == 2:
                subAns = moveOnce(7, N0-1) + moveOnce(9, N0-1)
            elif num0 == 3:
                subAns = moveOnce(4, N0-1) + moveOnce(8, N0-1)
            elif num0 == 4:
                subAns = moveOnce(3, N0-1) + moveOnce(9, N0-1) + moveOnce(0, N0-1)
            elif num0 == 5:
                subAns = 0#moveOnce(5, N0-2) + moveOnce(7, N0-2) + moveOnce(9, N0-2)
            elif num0 == 6:
                subAns = moveOnce(1, N0-1) + moveOnce(7, N0-1) + moveOnce(0, N0-1)
            elif num0 == 7:
                subAns = moveOnce(2, N0-1) + moveOnce(6, N0-1) #+ moveOnce(5, N0-2) + moveOnce(7, N0-2)
            elif num0 == 8:
                subAns = moveOnce(1, N0-1) + moveOnce(3, N0-1)
            elif num0 == 9:
                subAns = moveOnce(2, N0-1) + moveOnce(4, N0-1) #+ moveOnce(5, N0-2) + moveOnce(9, N0-2)
            elif num0 == 0:
                subAns = moveOnce(4, N0-1) + moveOnce(6, N0-1)
            dp[(num0, N0)] = subAns%MOD
            return subAns
        return sum([moveOnce(i, N-1) for i in range(10)])%MOD

class Solution:
    
    def knightDialer(self, N: int) -> int:
            
        
        def getNeighbors(N):
            neighs=[[4,6],[6,8],[7,9],[4,8],[0,3,9],[],[0,1,7],[2,6],[1,3],[2,4]]
            return neighs[N]
        
        mod= 10**9 +7
        curr= [1]*10
        for i in range(N-1):
            nextlist= [0]*10
            for j in range(10):
                
                for neigh in getNeighbors(j):
                    nextlist[neigh]= (nextlist[neigh]+curr[j])%mod
                    
            curr=nextlist
            
        return sum(curr)%mod

class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10 ** 9 + 7
        jumps = {
            1: (6, 8),
            2: (7, 9),
            3: (4, 8),
            4: (3, 9, 0),
            5: (),
            6: (1, 7, 0),
            7: (2, 6),
            8: (1, 3),
            9: (2, 4),
            0: (4, 6),
        }

        dp = [1] * 10

        for i in range(2, n + 1):
            t = list(dp)
            for i in range(10):
                dp[i] = sum(t[v] for v in jumps[i]) % MOD

        return sum(dp) % MOD



class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 1:
            return 10
        last_dp = [1]*10
        this_dp = [0]*10
        next_steps = {
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [3, 9, 0],
            5: [],
            6: [1, 7, 0],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4],
            0: [4, 6]
        }
        for _ in range(2, n+1):
            for i in range(10):
                if i != 5:
                    this_dp[i] = sum(last_dp[next_step] for next_step in next_steps[i]) % int(10**9+7)
            last_dp = this_dp
            this_dp = [0]*10
        return sum(last_dp) % int(10**9+7)


class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 1:
            return 10
        graph = {1: (6,8),
                 2: (9,7),
                 3: (4,8),
                 4: (9,3,0),
                 5: (),
                 6: (7,1,0),
                 7: (2,6),
                 8: (1,3),
                 9: (4,2),
                 0: (4,6)}
        count = 0
        MOD = 10**9 + 7
        memo = collections.defaultdict(list)
        def dfs(cur,graph,n,memo):
            if n == 0:
                return 1
            if (n,cur) in memo:
                return memo[(n,cur)]
            count = 0
            for nei in graph[cur]:
                count += dfs(nei,graph,n-1,memo) % MOD
            memo[(n,cur)] = count
            return count
        for nei in range(10):
            memo[nei] = []
            count += dfs(nei,graph,n-1,memo) % MOD
        return count % MOD

class Solution:
    def knightDialer(self, N: int) -> int:
        memo = {} #(number,steps): totalDistinctValues
        
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]

        
        
        for i in range(0, 10):
            memo[(i,0)] = 0
            memo[(i,1)] = 1
        
        for n in range(2, N+1):
            for i in range(0, 10):
                memo[(i,n)] = 0
                
                for nextDig in moves[i]:
                    memo[(i,n)] += memo[(nextDig, n-1)]
        
        total = 0
        
        for i in range(0, 10):
            total += memo[(i,N)]
        
        return total % (10**9+7)

class Solution:
    def knightDialer(self, n: int) -> int:
        s = 0
        for k in range(10):
            d = [0] * 10
            d[k] = 1
            for i in range(n - 1):
                d2 = [
                    d[4] + d[6],
                    d[6] + d[8],
                    d[7] + d[9],
                    d[4] + d[8],
                    d[3] + d[9] + d[0],
                    0,
                    d[1] + d[7] + d[0],
                    d[2] + d[6],
                    d[1] + d[3],
                    d[2] + d[4],
                ]
                d = d2
            s += sum(d)
        return s % (10 ** 9 + 7)



class Solution:
    def knightDialer(self, n: int) -> int:
        memo, dp = [[4,6],[8,6],[7,9],[4,8],[3,9,0],[],[0,1,7],[2,6],[1,3],[2,4]], [1] * 10
        for i in range(n - 1):
            dp = [sum([dp[j] for j in memo[i]]) for i in range(10)]
        return sum(dp) % (10 ** 9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        nei = {
            1: [6, 8],
            2: [7, 9],
            3: [8, 4],
            4: [3, 9, 0],
            5: [],
            6: [1, 7, 0],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4],
            0: [4, 6]
        }
        def helper(n, curr, seen, nei):
            if n == 1:
                return 1
            if curr not in nei:
                return 0
            key = (n, curr)
            if key in seen:
                return seen[key]
            answer = 0
            for ne in nei[curr]:
                answer = (answer + helper(n - 1, ne, seen, nei)) % (10 ** 9 + 7)
            seen[key] = answer
            return answer
        total = 0
        seen = {}
        for i in range(10):
            total = (total + helper(n, i, seen, nei)) % (10 ** 9 + 7)
        return total


class Solution:
    def knightDialer(self, N: int) -> int:
        mapping = {
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [3, 9, 0],
            6: [1, 7, 0],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4],
            0: [4, 6]
        }
        
        if N == 1: return 10
        dp = collections.defaultdict(int)
        for idx in range(10):
            if idx == 5: continue
            dp[idx] = 1
        while N > 1:
            next_dp = collections.defaultdict(int)
            for idx in range(10):
                if idx == 5: continue
                for k in mapping[idx]:
                    next_dp[k] += dp[idx]
            N -= 1
            dp = next_dp
        return sum(dp.values()) % (10**9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        neighbors = {0:[4,6],1:[6,8],2:[7,9],3:[4,8],4:[0,3,9],5:[],6:[0,1,7],7:[2,6],8:[1,3],9:[2,4]}
        validNumbers = {(1,i):1 for i in range(10)}##because it will always be 1 thing possible regardless of start digit. If we had used base case of 0, we would've gotten that we would double count. So sometimes it is better to do the simplest nontrivial basecase rather than try to work with 0.
        BIG_MOD = 10**9+7
        def computePhoneNumbers(length,startDigit):##we can assume length is always >= 1
            if (length,startDigit) in validNumbers:
                return validNumbers[(length,startDigit)]
            else:
                totalValid = 0
                for neighbor in neighbors[startDigit]:
                    totalValid += computePhoneNumbers(length-1,neighbor)
                    totalValid %= (BIG_MOD)
                validNumbers[(length,startDigit)] = totalValid
                return totalValid
        allValid = 0
        for i in range(10):
            allValid += computePhoneNumbers(n,i)
            allValid %= (BIG_MOD)
        return allValid


from collections import defaultdict


class Solution:
    def knightDialer(self, n: int) -> int:
        self.buildPad()
        self.buildMoves()
        
        self.memo = [[-1 for _ in range(n)] for _ in range(10)]
        
        numbers = sum(self.visit(start, n-1) for start in range(10))
                      
        return numbers % (10**9 + 7)
        
    def visit(self, start: int, n: int) -> int:
        if n == 0:
            return 1
        elif self.memo[start][n] != -1:
            return self.memo[start][n]
        
        numbers = 0
        for new_start in self.moves[start]:
            numbers += self.visit(new_start, n-1)
        
        self.memo[start][n] = numbers
        return numbers
    
    def buildPad(self) -> None:
        self.pad = [[str(i + j) for j in range(3)] for i in range(1, 10, 3)]
        self.pad.append(['*', '0', '#'])
    
    def buildMoves(self) -> None:
        self.moves = (
            (4, 6),
            (6, 8),
            (7, 9),
            (4, 8),
            (0, 3, 9),
            (),
            (0, 1, 7),
            (2, 6),
            (1, 3),
            (2, 4)
        )


class Solution:
    def knightDialer(self, N: int) -> int:
        if N == 1: return 10
        mapper = {1:[8,6],
                 2:[7,9],
                 3:[8,4],
                 4:[0,9,3],
                 6:[0,1,7],
                 7:[2,6],
                 8:[1,3],
                 9:[2,4],
                 0:[4,6]}
        
        dp =[ [0]*10 for _ in range(N)]
        MM = 10**9+7
        for i in range(10):
            if i==5: continue
            dp[0][i] = 1
            
        def searching(s, i):
            
            if dp[s][i]>0:
                return dp[s][i]
            
            for k in mapper[i]:
                dp[s][i] += searching(s-1,k)
                dp[s][i] = dp[s][i] % MM
            return dp[s][i]
        for i in range(10):
            if i==5: continue
            searching(N-1,i)
        
        return sum(dp[N-1])% MM

class Solution:
    def knightDialer(self, n: int) -> int:
        possibleMoves = {0:[4,6], 1:[6,8],2:[9,7],3:[4,8],4:[0,3,9],5:[],6:[0,1,7],7:[2,6],8:[1,3], 9:[2,4]}
        upper = 10**9 + 7
        cache = {}
        def dfs(steps,loc):
            if (steps,loc) in cache: return cache[(steps,loc)]
            if steps == 0: 
                return 1
            ans = 0
            for stop in possibleMoves[loc]:
                ans = (ans + dfs(steps-1,stop))%upper
            cache[(steps,loc)] = ans
            return ans
        return sum(dfs(n-1,loc) for loc in possibleMoves)%upper

class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10 ** 9 + 7
        if n == 1:
            return 10
        moves = {
            0: [4, 6],
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [0, 3, 9],
            6: [0, 1, 7],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4]
        }
        
        memo = dict()
        
        def count_moves(position, digits):
            if digits == 1:
                return 1
            if (position, digits) in memo:
                return memo[position, digits]
            curr = 0
            for m in moves[position]:
                curr += count_moves(m, digits - 1)
            memo[position, digits] = curr % MOD
            return memo[position, digits]
        
        res = 0
        
        for pos in moves.keys():
            res += count_moves(pos, n)
            res %= MOD
            
        return res

class Solution:
    def knightDialer(self, N: int) -> int:
        MOD = 10**9 + 7
        reach = {
            0:[4,6],
            1:[6,8],
            2:[7,9],
            3:[4,8],
            4:[3,9,0],
            5:[],
            6:[1,7,0],
            7:[2,6],
            8:[1,3],
            9:[2,4],
        }
        
        memo = {}
        
        def helper(num, steps):
            if (num, steps) in memo:
                return memo.get((num, steps))
            if steps == 0:
                memo[((num, steps))] = 1
                return memo.get((num, steps))
            res = 0
            for next_no in reach[num]:
                res += helper(next_no, steps-1)
                
            res = res % MOD 
            memo[((num, steps))] = res
            return res
        
        result = 0
        for pos in range(0,10):
            result += helper(pos, N-1)
        
        return result % MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        paths = {1: [6, 8], 2: [7, 9], 3: [4, 8], 4: [3, 9, 0], 5: [], 6: [1, 7, 0], 7: [2,6], 8: [1,3], 9: [2, 4], 0: [4,6]}
        counts = 0
        lookup = {}
        for i in range(10):
            counts += self.traverse(i,paths, lookup,n,0)
        return counts % ( 10**9 + 7 )
        
    def traverse(self, starting, paths, lookup, n, level):
        if level == n-1:
            return 1
        counts = 0 
        for path in paths[starting]:
            if (path, level +1) not in lookup:
                lookup[(path, level +1)] = (self.traverse(path, paths, lookup, n, level +1))
            counts += lookup[(path, level +1)]
        
        return counts % ( 10**9 + 7 )

class Solution:
    def knightDialer(self, n: int) -> int:
        
        adj_graph = {
            
            1: [8,6],
            2: [7,9],
            3: [4,8],
            4: [3,9,0],
            5: [],
            6: [1,7,0],
            7: [2,6],
            8: [1,3],
            9: [4,2],
            0: [4,6]
                
        }
        
        def moveHelper(num,n,memo):
            
            if n == 1:
                
                return 1
            
            sumCounts = 0
            
            for number in adj_graph[num]:
                
                if (number,n-1) in memo:

                    sumCounts += memo[(number,n-1)]
                    
                else:
                
                    res = moveHelper(number,n-1,memo)
                    sumCounts += res
                    memo[(number,n-1)] = res
                
            return sumCounts
        
        
        sumCount = 0
        memo = {}
        
        for k in list(adj_graph.keys()):
            
            sumCount += moveHelper(k,n,memo)
            
            
        return sumCount%(pow(10,9)+7)


import numpy as np


class Solution:
    def knightDialer(self, n: int) -> int:
        if n==1: return 10
        def fast_power(a,m):

            res=np.identity(10,int)
            for bit_idx,bit in enumerate(reversed(bin(m)[2:])):
                if bit_idx==0:
                    cur=a
                else:
                    cur=np.mod(np.dot(cur,cur),10**9+7)
                if bit == '1':
                    res=np.mod(np.dot(res,cur),10**9+7)
            return res

        gh = {}
        gh[0] = [4, 6]
        gh[1] = [6, 8]
        gh[2] = [7, 9]
        gh[3] = [4, 8]
        gh[4] = [0,3, 9]
        gh[5] = []
        gh[6] = [0, 1, 7]
        gh[7] = [2, 6]
        gh[8] = [1, 3]
        gh[9] = [2, 4]
        t = []
        for u in gh:
            
            if u != 5:
                row = 0
                for v in gh[u]:
                    row = row^(1 << v)
                row = list(bin(row)[2:])
                row.reverse()
                
                row = list([int(x) for x in row])
                row.extend([0] * (10 - len(row)))
                t.append(row)
            else:
                t.append([0] * 10)
        t = np.array(t,dtype=int)
        
        ans = sum(np.mod(np.dot(fast_power(t, n - 1), np.ones(10,dtype=int)),10**9+7)) % (10**9+7)
        return ans







class Solution:
    def knightDialer(self, n: int) -> int:
        # mod = int(1e9)+7
        # d = {1: [6, 8], 2: [7, 9], 3: [4, 8], 4: [0, 3, 9], 5: [], 6: [0, 1, 7], 7:[2,6], 8: [1,3], 9:[2, 4], 0: [4,6]}
        # cache = collections.defaultdict(int)
        # #@lru_cache(maxsize=None)
        # def dfs(i, n):
        #     #nonlocal d, cache
        #     if not n: return 1
        #     if (i, n) not in cache:
        #         s = sum(dfs(val, n-1) for val in d[i])
        #         cache[i, n] = s
        #         if i in [3,6,9]: cache[i-2, n] = s
        #         elif i in [1,4,7]: cache[i+2, n] = s
        #     return cache[i, n]
        # 
        # return sum(dfs(i, n-1) for i in range(10)) % mod

        self.moves = [(4,6),(6,8),(7,9),(4,8),(3,9,0),(),(1,7,0),(2,6),(1,3),(2,4)]
        return sum(self.knightDialer_(n, i) for i in range(10)) % (10**9 + 7)

    def knightDialer_(self, N, i, dp={}):
        if N == 1: return 1
        if (N,i) not in dp:
            dp[(N,i)] = sum(self.knightDialer_(N-1, j) for j in self.moves[i])
        return dp[(N,i)]
    


class Solution:
    def knightDialer(self, n: int) -> int:
#         MOD = 10**9 + 7
#         moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
#                      [1,7,0],[2,6],[1,3],[2,4]]

#         dp = [1] * 10
#         for hops in range(n-1):
#             dp2 = [0] * 10
#             for node, count in enumerate(dp):
#                 for nei in moves[node]:
#                     dp2[nei] += count
#                     dp2[nei] %= MOD
#             dp = dp2
#         return sum(dp) % MOD
        modulo = pow(10,9)  + 7
        get_position= [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]   
        cache = {}
        def solve(pos, step):
            key = (pos, step)
            if key not in cache:
                if step>=n:
                    return 1
                res = 0
                for i in get_position[pos]:
                    res += solve(i, step + 1)
                    res = res % modulo
                cache[key] = res
            return cache[key]
        res = 0
        
        for i in range(10):
            res += solve(i, 1)
        return res % modulo

class Solution:
    def knightDialer(self, n: int) -> int:
        mod = 10**9 + 7
        reachFrom = {1: [6, 8], 2: [7, 9], 3: [4, 8], 4: [0, 3, 9], 5: [],
                     6: [0, 1, 7], 7: [2, 6], 8: [1, 3], 9: [2, 4], 0: [4, 6]}
        dp = [[1] * 10 for _ in range(2)]
        for i in range(1, n):
            for j in range(10):
                dp[i % 2][j] = 0
                for src in reachFrom[j]:
                    dp[i % 2][j] += dp[(i - 1) % 2][src]
        return sum(dp[(n - 1) % 2]) % mod

class Solution:
    def knightDialer(self, n: int) -> int:
        valid = {
            1: [8, 6],
            2: [7, 9],
            3: [4, 8],
            4: [3, 9, 0],
            5: [],
            6: [1, 7, 0],
            7: [2, 6],
            8: [1, 3],
            9: [4, 2],
            0: [4, 6]
        }
        
        MOD = 10 ** 9 + 7
        dp = {}
        nums = 0
        
        def dfs(pos, steps):
            if steps == 0:
                return 1
            if (pos, steps,) in dp:
                return dp[(pos, steps,)]
            c = 0
            for next in valid[pos]:
                c += dfs(next, steps - 1)
                c %= MOD
            dp[(pos, steps,)] = c
            return c
        
        ans = 0
        for i in range(10):
            x = dfs(i, n - 1)
            ans += x
            ans %= MOD
        return ans % MOD


class Solution:
    def knightDialer(self, n: int) -> int:
        self.knight_movable_map = {
            0:[4,6],
            1:[6, 8],
            2:[7,9],
            3:[4,8],
            4:[0,3,9],
            5: [],
            6:[0,1,7],
            7:[2,6],
            8:[1,3],
            9:[2,4]
        }
        self.dp = [[None for _ in range(10)] for _ in range(n)]
        
        def traverse(dial, remaining):
            if remaining == 0:
                return 1
            if self.dp[remaining][dial] is not None:
                
                return self.dp[remaining][dial]
            
            cnt = 0
            for next_dial in self.knight_movable_map[dial]:
                cnt += traverse(next_dial, remaining-1)
            
            self.dp[remaining][dial] = cnt
            return cnt
            
            
        cnt = 0
        for i in range(10):
            cnt += traverse(i, n -1)
        
        modulo_num = 10**9 + 7
        
        return cnt % modulo_num


# DFS solution
# O(n) time and space
class Solution:
    def knightDialer(self, N: int) -> int:
        steps = {
           0:[4, 6],
           1:[6, 8], 
           2:[7, 9], 
           3:[4, 8], 
           4:[0, 3, 9], 
           5:[], 
           6:[0, 1, 7], 
           7:[2, 6], 
           8:[1, 3], 
           9:[2, 4]
        }
        
        
        def dfs(start, remain, seen):
            if remain == 0:
                return 1
            if (start, remain) in seen:
                return seen[(start, remain)]
            
            ans = 0
            for s in steps[start]:
                ans += dfs(s, remain-1, seen)
            seen[(start, remain)] = ans
            return ans
                
        ans = 0
        seen = {}
        
        for i in range(10):
            ans += dfs(i, N-1, seen)
        return ans %(10**9+7)

class Solution:
    def knightDialer(self, n: int) -> int:
        neighbors = {
            1: (6, 8),
            2: (7, 9),
            3: (4, 8),
            4: (3, 9, 0),
            5: [],  # 5 has no neighbors
            6: (1, 7, 0),
            7: (2, 6),
            8: (1, 3),
            9: (2, 4),
            0: (4, 6),
        }
        memo = {}
        def dp_memo(S, N):
            if (S, N) in memo:
                return memo[(S, N)]
            elif N == 0:
                return 1
            else:
                moves = 0
                for neigh in neighbors[S]:
                    moves += dp_memo(neigh, N - 1)
                memo[(S, N)] = moves
                return moves
        result = 0
        for i in range(0, 10):
            result += dp_memo(i, n - 1)
        return result % ((10 ** 9) + 7)
            


class Solution:
    def knightDialer(self, n: int) -> int:
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]
        mem = {}
        MOD = 10**9 + 7
        def get(start, k):
            if k == 1:
                return 1
            if (start, k) in mem:
                return mem[start, k]
            total = 0
            for nxt in moves[start]:
                total += get(nxt, k-1)
                total = total % MOD
            
            mem[start,k] = total
            return total
        
        ret = 0
        for x in range(10):
            ret += get(x, n)
            ret = ret%MOD
        return ret

class Solution:
    def knightDialer(self, n: int) -> int:
        mapping = {
            0:[4,6],
            1:[6,8],
            2:[7,9],
            3:[4,8],
            4:[0,3,9],
            5:[],
            6:[0,1,7],
            7:[2,6],
            8:[1,3],
            9:[2,4]
        }
        memo = {}
        def helper(num, total):
            if (num, total) in memo:
                return memo[(num, total)]
            if total == 0:
                return 1
            count = 0
            for next_num in mapping[num]:
                count += helper(next_num, total-1)
            memo[(num, total)] = count
            return count
        count = 0
        for i in range(10):
            count += helper(i,n-1)
        return count % (10**9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        '''
        mod = 10**9 + 7
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],[1,7,0],[2,6],[1,3],[2,4]]
        dp = [1]*10
        for _ in range(n-1):
            dp2 = [0]*10
            for node, count in enumerate(dp):
                for nei in moves[node]:
                    dp2[nei] = (dp2[nei] + count) % mod
            dp = dp2
        return sum(dp)%mod
        '''

        mod = 10**9+7
        x0 = x1 = x2 = x3 = x4 = x5 = x6 = x7 = x8 = x9 = 1
        for k in range(1, n):
            x0, x1, x2, x3, x4, x5, x6, x7, x8, x9 = x4+x6, x6+x8, x7+x9, x4+x8, x3+x9+x0, 0, x1+x7+x0, x2+x6, x1+x3, x2+x4
        return (x0+x1+x2+x3+x4+x5+x6+x7+x8+x9)%mod

class Solution:
    def __init__(self):
        self.moves = [
            [4,6],
            [6,8],
            [7,9],
            [4,8],
            [3,9,0],
            [],
            [7,1,0],
            [6,2],
            [1,3],
            [4,2]
        ]
        
        self.memoized_moves = {}
    
    def knightDialer(self, n: int) -> int:
        moves = 0
        for i in range(10):
            moves += self.getNumberFromNMoves(n-1, i)
        
        return moves%(pow(10,9) + 7)
        
    
    def getNumberFromNMoves(self, remaining_moves, current_number):
        if remaining_moves == 0:
            return 1
        
        moves = 0
        for move in self.moves[current_number]:
            if (move, remaining_moves) not in self.memoized_moves:
                self.memoized_moves[(move, remaining_moves)] = self.getNumberFromNMoves(remaining_moves-1, move)
            moves += self.memoized_moves[(move, remaining_moves)]
            
        return moves
        
    
    def getMoves(self, number):
        return self.moves[number]
        
        


class Solution:
    def knightDialer(self, n: int) -> int:
        # mp = {0: [4,6], 1: [6, 8], 2: [9,7], 3: [8,4], 4:[9, 0, 3], 5:[], 6: [1, 7, 0], 7: [6, 2], 8:[3,1], 9: [2,4]}
        c = 0
        mp = [[4,6], [6,8], [9,7], [8,4], [0,9,3], [],[1,7,0],[6,2],[3,1], [2,4]]
        memo = {}
        for i in range(0, 10):
            c += self.gen(i, n, mp, memo)
        mpow = (10**9) + 7
        return c % mpow
    
    def gen(self, start, n, mp, memo):
        if n == 1:
            return 1
        key = (start, n)
        if key in memo:
            return memo[key]
        c = 0
        for opt in mp[start]:
            c += self.gen(opt, n-1, mp, memo)
        memo[key] = c
        return c
        
            


class Solution:
    def knightDialer(self, n: int) -> int:
        mp = {0: [4,6],
              1: [6, 8],
              2: [9,7],
              3: [8,4],
              4:[9, 0, 3],
              5:[],
              6: [1, 7, 0],
              7: [6, 2],
              8:[3,1],
              9: [2,4]
             }
        c = 0
        memo = {}
        for i in range(0, 10):
            c += self.gen(i, n, mp, memo)
        mpow = (10**9) + 7
        return c % mpow
    
    def gen(self, start, n, mp, memo):
        if n == 1:
            return 1
        key = (start, n)
        if key in memo:
            return memo[key]
        c = 0
        for opt in mp[start]:
            c += self.gen(opt, n-1, mp, memo)
        memo[key] = c
        return c
        
            


class Solution:
    
    def distinctNumbers(self, start, moves, validMoves, cache):
        if moves == 1:
            return 1
        
        if (start, moves) in cache:
            return cache[(start,moves)]
        
        result = 0
        for i in validMoves[start]:
            result += self.distinctNumbers(i, moves-1, validMoves, cache)
        cache[(start, moves)] = result
        
        return result
        
    def knightDialer(self, n: int) -> int:
        
        '''
        define numpad
        define validmove (within array and not 'X')
        use dynamic programming, grid of numbers and length n
        '''
        
        validMoves = dict()
        validMoves[1] = [6,8]
        validMoves[2] = [7,9]
        validMoves[3] = [4,8]
        validMoves[4] = [3,9,0]
        validMoves[5] = []
        validMoves[6] = [1,7,0]
        validMoves[7] = [2,6]
        validMoves[8] = [1,3]
        validMoves[9] = [2,4]
        validMoves[0] = [4,6]
        
        cache = {}
        
        
        result = 0
        for i in range(10):
            result += self.distinctNumbers(i, n, validMoves, cache)
            
        return result % (10 ** 9 + 7)
        
    
        
        
        


class Solution:
    def knightDialer(self, n: int) -> int:
        path={
            0:[4,6],
            1:[6,8],
            2:[7,9],
            3:[4,8],
            4:[0,3,9],
            5:[],
            6:[0,1,7],
            7:[2,6],
            8:[1,3],
            9:[2,4]
        }
        M=10**9+7
        dp={}
        def paths(i,n):
            if (i,n) in dp:
                return dp[(i,n)]
            #number of ways to jump from i n times          
            if n==1:
                return len(path[i])
            if n==0:
                return 1
            s=0
            for v in path[i]:
                s+=paths(v,n-1)
            dp[(i,n)]=s%M
            return dp[(i,n)]
        ans=0
        for k in path:
            ans+=paths(k,n-1)
        return ans%(M)
                
            


class Solution:
    def knightDialer(self, n: int) -> int:
        self.res = 0
        mapping = {1:[6,8],2:[9,7],3:[8,4],4:[3,9,0],6:[1,7,0],7:[2,6],8:[1,3],9:[2,4],0:[4,6],5:[]}
        memo = {}
        
        def helper(n,rem):
            if (n,rem) in memo:
                return memo[(n,rem)]
            if rem == 0:
                return 1
            res = 0
            for nei in mapping[n]:
                res += helper(nei,rem-1)
            memo[(n,rem)] = res
            return res
        res = 0
        for i in range(10):
            res += helper(i,n-1)
        return res % (10**9+7)

class Solution:
    def knightDialer(self, n: int) -> int:
        neighbors = {
            0: [4,6],
            1: [6,8],
            2: [7,9],
            3: [4,8],
            4: [0,3,9],
            5: [],
            6: [0,1,7],
            7: [2,6],
            8: [1,3],
            9: [2,4]
        }
        def helper(pos, hops_left):
            if hops_left == 1: return 1
            if (pos, hops_left) in cache:
                return cache[(pos, hops_left)]
            else:
                sequences = 0
                for ne in neighbors[pos]:
                    sequences += helper(ne, hops_left-1)
                cache[(pos, hops_left)] = sequences
                # print(f\"seq {sequences} for (pos {pos}, hops_left {hops_left})\")
                return sequences
        cache = {}
        counts = [0]*10
        for start in range(10):
            counts[start] = helper(start, n)
            # print(f\"counts[{start}] = {counts[start]}\")
        return sum(counts)%(10**9+7)

class Solution:
    moves = {0: [4, 6], 1: [6, 8], 2: [7, 9],
            3: [4, 8], 4: [0,3,9], 5:[], 6:[0, 1, 7], 
             7: [2, 6], 8: [1, 3], 9: [2, 4]}
    
    def dialed_Numbers(self, number, moves_left, memoization):
        if (number, moves_left) in memoization:
            return memoization[(number, moves_left)]
        
        if moves_left == 0:
            return 1
        
        fin_sum = 0
        for next_move in self.moves[number]:
            fin_sum += self.dialed_Numbers(next_move, moves_left - 1, memoization)
            
        memoization[(number, moves_left)] = fin_sum
        return fin_sum
    
    def knightDialer(self, n: int) -> int:
        memoization = {}
        fin_sum = 0
        for i in range(0, 10):
            fin_sum += (self.dialed_Numbers(i, n-1, memoization))
        
        return fin_sum % (10**9 + 7)

class Solution:
    
    def recur_helper(self, num, n, cnt, memo, next_moves):
        
        if n == 0:
            return cnt
        
        key = (num, n)
        if key in memo:
            return memo[key]
        
        cnt = 0
        for next_num in next_moves[num]:
            cnt += self.recur_helper(next_num, n-1, 1, memo, next_moves)
        
        memo[key] = cnt
        
        return memo[key]
    
    def knightDialer(self, n: int) -> int:
        next_moves = {
            0: [4, 6],
            1: [8, 6],
            2: [7, 9],
            3: [4, 8],
            4: [9, 3, 0],
            5: [],
            6: [1, 7, 0],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4]
        }
        memo = dict()
        cnt = 0
        for num in range(10):
            cnt += self.recur_helper(num, n-1, 1, memo, next_moves)
        
        return cnt % (10 ** 9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        moves = [[4,6], [6,8], [7,9], [4,8], [0,3,9], [], [1,7,0], [2,6], [1,3], [2,4]]
        
        dp = [1] * 10
        for _ in range(n-1):
            dp2 = [0] * 10
            for i in range(10):
                dp2[i] = sum(dp[j] for j in moves[i]) % (10**9+7)
                
            dp = dp2
            
        return sum(dp) % (10**9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        results = 0
        self.cache = {}
        for pos in range(10):
            results += self.traverse(pos, n)
            results %= 1000000007
        return results
        
        
    def traverse(self, pos: int, length: int) -> int:
        if length == 1:
            return 1
        if (pos, length) in self.cache:
            return self.cache[(pos, length)]
        jumps = 0
        for neighbor in self.get_neighbors(pos):
            jumps += self.traverse(neighbor, length - 1)
            
        jumps %= 1000000007
        self.cache[(pos, length)] = jumps
        return jumps
        
    def get_neighbors(self, n: int) -> Tuple[int]:
        NEIGHBORS = (
            (4, 6),
            (6, 8),
            (7, 9),
            (4, 8),
            (0, 3, 9),
            (),
            (0, 1, 7),
            (2, 6),
            (1, 3),
            (2, 4)
        )
        return NEIGHBORS[n]

class Solution:
    def knightDialer(self, n: int) -> int:
        self.edges = {
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [9, 3, 0],
            5: [],
            6: [1, 7, 0],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4],
            0: [4, 6]
        }
        
        self.MAX = (10 ** 9) + 7
        
        # at *this* cell, with *this* many steps left, what's the count?
        self.ledger = [[None]*n for _ in range(10)]
        
        dialable = 0
        for cell in range(10):
            dialable += self.knight_dialer(n - 1, cell)

        return dialable % self.MAX
        
        

    def knight_dialer(self, steps_left: int, position: int) -> None:
        if not steps_left:
            return 1

        if self.ledger[position][steps_left]:
            return self.ledger[position][steps_left]
        
        dialable = 0
        for nbr in self.edges[position]:
            dialable += self.knight_dialer(steps_left - 1, nbr) % self.MAX
        
        self.ledger[position][steps_left] = dialable
        
        
        return dialable % (10 ** 9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        neighbors = {
            0: [4,6],
            1: [6,8],
            2: [7,9],
            3: [4,8],
            4: [0,3,9],
            5: [],
            6: [0,1,7],
            7: [2,6],
            8: [1,3],
            9: [2,4]
        }
        def helper(pos, hops_left):
            if hops_left == 1: return 1
            if (pos, hops_left) in cache:
                return cache[(pos, hops_left)]
            else:
                sequences = 0
                for ne in neighbors[pos]:
                    sequences += helper(ne, hops_left-1)
                cache[(pos, hops_left)] = sequences
                # print(f\"seq {sequences} for (pos {pos}, hops_left {hops_left})\")
                return sequences
        cache = {}
        counts = 0
        for start in range(10):
            counts += helper(start, n)
        return counts%(10**9+7)

class Solution:
    def knightDialer(self, n: int) -> int:
        graph = {1:[6, 8], 2:[7, 9], 3:[4, 8], 4:[3, 9, 0], 5:[], 6:[1, 7, 0], 7:[6, 2], 8:[1, 3], 9:[2, 4], 0:[4, 6]}
        
        @lru_cache(None)
        def dfs(node, n=n):
            if n == 1:
                return 1
            else:
                moves = 0
                for neigb in graph[node]:
                    # if neigb in (3, 6, 9):
                    #     neigb -= 2
                    moves += dfs(neigb, n-1)
                return moves
                
        ans = 0
        for node in range(10):
            ans += dfs(node)
        
        return ans % (10 **9 + 7)

#bfs solution

#graph problem



class Solution:
    def knightDialer(self, n: int) -> int:
        
        neighbours = {
            1: (6, 8),
            2: (7, 9),
            3: (4, 8),
            4: (3, 9, 0),
            5: tuple(),  # 5 has no neighbors
            6: (1, 7, 0),
            7: (2, 6),
            8: (1, 3),
            9: (2, 4),
            0: (4, 6),
        }
        
        memo={}
        def helper(position, num_hops):
            if (position, num_hops) in memo:
                return memo[(position, num_hops)]
            
            if num_hops == 0: return 1
            
            num_sequences = 0
            for neighbour in neighbours[position]:
                num_sequences += helper(neighbour, num_hops - 1)
                
            memo[(position, num_hops)] = num_sequences
            
            return num_sequences
        
        total = 0
        for pos in neighbours:
            total += helper(pos, n-1)
        
        return total%(10**9+7)


class Solution:
    NEIGHBORS = (
            (4, 6),
            (6, 8),
            (7, 9),
            (4, 8),
            (0, 3, 9),
            (),
            (0, 1, 7),
            (2, 6),
            (1, 3),
            (2, 4)
    )
    
    def knightDialer(self, n: int) -> int:
        results = 0
        self.cache = {}
        for pos in range(10):
            results += self.traverse(pos, n)
            results %= 1000000007
        return results
        
        
    def traverse(self, pos: int, length: int) -> int:
        if length == 1:
            return 1
        if (pos, length) in self.cache:
            return self.cache[(pos, length)]
        jumps = 0
        for neighbor in self.get_neighbors(pos):
            jumps += self.traverse(neighbor, length - 1)
            
        jumps %= 1000000007
        self.cache[(pos, length)] = jumps
        return jumps
        
    def get_neighbors(self, n: int) -> Tuple[int]:
        return self.NEIGHBORS[n]

class Solution:
    d = [[4,6], [6, 8], [7, 9], [4, 8], [0, 3, 9], [], [0, 1, 7], [2,6], [1,3], [2, 4]]
    #d = [(4,6),(6,8),(7,9),(4,8),(3,9,0),(),(1,7,0),(2,6),(1,3),(2,4)]
    def dfs(self, i, n, cache={}):
        if n == 1: return 1
        if (i, n) not in cache:
            cache[i, n] = sum(self.dfs(val, n-1) for val in self.d[i])
        return cache[i, n]
    
    def knightDialer(self, n: int) -> int:
        mod = int(1e9)+7
        return sum(self.dfs(i, n) for i in range(10)) % mod

# class Solution(object):
#     moves = [(4,6),(6,8),(7,9),(4,8),(3,9,0),(),(1,7,0),(2,6),(1,3),(2,4)]
#     def knightDialer(self, N):
#         return sum(self.knightDialer_(N, i) for i in range(10)) % (10**9 + 7)
#     def knightDialer_(self, N, i, dp={}):
#         if N == 1: return 1
#         if (N,i) not in dp:
#             dp[(N,i)] = sum(self.knightDialer_(N-1, j) for j in self.moves[i])
#         return dp[(N,i)]


class Solution:
    def knightDialer(self, n: int) -> int:
        dp = [[-1 for i in range(n+1)] for i in range(10)]
        d={1:[6,8],2:[7,9],3:[4,8],4:[3,9,0],5:[],6:[1,7,0],7:[2,6],8:[1,3],9:[2,4],0:[4,6]}
        out = 0
        for i in range(0,10):
            out+=self.helper(n-1,i,d,dp)
        return out%1000000007
    
    def helper(self,n,index,d,dp):
        if(n==0):
            return 1
        
        if(dp[index][n]!=-1):
            return dp[index][n]
        
        ans = 0
        for i in range(len(d[index])):
            ans+=self.helper(n-1,d[index][i],d,dp)
        dp[index][n] = ans
        return ans

class Solution:
    mod = 10**9 + 7
    
    def knightDialer(self, N: int) -> int:
        nMap = {
            0: (6, 4),
            1: (6, 8),
            2: (7, 9),
            3: (4, 8),
            4: (3, 9, 0),
            5: (),
            6: (1, 7, 0),
            7: (2, 6),
            8: (1, 3),
            9: (4, 2)
        }

        m = {} # (position, num)
        
        def count(start, n):
            
            if (start, n) in m:
                return m[(start, n)]
            
            if n == 0:
                return 1

            else:
                
                num = 0
                
                for i in nMap[start]:
                    num += count(i, n - 1) 
                    
                m[(start, n)] = num
                
                return num
        
        ret = 0
        for i in range(10):
            ret = (ret + count(i, N - 1)) % self.mod

        return int(ret)
        


class Solution:
    def knightDialer(self, n: int) -> int:
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
             [1,7,0],[2,6],[1,3],[2,4]]
        
        cache = {}
        def backtrack(pos, hops):
            if (pos, hops) in cache:
                return cache[(pos, hops)]
            if hops == 0:
                return 1
            count = 0
            for nbr in moves[pos]:
                count += backtrack(nbr, hops-1)
            cache[(pos, hops)] = count
            return count
            
        counts = 0
        for pos in range(10):
            counts += backtrack(pos, n-1)
            
        return counts%(10**9+7)
        
#         cur_hops = 1
#         prev_counts = [1]*10
#         cur_counts = [0]*10
        
#         while cur_hops < n:
#             cur_hops += 1
#             cur_counts = [0]*10

#             for pos in range(10):
#                 for nbr in moves[pos]:
#                     cur_counts[pos] += prev_counts[nbr]
#             prev_counts = cur_counts
        
#         return sum(prev_counts)%(10**9+7)


class Solution:
    legal_moves = {
            0: [4, 6],
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [0, 3, 9],
            # 5: [],
            6: [0, 1, 7],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4]
        }
    
    def knightDialer(self, n: int) -> int:
        total = 0 if n != 1 else 1
        memo = {}
        for i in range(0, 10):
            if i is not 5:
                total = total + self.num_jumps(i, n - 1, memo)
                
        return total % (pow(10, 9) + 7)
            
    def num_jumps(self, start, jumps_left, memo):
        
        # If we have no moves left we have completed a number
        if jumps_left == 0:
            return 1
        
        # Check if we have done this calculation before
        if (start, jumps_left) not in memo:
            
            # Calculate total number of numbers from this starting position
            total = 0
            for legal_move in self.legal_moves[start]:
                total = total + self.num_jumps(legal_move, jumps_left - 1, memo)
        
            # Save result
            memo[(start, jumps_left)] = total
        
        # Return calculated or retreived result
        return memo[(start, jumps_left)]

class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10 ** 9 + 7
        
        moveMap = {1:[8, 6], 2:[7, 9], 3:[4, 8], 4:[3, 9, 0], 5:[], 6:[1, 7, 0],
                   7:[2, 6], 8:[1, 3], 9:[4, 2], 0:[4, 6]}
        
        memo = {}
    
        def aux(key, rem):
            if rem == 0:
                return 1
            if (key, rem) in memo: return memo[(key, rem)]
            
            count = 0
            # Move to each valid key from this key
            moves = moveMap[key]
            for m in moves:
                count += aux(m, rem - 1)
            
            # Save the result
            memo[(key, rem)] = count
            return count
        
        count = 0
        for startKey in moveMap:
            count += aux(startKey, n - 1)
            
        return count % MOD
                
            


class Solution:
    def __init__(self):
        
        self.pos_2_pos_map = {
            1: (6, 8),
            2: (7, 9),
            3: (4, 8),
            4: (3, 0, 9),
            5: tuple(),
            6: (7, 1, 0),
            7: (2, 6),
            8: (1, 3),
            9: (4, 2),
            0: (4, 6)
        }
        
    def dfs(self, position, n, memo):
        if n == 0:
            return 1
        
        if (position, n) in memo:
            return memo[(position, n)]

        counts = 0
        for nei in self.pos_2_pos_map[position]:
            counts += self.dfs(nei, n-1, memo)
        memo[(position, n)] = counts
        
        return counts
        
    def knightDialer(self, n: int) -> int:
        memo = {}
        counts = 0
        
        for position in self.pos_2_pos_map:
            counts += self.dfs(position, n-1, memo)
        return counts % (10 ** 9 + 7)

class Solution:
    def knightDialer(self, l: int) -> int:
        table = defaultdict(lambda: defaultdict(int))
        tableEnts = {(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (5, 0), (6, 0), (7, 0), (8, 0), (9, 0)}
        def dp(n, lv) -> int:
            if lv == 0:
                return 1
            if (n, lv) in tableEnts:
                return table[n][lv]

            if n == 0:
                ret = dp(4, lv - 1) + dp(6, lv - 1)
            elif n == 1:
                ret = dp(6, lv - 1) + dp(8, lv - 1)
            elif n == 2:
                ret = dp(7, lv - 1) + dp(9, lv - 1)
            elif n == 3:
                ret = dp(4, lv - 1) + dp(8, lv - 1)
            elif n == 4:
                ret = dp(3, lv - 1) + dp(9, lv - 1) + dp(0, lv - 1)
            elif n == 6:
                ret = dp(1, lv - 1) + dp(7, lv - 1) + dp(0, lv - 1)
            elif n == 7:
                ret = dp(2, lv - 1) + dp(6, lv - 1)
            elif n == 8:
                ret = dp(1, lv - 1) + dp(3, lv - 1)
            elif n == 9:
                ret = dp(2, lv - 1) + dp(4, lv - 1)
            
            ret %= 1000000007
            table[n][lv] = ret
            tableEnts.add((n, lv))
            return ret

        if l == 1:
            return 10
        else:
            res = 0
            for i in [0, 1, 2, 3, 4, 6, 7, 8, 9]:
                res += dp(i, l - 1)
            return res % 1000000007

class Solution:
    def knightDialer(self, n: int) -> int:
        
        k = {
            0: [4, 6],
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [0, 3, 9],
            5: [],
            6: [0, 1, 7],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4],
        }
        
        mem = {}
        def count(i, j):
            if j > n: return 0
            if j == n: return 1
            if (i, j) in mem: return mem[i, j]
            
            cc = 0
            for l in k[i]:
                cc += count(l, j + 1)
            
            mem[i, j] = cc % (10 ** 9 + 7)
            return mem[i, j]
        
        
        return sum(count(i, 1) for i in range(10)) % (10 ** 9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        def matmul(A, B):
            BT = list(zip(*B))
            res = [[sum((x*y)%M for x, y in zip(row, col)) for col in BT] for row in A]
            return res
        
        def pow(A, n):
            
            l = n.bit_length()
            res = [[1 if i==j else 0 for j in range(len(A[0]))] for i in range(len(A))]
            tmp = A
            
            for i in range(l):
                
                mask = 1 << i
                
                if mask & n != 0:
                    res = matmul(res, tmp)
                    
                tmp = matmul(tmp, tmp)
                
            return res
        
        M = 10**9+7
        A = [[0,0,0,0,1,0,1,0,0,0],
             [0,0,0,0,0,0,1,0,1,0],
             [0,0,0,0,0,0,0,1,0,1],
             [0,0,0,0,1,0,0,0,1,0],
             [1,0,0,1,0,0,0,0,0,1],
             [0,0,0,0,0,0,0,0,0,0],
             [1,1,0,0,0,0,0,1,0,0],
             [0,0,1,0,0,0,1,0,0,0],
             [0,1,0,1,0,0,0,0,0,0],
             [0,0,1,0,1,0,0,0,0,0]]
        
        res = matmul([[1,1,1,1,1,1,1,1,1,1]], pow(A,n-1))
        
        return sum(res[0]) % M


class Solution:
    def knightDialer(self, n: int) -> int:
        graph = {1:[6, 8], 2:[7, 9], 3:[4, 8], 4:[3, 9, 0], 5:[], 6:[1, 7, 0], 7:[6, 2], 8:[1, 3], 9:[2, 4], 0:[4, 6]}
        
        @lru_cache(None)
        def dfs(node, n=n):
            if n == 1:
                return 1
            else:
                moves = 0
                for neigb in graph[node]:
                    if neigb in (3, 6, 9):
                        neigb -= 2
                    moves += dfs(neigb, n-1)
                return moves
                
        ans = 0
        for node in range(10):
            ans += dfs(node)
        
        return ans % (10 **9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        cnt = 0
        jump = [[4, 6], [6, 8], [7, 9], [4, 8], [
            0, 3, 9], [], [0, 1, 7], [2, 6], [1, 3], [2, 4]]
        visited = dict()
        def helper(n,i):
            if (n,i) in visited:
                return visited[(n,i)]
            if n == 1:
                visited[(n,i)] = 1
                return 1
            tot = 0
            
            for v in jump[i]:
                tot += helper(n -1,v)
            visited[(n,i)] = tot
            return tot
        for i in range(10):
            cnt += helper(n,i)
        return cnt%(10**9 + 7)
                
        


class Solution:
    def knightDialer(self, n: int) -> int:
        
        d = {1:[6,8],
            2:[7,9],
            3:[4,8],
            4:[3,9,0],
            5:[],
            6:[1,7,0],
            7:[2,6],
            8:[1,3],
            9:[2,4],
            0:[4,6]}
        
        cache = {}
        
        def dfs(l,m):
            nonlocal d
            nonlocal cache
            key = (l,m)
            
            if key in cache:
                return cache[key]
            
            if m == n:
                return 1
            
            ans = 0
            
            for v in d[l]:
                ans += dfs(v,m+1)
                
            cache[key] = ans
            return ans
        
        ret = 0
        for i in range(10):
            ret += dfs(i,1)
                
        return ret%(10**9 +7)

class Solution:
    
    def __init__(self):
        self.paths = {1: [8, 6], 2: [7, 9], 3: [4, 8], 4: [3, 9, 0], 5: [], 6: [1, 7, 0], 7: [2, 6], 8: [1, 3], 9: [2, 4], 0: [4, 6]}
    
    def knightDialer(self, n: int) -> int: # 3
        
        # ways(0, 3)
            # ways(4, 2)
                # ways(3, 1)
                    # ways(4, 0)
                        # return 0
                    # ways(8, 0) # 0
                # ways(9, 1)
                # ways(0, 1)
            # ways(6, 2)
        
        cache = {}
        
        # @lru_cache
        def ways(number, turns):
            if turns < 2:
                return turns
            
            key = (number, turns)
            if key in cache:
                return cache[key]
            
            total_ways = 0
            for new_number in self.paths[number]:
                total_ways += ways(new_number, turns-1)
            
            cache[key] = total_ways
            
            return cache[key]
                
        total_ways = 0 # 0
        for i in range(10):
            total_ways += ways(i, n) # 
        return total_ways % (10**9+7)


class Solution:
    def knightDialer(self, n: int) -> int:
        moves = {0: (4,6), 1: (8, 6), 2: (7, 9), 3: (4, 8), 4: (0, 3, 9), 6: (0, 1, 7), 7: (2, 6), 8: (1,3), 9: (2, 4)}
        @lru_cache(None)
        def dfs(last_val=None, length=0):
            if length == n:
                return 1
            count = 0
            if not length:
                for i in range(0,10): 
                    count += dfs(i, 1)
            elif last_val != 5:
                for i in moves[last_val]:
                    count += dfs(i, length+1)
            return count
        return dfs() % ((10**9)+7)
                
        


class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10**9 + 7
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]

        # dp = [1] * 10  # dp[i, N] = dp[nei, N-1] + dp[nei1, N-1] => dp[i] = 
        # for i_n in range(n-1):
        #     dp2 = [0] * 10
        #     for i in range(10):
        #         for nei in moves[i]:
        #             dp2[nei] += dp[i]
        #             dp2[nei] %= MOD
        #     dp = list(dp2)
        # return sum(dp) % MOD        
        dp = [[0] * 10 for _ in range(n)]
        for i in range(10):
            dp[0][i] = 1
            
        for i_n in range(0, n-1):
            for i in range(10):
                for nei in moves[i]:
                    dp[i_n+1][nei] += dp[i_n][i]
                    dp[i_n+1][nei] %= MOD
        res = 0
        for i in range(10):
            res += dp[n-1][i]
            res %= MOD
        return res 


class Solution:
    def knightDialer(self, n: int) -> int:
        neighbors = {
            0:[4,6],
            1:[6,8],
            2:[7,9],
            3:[4,8],
            4:[0,3,9],
            5:[],
            6:[0,1,7],
            7:[2,6],
            8:[1,3],
            9:[2,4]
        }
        MOD = 10**9 + 7
        res = 0
        cache = {}
        for i in range(10):
            res += self.helper(i,n,neighbors,cache)
        return res % MOD
    def helper(self,num,hops,neighbors,cache):
        if hops == 1:
            return 1
        if (num,hops) in cache:
            return cache[(num,hops)]
        seq = 0
        for i in neighbors[num]:
            seq += self.helper(i,hops-1,neighbors,cache)
        cache[(num,hops)] = seq
        return seq

class Solution:
    def knightDialer(self, n: int) -> int:
        modulo = 10**9 + 7

        dp = [1] * 10 
        
        while n > 1:
            new_table = [0] * 10
            for digit in range(0,10):
                for neighbor in self.neighbors(digit):
                    new_table[neighbor] += dp[digit]
            n -= 1
            dp = new_table
            
        return sum(dp) % modulo
    
#     def getWays(self, digit, n):
#         if n == 0:
#             return 1
        
#         if (digit,n) in self.cache:
#             return self.cache[(digit,n)]
        
#         temp = 0
#         for neighbor in self.neighbors(digit):
#             temp += self.getWays(neighbor, n-1)
    
#         self.cache[(digit, n)] = temp
#         return self.cache[(digit,n)]
    
    def neighbors(self, digit):
        neighbors = {
            0: (4, 6),
            1: (6, 8),
            2: (7, 9),
            3: (4, 8),
            4: (0, 3, 9),
            5: (),
            6: (0, 1, 7),
            7: (2, 6),
            8: (1, 3),
            9: (2,4)

        }
        
        return neighbors[digit]

jumps = [
(4, 6),
(6, 8),
(7, 9),
(4, 8),
(0, 3, 9),
(),
(0, 1, 7),
(2, 6),
(1, 3),
(2, 4),
]

class Solution:
    @staticmethod
    def numNumbersFrom(cache, button, ttl):
        if ttl == 0:
            return 0
        if ttl == 1:
            return 1
        if button in cache and ttl in cache[button]:
            return cache[button][ttl]
        total = 0
        for i in jumps[button]:
            total += int(Solution.numNumbersFrom(cache, i, ttl - 1) % (1e9 + 7))
        if button not in cache:
            cache[button] = {}
        cache[button][ttl] = total
        return total
        
    
    def knightDialer(self, n: int) -> int:
        total = 0
        cache = {}
        for i in range(0, len(jumps)):
            total += self.numNumbersFrom(cache, i, n)
        return int(total % (1e9 + 7))

class Solution:
    def __init__(self):
        self.moves = [
            [4,6],
            [6,8],
            [7,9],
            [4,8],
            [3,9,0],
            [],
            [7,1,0],
            [6,2],
            [1,3],
            [4,2]
        ]
        self.memoized_moves = {}
    
    def knightDialer(self, n: int) -> int:
        moves = 0 
        
        for i in range(10):
            moves += self.calculateMoves(n-1, i)
            
        return moves% (pow(10,9) + 7)
            
            
    def calculateMoves(self, moves_remaining, current_number):
        if moves_remaining == 0:
            return 1
        
        moves = 0
        for next_number in self.getMoves(current_number):
            if (moves_remaining, next_number) not in self.memoized_moves:
                self.memoized_moves[(moves_remaining, next_number)] = self.calculateMoves(moves_remaining-1, next_number)
            moves += self.memoized_moves[(moves_remaining, next_number)]
            
        return moves
        
        
    def getMoves(self, number):
        return self.moves[number]
        
        


class Solution:
    d = [[4,6], [6, 8], [7, 9], [4, 8], [0, 3, 9], [], [0, 1, 7], [2,6], [1,3], [2, 4]]
    #d = [(4,6),(6,8),(7,9),(4,8),(3,9,0),(),(1,7,0),(2,6),(1,3),(2,4)]
    def dfs(self, i, n, cache={}):
        if n == 0: return 1
        if (i, n) not in cache:
            cache[i, n] = sum(self.dfs(val, n-1) for val in self.d[i])
        return cache[i, n]
    
    def knightDialer(self, n: int) -> int:
        mod = int(1e9)+7
        return sum(self.dfs(i, n-1) for i in range(10)) % mod

# class Solution(object):
#     moves = [(4,6),(6,8),(7,9),(4,8),(3,9,0),(),(1,7,0),(2,6),(1,3),(2,4)]
#     def knightDialer(self, N):
#         return sum(self.knightDialer_(N, i) for i in range(10)) % (10**9 + 7)
#     def knightDialer_(self, N, i, dp={}):
#         if N == 1: return 1
#         if (N,i) not in dp:
#             dp[(N,i)] = sum(self.knightDialer_(N-1, j) for j in self.moves[i])
#         return dp[(N,i)]


NEIGHBORS_MAP = {
    1: (6, 8),
    2: (7, 9),
    3: (4, 8),
    4: (3, 9, 0),
    5: tuple(),  # 5 has no neighbors
    6: (1, 7, 0),
    7: (2, 6),
    8: (1, 3),
    9: (2, 4),
    0: (4, 6),
}

class Solution:
    def nextPositions(self,n):
        return NEIGHBORS_MAP[n]
    
    def build_x_y_map(self):
        r,c = 0,0
        ht = {}
        
        for i in range(1,10):
            ht[i] = (r,c)
            c+=1
            if c == 3:
                r+=1
                c = 0
        
        ht[0] = (3,1)
        return ht
    
    def knightDialer(self, n: int) -> int:
        def count_moves(curr_cell,hops,memo):
            if hops == 0:
                return 1
            key = (curr_cell,hops)
            if key not in memo:
                ways = 0
                for pos in self.nextPositions(curr_cell):
                    ways += count_moves(pos,hops-1,memo)
                memo[key] = ways
            return memo[key]
        
        total = 0
        memo = {}
        for i in range(0,10):
            total += count_moves(i,n-1,memo)
        return total % (10**9 + 7)
        


class Solution:
    def nextHops(self, row: int, col: int) -> list:
        hops = []
        if (row, col) not in self.hopDict:       
            for jump in [(-2, -1), (-1, -2), (1, -2), (2, -1), (2, 1), (1, 2),(-1, 2), (-2, 1)]:
                nr, nc = row + jump[0], col + jump[1]
                if nr < 0 or nc < 0 or nr > 2 or nc > 2:
                    if (nr == 3 and nc == 1):
                        hops.append((nr, nc))
                    continue

                hops.append((nr, nc))
                
            self.hopDict[(row, col)] = hops
            
        return self.hopDict[(row, col)]
    
    def knightDialer(self, n: int) -> int:
        if n == 0:
             return
            
        reached = [ [1] * 3 for _ in range(4)]
        reached[3][0] = 0
        reached[3][2] = 0
        self.hopDict = {}

        for move in range(2, n + 1):
            nreached = [ [0] * 3 for _ in range(4)]
            for i, row in enumerate(reached):
                for j, button in enumerate(row):
                    if button == 0:
                        continue

                    for hop in self.nextHops(i, j):
                        nreached[hop[0]][hop[1]] += button
                        nreached[hop[0]][hop[1]] %= (10**9 + 7)
            
            reached = nreached
        
        return sum(map(sum, reached)) % (10**9 + 7)

class Solution:
    def knightDialer(self, N: int) -> int:
        maxs = (10**9 + 7)
        moves = ((-1, -2), (-2, -1), (-2, 1), (-1, 2), (1, 2), (2, 1), (2, -1), (1, -2))
        memo = {}
        neighbors = { 1: (6, 8) , 2: (7, 9), 3: (4, 8), 4: (3, 9, 0),5: tuple(), 6: (1, 7, 0), 7: (2, 6), 8: (1, 3), 9: (2, 4), 0: (4, 6),}
        def dfs(i,n):
            if n == 1:
                return 1

            if (n,i) in memo:
                return memo[(n,i)]

            else:
                nums = 0
                for d in neighbors[i]:
                    nums +=  dfs(d ,n-1) 
                memo[(n,i)] = nums 
            return nums
            
        total = 0
        
        for i in range(10):
                total += dfs(i,N)
        
        return total % maxs
            
       
            
            
                


class Solution:
    def knightDialer(self, n: int) -> int:
        moves = {1: [6, 8], 2: [7, 9], 3: [4, 8], 4: [3, 9, 0], 5: [], 6: [1, 7, 0], 7: [2, 6], 8: [1, 3], 9: [2, 4], 0: [4, 6]}
        
        # dp [i][j] = distinct phone numbers reachable of length j if you are at number i
        # 0 <= i <= 9
        # 0 <= j <= n
        
        dp = [[0 for j in range(n + 1)] for i in range(10)]
        
        for j in range(n + 1):
            for i in range(10):
                if (j <= 1):
                    dp[i][j] = 1
                else:
                    dp[i][j] = sum([dp[possibleMove][j - 1] for possibleMove in moves[i]])

        return sum([dp[i][n] for i in range(10)]) % (10 ** 9 + 7)


move_map = {
    0: {4,6},
    1: {6,8},
    2: {7,9},
    3: {4,8},
    4: {3, 9, 0},
    5: {},
    6: {1, 0, 7},
    7: {2, 6},
    8: {1, 3},
    9: {2, 4}
}

class Solution:
    def dfs(self, n, key):
        if n == 1:
            return 1
        if (n, key) in self.memo:
            return self.memo[n, key]
        res = 0
        for new_key in move_map[key]:
            res += self.dfs(n-1, new_key)
        self.memo[n, key] = res
        return res
    
    def knightDialer(self, n: int) -> int:
        self.memo = {}
        res = 0
        for key in move_map:
            res += self.dfs(n, key)
            
        return res % (10**9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        s = 0
        for k in range(10):
            d = [0] * 10
            d2 = [0] * 10
            d[k] = 1
            for i in range(n - 1):
                d2[0] = d[4] + d[6]
                d2[1] = d[6] + d[8]
                d2[2] = d[7] + d[9]
                d2[3] = d[4] + d[8]
                d2[4] = d[3] + d[9] + d[0]
                d2[5] = 0
                d2[6] = d[1] + d[7] + d[0]
                d2[7] = d[2] + d[6]
                d2[8] = d[1] + d[3]
                d2[9] = d[2] + d[4]
                d, d2 = d2, d
            s += sum(d)
        return s % (10 ** 9 + 7)



class Solution:
    def knightDialer(self, N: int) -> int:
        
        jump_map = {1:[6,8],
                   2:[7,9],
                   3:[4,8],
                   4:[3,9,0],
                   5: [],
                   6: [1,7,0],
                   7:[6,2],
                   8:[1,3],
                   9:[2,4],
                   0:[4,6]}
        
        dp_map = {}
        
        def get_num(s, n):
            if (s,n) not in dp_map:
                if n == 1:
                    dp_map[(s,n)] = 1
                    return dp_map[(s,n)]
                ans = 0
                for target in jump_map[s]:
                    ans += get_num(target, n-1)
                dp_map[(s,n)] = ans
            return dp_map[(s,n)]
            
        total = 0
        for i in jump_map.keys():
            total += get_num(i, N)
            
        return total % (10**9 + 7)

class Solution:
    def _knightDialer(self, n: int, curr_n: int, moves_map: dict, cache: dict) -> int:
        if n == 0:
            return 1
        
        if (curr_n,n) in cache:
            return cache[(curr_n,n)]
        
        distinct_nums = 0
        for next_n in moves_map[curr_n]:
            distinct_nums += self._knightDialer(n-1, next_n, moves_map, cache)
        
        cache[(curr_n, n)] = distinct_nums
        return cache[(curr_n,n)]
    
    def knightDialer(self, n: int) -> int:
        # TLE, let's take care of some symmetry
        # 1 == 3 == 9 == 7, 4 == 6, 2 == 8, 0
        if n == 1:
            return 10

        mod = 10 ** 9 + 7
        nums = 0
        cache = {}
        moves_map = {
            1: [6,8],
            2: [7,9],
            3: [4,8],
            4: [0,3,9],
            5: [],
            6: [0,1,7],
            7: [2,6],
            8: [1,3],
            9: [2,4],
            0: [4,6],
        }

        nums = 0
        for m, weight in [(1,4),(2,2),(4,2), (0,1)]:
            nums += weight * self._knightDialer(n-1, m, moves_map, cache)
        
        return nums % mod

class Solution:
    def helper(self, keys, n, digit, cache):
        if not n:
            return 1
        
        if (n, digit) in cache:
            return cache[(n,digit)]
        
        count = 0
        for d in keys[digit]:
            count += self.helper(keys, n-1, d, cache)
        
        cache[(n,digit)] = count
        return cache[(n,digit)]
        
    def knightDialer(self, n: int) -> int:
        
        keys = {1:[6,8], 2:[7,9], 3:[4,8],4:[0,3,9], 5: [], 6:[7,1,0], 7:[2,6], 8:[1,3], 9:[2,4], 0:[4,6]}
        
        count = 0
        cache = {}
        for i in range(0, 10):
            count += self.helper(keys, n-1, i, cache)
        return count % (10**9+7)
        # def helper()


from functools import lru_cache
class Solution:
    def knightDialer(self, n: int) -> int:
        ## dp/ recursion
        neighbors = {
            0:[4,6],
            1:[6,8],
            2:[7,9],
            3:[4,8],
            4:[3,9,0],
            5:[], # 5 is a stuck point? also no way to get to 5
            6:[1,7,0],
            7:[2,6],
            8:[1,3],
            9:[2,4],
        }
        
        @lru_cache(None)
        def dfs(i,n):
            if(n == 1):
                return 1;
            count = 0;
            for x in neighbors[i]:
                count = (count+dfs(x,n-1))%(10**9+7)
            return count;
        ansr = 0;
        for i in range(10):
            #print(dfs(i,n))
            ansr= (ansr+dfs(i,n))%(10**9+7)
            
        return ansr
            


# 当前index位置，下一个可能到达的位置(0 ~ 9)
MOVES = [
    [4, 6], [6, 8], [7,9],
    [4, 8], [3, 9, 0], [],
    [1, 7, 0], [2, 6], [1, 3], [2, 4],
]

class Solution:
    def knightDialer(self, N: int) -> int:
        memo = {}
        res = 0
        for i in range(10):
            res += self._dfs(i, N, memo)
        return res % (10 ** 9 + 7)

    def _dfs(self, curr, steps, memo):
        if steps == 1:
            return 1

        key = (curr, steps)
        if key in memo:
            return memo[key]
        memo[key] = 0
        for next_digit in MOVES[curr]:
            memo[key] += self._dfs(next_digit, steps - 1, memo)
        return memo[key]


class Solution:
    def knightDialer(self, n: int) -> int:
        dic = {0: [4, 6], 1: [6, 8], 2: [7, 9], 3: [4, 8], 4:[0, 3, 9], 6:[0, 1, 7], 7:[2, 6], 8:[1, 3], 9: [2, 4]}
        MOD = 10 ** 9 + 7
        cache = {}
        
        def dfs(start, digit):
            key = (start, digit)
            
            if key in cache:
                return cache[key]
            
            if digit == 0:
                return 1
            
            if digit < 0:
                return 0
            
            ans = 0
            if dic.get(start, -1) == -1:
                return 0
            
            for neigh in dic[start]:
                ans += dfs(neigh, digit -1)
            
            cache[key] = ans
            
            return ans
        
        count = 0
        for i in range(10):
            count = (count + dfs(i, n-1)) % MOD
            
        return count

class Solution:
        
    def knightDialer(self, n: int) -> int:
        
        MOD = 10**9 + 7
        
        M = [[0 for i in range(10)] for j in range(n+1)] 
        # print(M)
        
        next_move = {0: [4,6], 1:[6,8], 2:[7,9], 3:[4,8], 4:[3,9,0], 5:[],
                     6:[1,7,0], 7:[2,6],8:[1,3],9:[2,4]}
    
    
        def paths(pos, nhop):
            if nhop == 1:
                return 1
            
            if M[nhop][pos] > 0: 
                return M[nhop][pos];
        
            for j in range(len(next_move[pos])):
                M[nhop][pos] += paths(next_move[pos][j], nhop-1)% MOD  
            return M[nhop][pos]
        
        ans = 0
        for start in range(10):
            ans = (ans + paths(start, n)) % MOD
            
        return int(ans);


class Solution:
    def knightDialer(self, n: int) -> int:
        mod = 10**9+7
        
        if n == 1:
            return 10
        
        dic = {1: [6, 8], 2: [7, 9], 3: [4, 8], 4: [3, 9, 0], 6: {1, 7, 0}, 7: [2, 6], 8: [1, 3], 9: [2, 4], 0: [4, 6]}
        memo = {}
        def dfs(cur, n):
            if n == 0:
                return 1
            if (cur, n) in memo:
                return memo[cur, n]
            ret = 0
            for nxt in dic.get(cur, []):
                ret += dfs(nxt, n-1)
            memo[cur, n] = ret
            return ret
    
        ret = 0
        for i in range(10):
            ret += dfs(i, n-1) 
            ret %= mod
        return ret

class Solution:
    def dfs(self, i, N):
        if N == 1:
            return 1
        
        if (i, N) in self.memo:
            return self.memo[(i, N)]
        
        ans = 0
        for nxt in self.map[i]:
            ans += self.dfs(nxt, N - 1)
        self.memo[(i, N)] = ans
        return ans
            
    def knightDialer(self, n: int) -> int:
        if n == 0:
            return 0
        
        if n == 1:
            return 10
        
        self.map = {
            0: [4, 6],
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [3, 9, 0],
            6: [1, 7, 0],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4]
        }
        self.memo = {}
        
        ans = 0
        
        for i in range(10):
            if i == 5:
                continue
            ans = (ans + self.dfs(i, n)) % (10**9 + 7)
            
        return ans

class Solution:
    def knightDialer(self, n: int) -> int:
        # DP 每次要加上那个格的DP值
        #{4, 6}, {6, 8}, {7, 9}, {4, 8}, {3, 9, 0}, {}, {1, 7, 0}, {2, 6}, {1, 9}, {4, 2}
        # 二维数组 表示第i次跳到j上有多少种方法
        # 比如到4的时候 那么可能是从3,9,0 来的 那么i,4 = i,4 + i-1 (3,9,0)
        stack = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],[1,7,0],[2,6],[1,9],[4,2]]
        dp = [[0 for _ in range(10)] for __ in range(n)]
        for i in range(10):     # 随便放  所有按键都初始为1 因为n是跳的次数 放的不算
            dp[0][i] = 1
        for i in range(1,n):    # 跳 1 到 n-1 次
            for j in range(10):
                for k in stack[j]:
                    dp[i][j] = (dp[i][j] + dp[i-1][k]) % (10**9 + 7)
        return sum(dp[-1][i] for i in range(10))  % (10**9 + 7)

class Solution:
    NEIGHBORS = {
        0: (4, 6),
        1: (6, 8),
        2: (7, 9),
        3: (4, 8),
        4: (3, 9, 0),
        5: (),
        6: (1, 7, 0),
        7: (2, 6),
        8: (1, 3),
        9: (2, 4),
    }
    
    def numsFromPos(self, num, jumps):
        jumps_remaining = jumps - 1
        if not jumps_remaining:
            return 1
        
        if (num, jumps) in self.cache:
            return self.cache[(num, jumps)]
        
        res = 0
        for nei in self.NEIGHBORS[num]:
            res += self.numsFromPos(nei, jumps_remaining)
            
        self.cache[(num, jumps)] = res
        return res
        
    def knightDialer(self, n: int) -> int:
        self.cache = {}
        
        res = 0
        for i in range(10):
            res += self.numsFromPos(i, n)
        return res % (10**9 + 7)

class Solution:
    def knightDialer(self, N: int) -> int:
        x1 = x2 = x3 = x4 = x5 = x6 = x7 = x8 = x9 = x0 = 1
        for _ in range(N-1):
            x1, x2, x3, x4, x5, x6, x7, x8, x9, x0 = x8+x6, x7+x9, x4+x8, x3+x9+x0, 0, x1+x7+x0, x2+x6, x1+x3, x2+x4, x4+x6
        return (x1+x2+x3+x4+x5+x6+x7+x8+x9+x0)%(10**9+7)
        
        
        
#         x1 = x2 = x3 = x4 = x5 = x6 = x7 = x8 = x9 = x0 = 1
#         for i in range(N-1):
#             x1, x2, x3, x4, x5, x6, x7, x8, x9, x0 = x6+x8, x7+x9, x4+x8, x3+x9+x0, 0, x1+x7+x0, x2+x6, x1+x3, x2+x4, x4+x6
#         return (x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x0)%(10**9+7)


class Solution:
    def knightDialer(self, n: int) -> int:
        modulo = 10**9 + 7
        
        dp = [1] * 10 
        
        while n > 1:
            new_table = [0] * 10
            for digit in range(10):
                for neighbor in self.getNeighbor(digit):
                    new_table[neighbor] += dp[digit]
            dp = new_table
            n -= 1
            
        return sum(dp) % (modulo)
            
#     def getWays(self, curr, steps):
#         if steps == 0:
#             return 1 
#         if (curr, steps) in self.cache:
#             return self.cache[(curr,steps)]
#         temp = 0
#         for digit in self.getNeighbor(curr):
#             temp += self.getWays(digit,steps-1)
          
#         self.cache[(curr,steps)] = temp
        
#         return temp
            
    
    def getNeighbor(self, digit):
        neighbors = {
            1: (6,8),
            2: (7,9),
            3: (4,8),
            4: (0,3,9),
            5: (),
            6: (0,1,7),
            7: (2,6),
            8: (1,3),
            9: (2,4),
            0: (4,6)
        }
        
        return neighbors[digit]
    


class Solution:
    def _knightDialer(self, n: int, curr_n: int, moves_map: dict, cache: dict) -> int:
        if n == 0:
            return 1
        
        if (curr_n,n) in cache:
            return cache[(curr_n,n)]
        
        distinct_nums = 0
        for next_n in moves_map[curr_n]:
            distinct_nums += self._knightDialer(n-1, next_n, moves_map, cache)
        
        cache[(curr_n, n)] = distinct_nums
        return cache[(curr_n,n)]
    
    def knightDialer(self, n: int) -> int:
        # TLE, let's take care of some symmetry
        # 1 == 3 == 9 == 7, 4 == 6, 2 == 8, 0
        if n == 1:
            return 10

        mod = 10 ** 9 + 7
        nums = 0
        cache = {}
        moves_map = {
            1: [6,8],
            2: [7,9],
            3: [4,8],
            4: [0,3,9],
            5: [],
            6: [0,1,7],
            7: [2,6],
            8: [1,3],
            9: [2,4],
            0: [4,6],
        }
        for m in [1,2,4,0]:
            self._knightDialer(n-1, m, moves_map, cache)
        
        total = cache[(1, n-1)] * 4 + cache[(4,n-1)] * 2 + cache[(2,n-1)] * 2 + cache[(0,n-1)]
        return total % mod

class Solution:
    def knightDialer(self, N: 'int') -> 'int':
        path_graph = {0:[4,6],1:[6,8],2:[7,9],3:[4,8],4:[0,3,9],5:[],6:[0,1,7],7:[2,6],8:[1,3],9:[2,4]}
        mem = {}
        if N == 1: return 10
        def dfs(n, steps):
            if steps == 1: 
                # return [partial]
                return len(path_graph[n])
            if (n,steps) not in mem:
                all_paths = 0
                for next_num in path_graph[n]:
                    # if next_num not in visited:
                        # visited.add(next_num)
                    all_paths += dfs(next_num, steps-1)      
                mem[(n,steps)] = all_paths
            return mem[(n, steps)]
        result = 0
        for n in range(10):
            # visited = set([n])
            temp = dfs(n, N-1)
            # print(temp)
            result += temp
        return result%(10**9 + 7)
            


class Solution:
    def knightDialer(self, n: int) -> int:
        def dfs(pos, remain):
            if remain == 0:
                return 1
            if not (pos, remain) in memo:
                cur = 0
                for np in pos_map[pos]:
                    cur += dfs(np, remain-1)
                memo[(pos, remain)] = cur
            return memo[(pos, remain)]
        
        res = 0
        memo = {}
        pos_map = {0: [4,6], 1:[6,8], 2:[7,9], 3:[4,8], 4:[0,3,9],
                  5:[], 6:[0,1,7], 7:[2,6], 8:[1,3], 9:[2,4]}
        for i in range(10):
            res += dfs(i, n-1)
        return res % (pow(10,9)+7)


class Solution:
    def knightDialer(self, n: int) -> int:
        self.mod_Val = 10**9 + 7
        self.map = {
            1 : [6,8],
            2 : [7,9],
            3 : [4,8],
            4 : [3,9,0],
            5 : [],
            6 : [1,7,0],
            7 : [2,6],
            8 : [1,3],
            9 : [2,4],
            0 : [4,6],
        }
        self.ans = 0
        self.mem = collections.defaultdict(int)
        for i in range(10):
            self.ans+=self.recursion(n-1, i)
            
        return self.ans%self.mod_Val
        
    def recursion(self, hops, s):
        if not hops:
            return 1
        count = 0
        if (hops, s) not in self.mem:
            for n in self.map[s]:
                count += self.recursion(hops-1, n)
            self.mem[(hops,s)] = count
        
        return self.mem[(hops,s)]

class Solution:
    
    
    
    def knightDialer(self, n: int) -> int:
        mem = [[1] for i in range(10)]
        for i in range(1, n):
            for cell in range(10):
                mem[cell].append(self.knightDialerHelper(i, cell, mem))
            
        ans = sum([x[n - 1] for x in mem])
        return ans % (10 ** 9 + 7)
    
    def knightDialerHelper(self, n, cellNumber, mem):
        
        moves = [
            [4, 6],
            [6, 8],
            [7, 9],
            [4, 8],
            [3, 9, 0],
            [],
            [1, 7, 0],
            [2, 6],
            [1, 3],
            [2, 4]
        ]
        
        ans = 0
        for nextCell in moves[cellNumber]:
            ans += mem[nextCell][n - 1]
        return ans


# 当前index位置，下一个可能到达的位置(0 ~ 9)
MOVES = [
    [4, 6], [6, 8], [7,9],
    [4, 8], [3, 9, 0], [],
    [1, 7, 0], [2, 6], [1, 3], [2, 4],
]

class Solution:
    def knightDialer(self, N: int) -> int:
        memo = {}
        res = 0
        for i in range(10):
            res += self._dfs(i, N - 1, memo)
        return res % (10 ** 9 + 7)

    def _dfs(self, curr, steps, memo):
        if steps == 0:
            return 1

        key = (curr, steps)
        if key in memo:
            return memo[key]
        memo[key] = 0
        for next_digit in MOVES[curr]:
            memo[key] += self._dfs(next_digit, steps - 1, memo)
        return memo[key]


class Solution:
    def knightDialer(self, n: int) -> int:
        moves=[[4,6],[6,8],[7,9],[4,8],[3,9,0],[],[1,7,0],[2,6],[1,3],[2,4]]
        mod=10**9+7
        dp=[[0 for j in range(10)] for i in range(n)]
        for i in range(10):
            dp[0][i]=1
        for i in range(1,n):
            for j in range(10):
                for nei in moves[j]:
                    dp[i][nei]+=dp[i-1][j]
                    dp[i][nei]=dp[i][nei]%mod
        res=sum(dp[n-1])%mod
        return res


class Solution:
    def knightDialer(self, N: int) -> int:
        solution = 0
        self.valid_jumps = {
            1: [6, 8],
            2: [9, 7],
            3: [8, 4],
            4: [9, 3, 0],
            5: [],
            6: [7, 1, 0],
            7: [2, 6],
            8: [1, 3],
            9: [4, 2],
            0: [4, 6]
        }
        
        self.N = N
        self.cache = {}

        solution = 0

        for i in range(10):
            solution += self.jump_around(1, i)
        
                                    
        return solution % (pow(10, 9) + 7)
    

    def jump_around(self, number_len_so_far, last_number):
        if (number_len_so_far, last_number) in self.cache:
            return self.cache[(number_len_so_far, last_number)]
        
        if number_len_so_far == self.N:
            return 1
        else:
            solution_for_this_set = 0
            possible_jumps = self.valid_jumps[last_number]
            for possible_jump in possible_jumps:
                solution_for_this_set += self.jump_around(number_len_so_far + 1, possible_jump)
            self.cache[(number_len_so_far, last_number)] = solution_for_this_set
            return solution_for_this_set
         


class Solution:
    def knightDialer(self, n: int) -> int:
        
        next_map = {0:[4,6],1:[6,8],2:[7,9],3:[4,8],4:[0,3,9],5:[],6:[0,1,7],7:[2,6],8:[1,3],9:[2,4]}
        memo = {}
        def dfs(cur_num,n):
            if (cur_num,n) in memo.keys():
                return memo[(cur_num,n)]
            if n == 0:
                return 1
            ans = 0
            for next_num in next_map[cur_num]:                
                ans += dfs(next_num,n-1)
            memo[(cur_num,n)] = ans
            return ans
        
        ans = 0
        MOD = pow(10,9)+7
        memo = {}
        for i in range(10):            
            ans += dfs(i,n-1)%MOD
            ans = ans%MOD
        #    print (\"i:{}, ans={}\".format(i,ans))
            
        return ans

class Solution:
    def knightDialer(self, n: int) -> int:
        M = 10**9 + 7
        current_ways = [1]*10
        for i in range(1,n):
            prev = current_ways.copy()
            current_ways[0] = (prev[4] + prev[6]) % M
            current_ways[1] = (prev[6] + prev[8]) % M
            current_ways[2] = (prev[7] + prev[9]) % M
            current_ways[3] = (prev[4] + prev[8]) % M
            current_ways[4] = (prev[3] + prev[9] + prev[0]) % M
            current_ways[5] = 0
            current_ways[6] = (prev[1] + prev[7] + prev[0]) % M
            current_ways[7] = (prev[2] + prev[6]) % M
            current_ways[8] = (prev[1] + prev[3]) % M
            current_ways[9] = (prev[2] + prev[4]) % M
            
            
        return sum(current_ways) % M


class Solution:
    def knightDialer(self, n: int) -> int:
        # DP 每次要加上那个格的DP值
        #{4, 6}, {6, 8}, {7, 9}, {4, 8}, {3, 9, 0}, {}, {1, 7, 0}, {2, 6}, {1, 9}, {4, 2}
        # 二维数组 表示第i次跳到j上有多少种方法
        # 比如到4的时候 那么可能是从3,9,0 来的 那么i,4 = i,4 + i-1 (3,9,0)
        stack = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],[1,7,0],[2,6],[1,9],[4,2]]
        dp = [[0 for _ in range(10)] for __ in range(n)]
        for i in range(10):
            dp[0][i] = 1
        for i in range(1,n):
            for j in range(10):
                for k in stack[j]:
                    dp[i][j] = (dp[i][j] + dp[i-1][k]) % (10**9 + 7)
        return sum(dp[-1][i] for i in range(10))  % (10**9 + 7)

class Solution:
    def __init__(self):
        self.moves = [
            [4,6],
            [6,8],
            [7,9],
            [4,8],
            [3,9,0],
            [],
            [7,1,0],
            [6,2],
            [1,3],
            [4,2]
        ]
        self.memoized_moves = {}
    
    def knightDialer(self, n: int) -> int:
        if n == 0:
            return 0
        
        moves = 0 
        
        for i in range(10):
            moves += self.calculateMoves(n-1, i)
            
        return moves% (pow(10,9) + 7)
            
            
    def calculateMoves(self, moves_remaining, current_number):
        if moves_remaining == 0:
            return 1
        
        moves = 0
        for next_number in self.getMoves(current_number):
            if (moves_remaining, next_number) not in list(self.memoized_moves.keys()):
                self.memoized_moves[(moves_remaining, next_number)] = self.calculateMoves(moves_remaining-1, next_number)
            moves += self.memoized_moves[(moves_remaining, next_number)]
            
        return moves
        
        
    def getMoves(self, number):
        return self.moves[number]
        
        


class Solution:
    def knightDialer(self, n: int) -> int:
        
        next_map = {0:[4,6],1:[6,8],2:[7,9],3:[4,8],4:[0,3,9],5:[],6:[0,1,7],7:[2,6],8:[1,3],9:[2,4]}
       
        def dfs(cur_num,n):
            if (cur_num,n) in memo.keys():
                return memo[(cur_num,n)]
            if n == 0:
                return 1
            ans = 0
            for next_num in next_map[cur_num]:                
                ans += dfs(next_num,n-1)
            memo[(cur_num,n)] = ans
            return ans
        
        ans = 0
        MOD = pow(10,9)+7
        memo = {}
        for i in range(10):            
            ans += dfs(i,n-1)%MOD
            ans = ans%MOD
        #    print (\"i:{}, ans={}\".format(i,ans))
            
        return ans

class Solution:
    def knightDialer(self, n: int) -> int:
        memo = {}
        pos = {
            1: [6, 8],
            2: [7, 9],
            3: [4, 8], 
            4: [3, 9, 0],
            5: [],
            6: [1, 7, 0],
            7: [2, 6],
            8: [3, 1],
            9: [2, 4],
            0: [6, 4]
        }
        
        res = 0
        mod = 10**9 + 7
        
        def recur(i, hops):
            if (i, hops) in memo:
                return memo[(i, hops)]
            if hops == 0:
                return 1
            cnt = 0
            for nums in pos[i]:
                cnt += recur(nums, hops - 1)
                memo[(i, hops)] = cnt
            return cnt
                
        for i in range(10):
            res += recur(i, n-1)
        return res % mod

class Solution:
    def knightDialer(self, n: int) -> int:
        nbrs = {
                1: [6,8],
                2: [9,7],
                3: [4,8],
                4: [3,9,0],
                5 : [],
                6: [1,7,0],
                7: [2,6],
                8: [1,3],
                9: [2,4],
                0:  [4,6]            
                }
        
        self.memo = {}
        def find_count(idx,num):
            if idx == n:
                return 1
            if (num,idx) in self.memo:
                return self.memo[(num,idx)]
            count = 0
            for nbr in nbrs[num]:
                count += find_count(idx+1,nbr)
            
            self.memo[(num,idx)] = count
            return count
        ans = 0
        for i in range(10):
            ans += find_count(1,i)
        mod = 10 ** 9 + 7
        
        return ans%mod


class Solution:
    def knightDialer(self, n: int) -> int:
        
        moves = {1:[6, 8], 2:[7, 9], 3:[4, 8], 4:[0, 3, 9], 5:[], 6:[0, 1, 7], 7:[2, 6], 8:[1, 3], 9:[2, 4], 0:[4, 6]}
        
        from functools import lru_cache
        @lru_cache(maxsize = None)
        def dfs(i, length):
            if n == length:
                return 1
            
            total = 0
            for newI in moves[i]:
                total += dfs(newI, length + 1)
            return total
        
        ans = 0
        for i in range(0, 10):
            ans += dfs(i, 1)
            if ans >= 10**9+7:
                ans = ans%(10**9+7)
        return ans

class Solution:
    def knightDialer(self, n: int) -> int:
        dp = [0 for i in range(12)]
        num = [1,2,3,4,5,6,7,8,9,11]
        for j in num:
            dp[j] = 1
        for i in range(1,n):
            temp = [0 for l in range(12)]
            for j in num:
                if(j%3==0):
                    temp[j] += dp[j+5] if j+5 in num else 0
                    temp[j] += dp[j-5] if j-5 in num else 0
                    temp[j] += dp[j+1] if j+1 in num else 0
                    temp[j] += dp[j-7] if j-7 in num else 0
                elif(j%3==1):
                    temp[j] += dp[j+5] if j+5 in num else 0
                    temp[j] += dp[j-5] if j-5 in num else 0
                    temp[j] += dp[j+7] if j+7 in num else 0
                    temp[j] += dp[j-1] if j-1 in num else 0
                else:
                    temp[j] += dp[j+5] if j+5 in num else 0
                    temp[j] += dp[j-5] if j-5 in num else 0
                    temp[j] += dp[j+7] if j+7 in num else 0
                    temp[j] += dp[j-7] if j-7 in num else 0
            dp = temp
        return sum(dp)%(10**9+7)

class Solution:
    def __init__(self):
        self.moves = [
            [4,6],
            [6,8],
            [7,9],
            [4,8],
            [3,9,0],
            [],
            [7,1,0],
            [6,2],
            [1,3],
            [4,2]
        ]
        
        self.memoized_numbers= {}
    
    def knightDialer(self, n: int) -> int:
        distinctPhoneNumbers = 0
        for i in range(10):
            distinctPhoneNumbers += self.getPhoneNumbers(n-1, i)
        
        return(distinctPhoneNumbers%(pow(10,9)+7))
        
    
    def getPhoneNumbers(self, moves_remaining, current_number):
        if moves_remaining == 0:
            return 1
        
        else:
            moves = 0
            for number in self.getMoves(current_number):
                if (moves_remaining, number) not in list(self.memoized_numbers.keys()):
                    self.memoized_numbers[(moves_remaining, number)] = self.getPhoneNumbers(moves_remaining-1, number)
                moves += self.memoized_numbers[(moves_remaining, number)]

            return moves

    def getMoves(self, move):
        return self.moves[move]
        


from collections import defaultdict
class Solution:
    def knightDialer(self, N: int) -> int:
        
        MOD = 10 ** 9 + 7
        board = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [-1, 0, -1]]
        
        dp = defaultdict(int)
        movesC = {}
        def moves(i, j):
            valids = set()
            for u,v in [(i-1, j + 2), (i + 1, j + 2), (i - 1,j-2), (i+1, j-2), (i-2, j +1), (i-2,j-1), (i+2, j+1), (i + 2, j-1)]:
                if u < 0 or v < 0 or u >= len(board) or v >= 3:
                    continue
                if board[u][v] != -1:
                    valids.add((u,v))
            return valids
        for i in range(len(board)):
            for j in range(3):
                if board[i][j] != -1:
                    movesC[(i, j)] = moves(i, j)
        total = 0
        for n in range(1, N+1):
            for i in range(len(board)):
                for j in range(len(board[i])):
                    num = board[i][j]
                    if num != -1:
                        key = (i, j, n)
                        if n == 1:
                            dp[key] = 1
                        else:
                            
                            for u, v in movesC[(i, j)]:
                                dp[key] += dp[(u, v, n - 1)] % MOD
                        if n == N:
                            total += dp[key]  % MOD
                    
        return total % MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        
        MOD = 10**9 + 7
        poss = {}
        poss[1] = [6,8]
        poss[2] = [7,9]
        poss[3] = [4,8]
        poss[4] = [3,9,0]
        poss[5] = []
        poss[6] = [1,7,0]
        poss[7] = [2,6]
        poss[8] = [1,3]
        poss[9] = [2,4]
        poss[0] = [4,6]
        
        
        def helper(numb,i):
            # print('numb is ', numb)
            # print('at i ',i)
            if i == n:
                return 1
            if (numb,i) in mem:
                return mem[(numb,i)]
            out= 0
            child = poss[numb]
            nchild = len(child)
            for j in range(nchild):
                val = child[j]
                out += helper(val,i+1)
                out = out % MOD
            mem[(numb,i)] = out 
            return out
        res = 0
        mem = {}
        for i in range(10):
            # print('starting at ',i)
            res += helper(i,1)
        return res % MOD

from collections import defaultdict
class Solution:
    def knightDialer(self, N: int) -> int:
        
        
        board = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [-1, 0, -1]]
        
        dp = defaultdict(int)
        movesC = {}
        def moves(i, j):
            valids = set()
            for u,v in [(i-1, j + 2), (i + 1, j + 2), (i - 1,j-2), (i+1, j-2), (i-2, j +1), (i-2,j-1), (i+2, j+1), (i + 2, j-1)]:
                if u < 0 or v < 0 or u >= len(board) or v >= 3:
                    continue
                if board[u][v] != -1:
                    valids.add((u,v))
            return valids
        for i in range(len(board)):
            for j in range(3):
                if board[i][j] != -1:
                    movesC[(i, j)] = moves(i, j)
        total = 0
        for n in range(1, N+1):
            for i in range(len(board)):
                for j in range(len(board[i])):
                    num = board[i][j]
                    if num != -1:
                        key = (i, j, n)
                        if n == 1:
                            dp[key] = 1
                        else:
                            
                            for u, v in movesC[(i, j)]:
                                dp[key] += dp[(u, v, n - 1)]
                        if n == N:
                            total += dp[key]
                    
        return total % (10 ** 9 + 7)

from collections import deque

class Solution:
    
    def __init__(self):
        self.next_move = [(4,6), (6, 8), (7,9), (4, 8), (3,0,9), (), (1, 7,0), (6, 2), (3,1), (2, 4)]
        self.cache = {}
        
    def dfs(self, start, n):
        if n == 0:
            return 1
        
        if not self.cache.get((start, n)):
            total_numbers = 0
            for i in self.next_move[start]:
                total_numbers += self.dfs(i, n-1)
            self.cache[(start,n)] = total_numbers
        return self.cache[(start,n)]
    
    def knightDialer(self, n: int) -> int:
        return sum([self.dfs(i, n-1) for i in range(10)]) % (10**9 + 7)
                


class Solution:
    def knightDialer(self, n: int) -> int:
        dp = [0 for i in range(12)]
        num = [1,2,3,4,5,6,7,8,9,11]
        for i in range(n):
            temp = [0 for l in range(12)]
            for j in num:
                if(i==0):
                    temp[j] = 1
                else:
                    temp[j] += dp[j+5] if j+5 in num else 0
                    temp[j] += dp[j-5] if j-5 in num else 0
                    if(j%3==0):
                        temp[j] += dp[j+1] if j+1 in num else 0
                        temp[j] += dp[j-7] if j-7 in num else 0
                    elif(j%3==1):
                        temp[j] += dp[j+7] if j+7 in num else 0
                        temp[j] += dp[j-1] if j-1 in num else 0
                    else:
                        temp[j] += dp[j+7] if j+7 in num else 0
                        temp[j] += dp[j-7] if j-7 in num else 0
            dp = temp
        return sum(dp)%(10**9+7)

class Solution:
    def __init__(self):
        self.moves = [ 
            [4,6],
            [8,6],
            [7,9],
            [4,8],
            [9,3,0],
            [],
            [7,1,0],
            [6,2],
            [1,3],
            [2,4],
        ]
        
        self.memoized_current_number_and_remaining_moves = {}
    
    def getNextMoves(self, current_number):
        return self.moves[current_number]
    
    def knightDialer(self, n: int) -> int:
        total_moves = 0
        for number in range(10):
            total_moves += self.knightDialerOneNumber(number, n-1)
        return total_moves % (pow(10,9) +7)
    
    
    def knightDialerOneNumber(self, current_number, moves_left):
        if moves_left == 0:
            return 1
        
        moves = 0
        
        for move in self.getNextMoves(current_number):
            if (move, moves_left) in list(self.memoized_current_number_and_remaining_moves.keys()):
                moves += self.memoized_current_number_and_remaining_moves[(move, moves_left)]
            else:
                self.memoized_current_number_and_remaining_moves[(move, moves_left)] = self.knightDialerOneNumber(move, moves_left -1)
                moves += self.memoized_current_number_and_remaining_moves[(move, moves_left)]
            
        return moves


from functools import lru_cache
class Solution:
    def knightDialer(self, n: int) -> int:
        ## dp/ recursion
        neighbors = {
            0:[4,6],
            1:[6,8],
            2:[7,9],
            3:[4,8],
            4:[3,9,0],
            5:[], # 5 is a stuck point? also no way to get to 5
            6:[1,7,0],
            7:[2,6],
            8:[1,3],
            9:[2,4],
        }
        
        #lru_cache is needed
        @lru_cache(None)
        def dfs(i,n):
            if(n == 1):
                return 1;
            count = 0;
            for x in neighbors[i]:
                count = (count+dfs(x,n-1))%(10**9+7)
            return count;
        ansr = 0;
        for i in range(10):
            #print(dfs(i,n))
            ansr= (ansr+dfs(i,n))%(10**9+7)
            
        return ansr
            


class Solution:
    valid_jumps = dict()
    valid_jumps[0] = [4,6]
    valid_jumps[1] = [6,8]
    valid_jumps[2] = [7,9]
    valid_jumps[3] = [4,8]
    valid_jumps[4] = [0,3,9]
    valid_jumps[5] = []
    valid_jumps[6] = [0,1,7]
    valid_jumps[7] = [2,6]
    valid_jumps[8] = [1,3]
    valid_jumps[9] = [2,4]
    cache = dict()
    def knightDialer(self, n: int) -> int:
        if n == 1:
            return 10;
        agg = 0
        for idx in range(10):
            if idx != 5:
                agg += self.knightDialerHelper(idx, n-1)
        return agg % int(1e9 + 7)
    
    def knightDialerHelper(self, start, n):
        if n == 1:
            return len(self.valid_jumps[start])
        if (start, n) in self.cache.keys():
            return self.cache[(start,n)]
        numbers = 0
        for k in self.valid_jumps[start]:
            numbers += self.knightDialerHelper(k, n-1)
        self.cache[(start,n)] = numbers
        return numbers

class Solution:
    def knightDialer(self, n: int) -> int:
        
        dp = [1 for x in range(10)]
        
        # jumpMap = {1: [6, 8], 2: [7, 9], 3: [8, 4], 4: [9, 3, 0]: 5: [], 6: [1, 7, 0], 7: [2, 6], 8: [1, 3], 9: [4, 2], 0: [4, 6]}
        
        for index in range(n - 1):
            
            newDp = [dp[4] + dp[6],
                     dp[6] + dp[8], 
                     dp[7] + dp[9], 
                     dp[8] + dp[4], 
                     dp[9] + dp[3] + dp[0],
                     0, 
                     dp[1] + dp[7] + dp[0],
                     dp[2] + dp[6], 
                     dp[1] + dp[3], 
                     dp[4] + dp[2]]
                        
            dp = newDp
        
        return sum(dp) % (10**9 + 7)

from collections import defaultdict

class Solution:
    def knightDialer(self, n: int) -> int:
        
        # the graph
        G =  {1: [6, 8],
             2: [7, 9],
             3: [4, 8],
             6: [1, 7, 0],
             5: [],
             4: [3, 9, 0],
             7: [2,6],
             8: [1,3],
             9: [2,4],
             0: [4,6]}
        
        
        
        # keys are 0,1,2....10
        # values are dict
        #.      keys are number of movement from this point
        #       how many different combination exist
        
        dp = defaultdict(lambda: defaultdict(lambda: 0))
            
        
        def dfs(number, numberOfMovements):
            
            if numberOfMovements == 0:
                return 1
            
            if dp[number][numberOfMovements]:
                return dp[number][numberOfMovements]
            
            total = 0
            for i in G[number]:
                total += dfs(i, numberOfMovements-1)
                
                
            dp[number][numberOfMovements] = total
            return total
        
        res = 0
        for i in range(10):
            res += dfs(i, n-1)
            res = res % 1000000007
            
        return res
            
        
        
                                


class Solution:
    def knightDialer(self, n: int) -> int:
        dc = {0:(4,6),1:(6,8),2:(7,9),3:(4,8),4:(3,9,0),5:(),6:(0,7,1),7:(2,6),8:(1,3),9:(2,4)}
        dp = [[0]*10 for i in range(n+1)]
        for i in range(10):
            dp[1][i]=1
        for i in range(2,n+1):
            for j in range(10):
                for k in range(10):
                    if j in dc[k]:
                        dp[i][j]+=dp[i-1][k]
        return sum(dp[n])%(10**9+7)


import numpy as np
class Solution:
    def knightDialer(self, n: int) -> int:
        ans = np.ones((10,),dtype=int)
        table = {0:[4,6],
                 1:[6,8],
                 2:[7,9],
                 3:[4,8],
                 4:[0,3,9],
                 6:[0,1,7],
                 7:[2,6],
                 8:[1,3],
                 9:[4,2]
                }
   
        for i in range(n-1):
            tempans = np.zeros((10,),dtype=int)
            for j in range(10):
                if j!=5:
                    values = table.get(j)
                    for value in values:
                        tempans[value] += ans[j]
            ans = tempans
            if(sum(ans)>10**9+7):
                ans = ans%(10**9+7)
        return sum(ans)%(10**9+7)
                            
                    


class Solution:
    def knightDialer(self, n: int) -> int:
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
             [1,7,0],[2,6],[1,3],[2,4]]
        
        sol = []
        cache = {}
        def backtrack(pos, hops, cur):
            if (pos, hops) in cache:
                return cache[(pos, hops)]
            if hops == 0:
                return 1
            count = 0
            for nbr in moves[pos]:
                cur.append(nbr)
                count += backtrack(nbr, hops-1, cur)
                cur.pop()
            cache[(pos, hops)] = count
            return count
            
        counts = 0
        for pos in range(10):
            counts += backtrack(pos, n-1, [])
            
        return counts%(10**9+7)
        
#         cur_hops = 1
#         prev_counts = [1]*10
#         cur_counts = [0]*10
        
#         while cur_hops < n:
#             cur_hops += 1
#             cur_counts = [0]*10

#             for pos in range(10):
#                 for nbr in moves[pos]:
#                     cur_counts[pos] += prev_counts[nbr]
#             prev_counts = cur_counts
        
#         return sum(prev_counts)%(10**9+7)


from collections import defaultdict


class Solution:
    def knightDialer(self, n: int) -> int:
        self.buildPad()
        self.buildMoves()
        
        self.memo = defaultdict(lambda: -1)
        
        numbers = sum(self.visit(start, n-1) for start in range(10))
                      
        return numbers % (10**9 + 7)
        
    def visit(self, start: int, n: int) -> int:
        if n == 0:
            return 1
        elif self.memo[(start, n)] != -1:
            return self.memo[(start, n)]
        
        numbers = 0
        for new_start in self.moves[start]:
            numbers += self.visit(new_start, n-1)
        
        self.memo[(start, n)] = numbers
        return numbers
    
    def buildPad(self) -> None:
        self.pad = [[str(i + j) for j in range(3)] for i in range(1, 10, 3)]
        self.pad.append(['*', '0', '#'])
    
    def buildMoves(self) -> None:
        self.moves = (
            (4, 6),
            (6, 8),
            (7, 9),
            (4, 8),
            (0, 3, 9),
            (),
            (0, 1, 7),
            (2, 6),
            (1, 3),
            (2, 4)
        )


class Solution:
    def knightDialer(self, n: int) -> int:
        if n <=0:
            return 0
        MOD = 10 ** 9 + 7
        g = [[4,6],[6,8],[7,9],[4,8],[0,3,9],[],[0,1,7],[2,6],[1,3],[2,4]]
        dp = [[None] * 10 for _ in range(n+1)]
        # kd(n,start) = sum(kd(n-1,nxtstart) for nxtstart in g[start]))
        # kd(1,start) = 1
        def kd(n, start):
            if n == 1:
                return 1
            if dp[n][start] is None:
                dp[n][start] = sum([kd(n-1, nxt) for nxt in g[start]])
            return dp[n][start]
        return sum(kd(n, start) for start in range(10)) % MOD

class Solution:
    def knightDialer(self, N: int) -> int:
        
        g = {0:[4,6],
             1:[6,8],
             2:[7,9],
             3:[4,8],
             4:[3,9,0],
             5:[],
             6:[1,7,0],
             7:[2,6],
             8:[1,3],
             9:[4,2]}
        
        A = [[1 if i in g[j] else 0 for i in range(10)] for j in range(10)]
        
        v = [1]*10
        for _ in range(N-1):
            res = [0]*10
            for r in range(10):
                for c in range(10):
                    if A[r][c]:
                        res[c] += v[r]
            v = res
        return sum(v) % (10**9 + 7)

class Solution:
    def __init__(self):
        self.moves = [
            [4,6],
            [6,8],
            [7,9],
            [4,8],
            [3,9,0],
            [],
            [7,1,0],
            [6,2],
            [1,3],
            [4,2]
        ]
        
        self.memoized_numbers= {}
    
    def knightDialer(self, n: int) -> int:
        distinctPhoneNumbers = 0
        for i in range(10):
            distinctPhoneNumbers += self.getPhoneNumbers(n-1, i)
        
        return(distinctPhoneNumbers% (pow(10,9) +7))
        
        
    
    def getPhoneNumbers(self, moves_remaining, current_number):
        if moves_remaining == 0:
            return 1
            
        moves = 0
        for number in self.getMoves(current_number):
            if (moves_remaining-1, number) not in list(self.memoized_numbers.keys()):
                self.memoized_numbers[(moves_remaining-1, number)] = self.getPhoneNumbers(moves_remaining-1, number)
            moves += self.memoized_numbers[(moves_remaining-1, number)]
                
        return moves
    
    def getMoves(self, move):
        return self.moves[move]
        


class Solution:
    def knightDialer(self, n: int) -> int:
        adj = {1:[6,8], 2:[7,9], 3:[8,4], 4:[0,9,3], 5:[], 6:[7,1,0], 7:[6,2], 8:[3,1], 9:[4,2], 0:[6,4]}
        res = 0
        memo = collections.defaultdict(int)
        for i in range(10):
            res = (res + self.top_down(memo, adj, n-1, i))%(10**9+7)
        return res
    
    
    
    def top_down(self, memo, adj, n, cur):
        if n == 0: return 1
        if (cur, n) not in memo:
            for nb in adj[cur]:
                memo[(cur, n)] += self.top_down(memo, adj, n-1, nb)%(10**9+7)
        return memo[(cur, n)]
        
#         jump = {1:[6,8], 2:[7,9], 3:[8,4], 4:[0,9,3], 5:[], 6:[7,1,0], 7:[6,2], 8:[3,1], 9:[4,2], 0:[6,4]}
#         # dp = [1]*10
#         # for _ in range(n-1):
#         #     nxt = [0]*10
#         #     for i in range(10):
#         #         for j in jump[i]:
#         #             nxt[j] += dp[i]
#         #     dp = nxt
#         # return sum(dp)%(10**9+7)
    
#     def count_paths(self, start, n, adj):
#         if not n: return 1
#         dp = {v:1 for v in adj.keys()}
#         return self.helper([start], n, adj)
    
#     def helper(self, cur, n, adj):
#         if not n: 
#             return len(cur)
#         nxt = []
#         for u in cur:
#             nxt.extend(adj[u])
#         return self.helper(nxt, n-1, adj)
    


class Solution:
    def pos(self, idx):
        return {0: [4, 6],
                1: [6, 8],
                2: [9, 7],
                3: [4, 8],
                4: [3, 9, 0],
                5: [],
                6: [1, 7, 0],
                7: [6, 2],
                8: [1, 3],
                9: [4, 2]}[idx]

    def knightDialer(self, n: int) -> int:
        if n == 1:
            return 10
        memo = [[0 for _ in range(n + 1)] for i in range(10)]
        for i in range(10):
            memo[i][1] = 1
        for s in range(2, n + 1):
            for idx in range(10):
                for p in self.pos(idx):
                    memo[idx][s] += memo[p][s - 1]
        return sum((memo[i][n] for i in range(10))) % (10 ** 9 + 7)



class Solution:
    def knightDialer(self, n: int) -> int:
        jumps = [[4,6],[6,8],[7,9],[4,8],[0,3,9],[],[0,1,7],[2,6],[1,3],[2,4]]
        mod = 10**9 + 7
        memo = {}
        def helper(n, starting, memo):
            if (n,starting) in memo:
                return memo[(n,starting)]
            if n == 1:
                return 1
            if n == 2:
                return len(jumps[starting])
            sum = 0
            for jump_location in jumps[starting]:
                sum += helper(n-1, jump_location, memo)
            memo[(n,starting)] = sum
            return sum
        
        total_jumps = 0
        for i in range(10):
            if i == 5 and n != 1:
                continue
            total_jumps += helper(n, i, memo)
        return total_jumps % mod
        
        
        
        


class Solution:
    def knightDialer(self, n: int) -> int:
        dc = {0:[4,6],1:[6,8],2:[7,9],3:[4,8],4:[3,9,0],5:[],6:[0,7,1],7:[2,6],8:[1,3],9:[2,4]}
        dp = [[0]*10 for i in range(n+1)]
        for i in range(10):
            dp[1][i]=1
        for i in range(2,n+1):
            for j in range(10):
                for k in range(10):
                    if j in dc[k]:
                        dp[i][j]+=dp[i-1][k]
        return sum(dp[n])%(10**9+7)


class Solution:
    def knightDialer(self, n: int) -> int:
        path = [(4, 6), (6, 8), (7, 9), (4, 8),
               (0, 3, 9), (), (0, 1, 7),
               (2, 6), (1, 3), (2, 4)]
        memo = []
        for i in range(n+1):
            memo.append({})
            for j in range(10):
                memo[i][j] = -1
        
        def dp(num, steps):
            if steps == 1:
                return 1
            if memo[steps][num] != -1:
                return memo[steps][num]
            ret = 0
            for i in path[num]:
                ret += dp(i, steps-1)
            memo[steps][num] = ret
            return ret % 1000000007
        
        res = 0
        for num in range(10):
            res += dp(num, n)
            res %= 1000000007
        return res

import numpy as np

class Solution:
    # Time: O(N), Space: O(N).
    def knightDialer(self, N: int) -> int:
        goto = {
            0: [4, 6],
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [0, 3, 9],
            5: [],
            6: [0, 1, 7],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4],
        }
        # We can build backwards...
        # With x moves left how many numbers numbers can you form from i.
        # For x = 0, 1. 
        
        # Shape (10, N).
        # dp[p, i] = on position p, with i move lefts, how many moves
        # can the knight make.
        dp = np.zeros((10, N)).astype(int)
        
        # With 0 moves left you can only make 1 number. 
        dp[:, 0] = 1
        
        for c in range(1, N):
            for p in range(10):
                for next_vals in goto[p]:
                    dp[p, c] += dp[next_vals, c - 1] % (10**9 + 7)
        
        return int(sum(dp[:, N - 1])) % (10**9 + 7)

class Solution:
    def knightDialer(self, N: int) -> int:
        myMap = {1: [8, 6], 
                 2: [7, 9],
                 3: [4, 8],
                 4: [0, 3, 9],
                 5: [], 
                 6: [0, 1, 7], 
                 7: [2, 6], 
                 8: [1, 3], 
                 9: [2, 4], 
                 0: [4, 6], 
                 -1: list(range(10))}
        cache = {}
        
        def dfs(start, level):
            if level == 0:
                return 1 
            key = str(start) + str(level)
            if key in cache:
                return cache[key]
            else:
                ans = 0 
                for number in myMap[start]:
                    ans += dfs(number, level - 1)
                cache[key] = ans 
                return ans 
            
        total = dfs(-1, N)
        return total % (10**9 + 7)

class Solution:
    def knightDialer(self, N: int) -> int:
        NEIGHBORS_MAP = {
            1: (6, 8),
            2: (7, 9),
            3: (4, 8),
            4: (3, 9, 0),
            5: tuple(),  # 5 has no neighbors
            6: (1, 7, 0),
            7: (2, 6),
            8: (1, 3),
            9: (2, 4),
            0: (4, 6),
        }
        mx = 10**9 + 7
        memo = {}
        def dp(n, curr_num):
            if (n, curr_num) in memo:
                return memo[(n, curr_num)]
            
            if n == N - 1:
                return 1
            comb = 0
            for neighbor in NEIGHBORS_MAP[curr_num]:
                comb += dp(n + 1, neighbor)
            memo[(n, curr_num)] = comb 
            return comb
        res = 0
        for i in range(0, 10):
            res += dp(0, i)
        return res % mx


class Solution:
    def knightDialer(self, n: int) -> int:
        mod = 10**9+7
        c = [1]*10
        for _ in range(n-1):
            c = [
                c[4]+c[6], c[6]+c[8],
                c[7]+c[9], c[4]+c[8],
                c[0]+c[3]+c[9], 0,
                c[0]+c[7]+c[1], c[2]+c[6],
                c[1]+c[3], c[2]+c[4]
            ]
        return sum(c)%mod

class Solution:
    def knightDialer(self, n: int) -> int:
        next = {1: (6, 8),
            2: (7, 9),
            3: (4, 8),
            4: (0, 3, 9),
            5: (),
            6: (0, 1, 7),
            7: (2, 6),
            8: (1, 3),
            9: (2, 4),
            0: (4, 6),
           }
        M = 1000000007
        # cache = {}
        cache = defaultdict(int)
        def helper(m, n):
            if (m, n) not in cache:
                # cache[m,n] = []
                if n == 1:
                    cache[m,n] = 1
                else:
                    for nn in next[m]:
                        # for e in helper(nn, n-1):
                        #     cache[m,n].append([m] + e)
                        cache[m,n] += helper(nn, n-1)
                cache[m,n] %= M
            return cache[m,n] 

        # res = []
        # for i in range(10):
        #    res.extend(helper(i, n))
        # return res

        return sum(helper(i, n) for i in range(10)) % M

class Solution:
    def knightDialer(self, n: int) -> int:
        if n==1: return 10
        hash_map = {0:(4,6),1:(6,8),2:(7,9),3:(4,8),4:(0,3,9),5:(),6:(0,1,7),7:(2,6),8:(1,3),9:(2,4)}
        
        dp = {}
        def ways_n(n,val):
            if n==0:
                return 1
            
            if (n,val) in dp:
                return dp[n,val]
            
            dp[n,val] = 0
            for i in hash_map[val]:
                dp[n,val] += ways_n(n-1,i)
            return dp[n,val]
        
        ans = 0
        for i in range(10):
            ans+=ways_n(n-1,i)
        return ans%(10**9+7)
    


class Solution:
    def getAccessible(self, key):
        switch = {
            1: [6, 8],
            2: [7, 9],
            3: [4,8],
            4: [0,3,9],
            5: [],
            6: [0,1,7],
            7: [2,6],
            8: [1,3],
            9: [2,4],
            0: [4,6]
        }
        return switch.setdefault(key, [])
        
    def knightDialer(self, n: int) -> int:
        dp = [[0]*10 for _ in range(n)]
        dp[0] = [1]*10
        
        for r in range(1,len(dp)):
            for c in range(len(dp[0])):
                neighbors = self.getAccessible(c)
                for n in neighbors:
                    dp[r][c] = dp[r-1][n] + (dp[r][c] % (10**9 + 7))
        return sum(dp[-1]) % (10**9 + 7)
        
                
                
            


class Solution:
    def knightDialer(self, N: int) -> int:
        possible_ways = {1:[6,8],2:[7,9],3:[4,8],4:[3,9,0],5:[],6:[1,7,0],7:[2,6],8:[1,3],9:[2,4],0:[4,6]}
        remember_dict = {}
        def numofways(N, startnum):
            if (startnum,N) in remember_dict:
                return remember_dict[(startnum,N)]
            if N == 1:
                return 1
            else:
                temp = 0
                for nextnum in possible_ways[startnum]:
                    temp += numofways(N-1,nextnum)
                remember_dict[(startnum,N)] = temp   
                return temp
        summation = 0
        for i in range(10):
            summation += numofways(N, i)
        return summation % 1000000007


class Solution:
    def knightDialer(self, n: int) -> int:
        cache = [[0 for i in range(n+1)] for i in range(10)]
        for i in range(10):
            cache[i][1] = 1
        return self.hopper(n, cache) % (10 ** 9 + 7)
    
    def hopper(self, hops_left, cache):
                
        if hops_left == 1:
            return sum([cache[i][1] for i in range(10)])
        elif hops_left < 1:
            return 0
        else:
            for i in range(2, hops_left+1):
                for j in range(10):
                    for nbr in self.nbrs(j):
                        cache[j][i] += cache[nbr][i-1]
                    
        return sum([cache[i][hops_left] for i in range(10)])
    
    
    def nbrs(self, ind):
        nbrs = {0: [4,6],
                1: [6, 8],
                2: [9, 7],
                3: [4, 8],
                4: [3, 9, 0],
                5: [],
                6: [1,7, 0],
                7: [6, 2],
                8: [1, 3],
                9: [4, 2]}
        
        return nbrs[ind]


class Solution:
    def knightDialer(self, n: int) -> int:
      moves = {
        0: [4, 6],
        2: [7, 9],
        1: [6, 8],
        3: [4, 8],
        4: [0, 3, 9],
        5: [],
        6: [0, 1, 7],
        7: [2, 6],
        8: [1, 3],
        9: [2, 4]
      }        
      
      store = {}
      def f(num, rem):
        if rem == 1: return 1 
        if (num, rem) in store: return store[(num, rem)]
        res = store[(num, rem)] = sum([f(m, rem - 1) for m in moves[num]])
        return res
      
      return sum([f(num, n) for num in range(10)]) % (10 ** 9 + 7)
        
        
        
        
      


class Solution:
    def knightDialer(self, N: int) -> int:
        
        
        hop_map = {1:[6,8],
                  2:[7,9],
                  3:[4,8],
                  4:[0,3,9],
                  5:[],
                  6:[0,1,7],
                  7:[2,6],
                  8:[1,3],
                  9:[2,4],
                  0:[4,6]}
        
        memo = {(i,1): 1 for i in range(10)}
        
        def num_hops(key:int, N:int):
            
            if N == 1:
                return memo[(key, 1)]
            if (key, N) in memo:
                return memo[(key, N)]
            
            sum_ = 0
            for v in hop_map[key]:
                sum_ += num_hops(v, N-1)
            
            memo[(key, N)] = sum_ % (10**9 + 7)
            return sum_
    
        sum_ = 0
        for i in range(10):
            sum_ += num_hops(i, N)  % (10**9 + 7)
        return sum_  % (10**9 + 7)


class Solution:
    arr = None
    
    def knightDialer(self, n: int) -> int:
        self.init_arr(n)
        if n == 1:
            return 10
        
        total = 0
        
        for j in range(2, n+1):
            for i in range(10):
                self.dialStart(i, j)
        
        return self.get_ans(n)
    
    def get_ans(self, n):
        total = 0
        for i in range(10):
            total = (total + self.arr[i][n]) % 1000000007
        return total
    
    def init_arr(self, n):
        self.arr = [[0]*(n+1) for i in range(10)]
        
        for i in range(10):
            self.arr[i][1] = 1
    
    def dialStart(self, start: int, n: int):
        neighbours = self.get_neighbours()

        total = 0
        for ne in neighbours[start]:
            total = (total + self.arr[ne][n-1]) % 1000000007
        
        self.arr[start][n] = total
    
    def get_neighbours(self):
        return {
            0: [4, 6],
            1: [8, 6],
            2: [7, 9],
            3: [8, 4],
            4: [0, 3, 9],
            5: [],
            6: [0, 1, 7],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4],
        }


class Solution:
    def knightDialer(self, n: int) -> int:
        move = [1]*10
        for i in range(n-1):
            new_move = [1]*10
            new_move[0], new_move[1] = (move[4]+move[6])%(10**9 + 7), (move[8]+move[6])%(10**9 + 7)
            new_move[2], new_move[3] = (move[7]+move[9])%(10**9 + 7), (move[8]+move[4])%(10**9 + 7)
            new_move[4], new_move[5] = (move[0]+move[3]+move[9])%(10**9 + 7), 0
            new_move[6], new_move[7] = (move[0]+move[1]+move[7])%(10**9 + 7), (move[2]+move[6])%(10**9 + 7)
            new_move[8], new_move[9] = (move[1]+move[3])%(10**9 + 7), (move[2]+move[4])%(10**9 + 7)
            move = new_move
        return sum(move) % (10**9 + 7)


class Solution:
    def knightDialer(self, N: int) -> int:
        if N == 1:
            return 10
        
        navigation = {
            0: [4, 6],
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [0, 3, 9],
            6: [0, 1, 7],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4],
        }
        
        memo = {}
        
        def get_num_distinct_dials(last_digit, N_left):
            if N_left == 0:
                return 1
            
            memo_key = (last_digit, N_left)
            if memo_key in memo:
                return memo[memo_key]
            
            result = sum([get_num_distinct_dials(next_digit, N_left - 1) for next_digit in navigation[last_digit]])
            memo[memo_key] = result
            return result
        
        return sum([get_num_distinct_dials(first_digit, N - 1) for first_digit in navigation.keys()]) % (10 ** 9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        
        moves = {
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [3, 9, 0],
            5: [],
            6: [1, 7, 0],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4],
            0: [4, 6]
        }
                
        dp1 = [1] * 10
        for i in range(n - 1):  # do n - 1 times 
            dp2 = [0] * 10
            for digit in range(10):
                for neib in moves[digit]:
                    dp2[digit] += dp1[neib]
                    dp2[digit] %= pow(10, 9) + 7
            dp1 = dp2
        
        return (sum(dp1)) % (pow(10, 9) + 7)
        


MAX = 10**9 + 7

d = [
    [4, 6],
    [6, 8],
    [7, 9],
    [4, 8],
    [3, 9, 0],
    [],
    [1, 7, 0],
    [2, 6],
    [1, 3],
    [2, 4],
    [4, 6]
]


class Solution:
    def __init__(self):
        self.memo = {}
    
    def knightDialer(self, n: int) -> int:
        return sum([self.helper(n, p) for p in range(10)]) % MAX
    
    def helper(self, n: int, p: int) -> int:
        if (n, p) in self.memo: return self.memo[(n, p)]
        if n == 1: return 1
        r = sum([self.helper(n - 1, q) for q in d[p]])
        self.memo[(n, p)] = r
        return r

MAX = 10**9 + 7

d = {
    1: [6, 8],
    2: [7, 9],
    3: [4, 8],
    4: [3, 9, 0],
    5: [],
    6: [1, 7, 0],
    7: [2, 6],
    8: [1, 3],
    9: [2, 4],
    0: [4, 6]
}

class Solution:
    def __init__(self):
        self.memo = {}
    
    def knightDialer(self, n: int) -> int:
        return sum([self.helper(n, p) for p in d.keys()]) % MAX
    
    def helper(self, n: int, p: int) -> int:
        if (n, p) in self.memo: return self.memo[(n, p)]
        if n == 1: return 1
        r = sum([self.helper(n - 1, q) for q in d[p]])
        self.memo[(n, p)] = r
        return r

class Solution:
    def knightDialer(self, n: int) -> int:
        
        graph = {0:[4,6],1:[6,8],2:[7,9],3:[4,8],4:[0,9,3],5:[],6:[0,7,1],7:[2,6],8:[1,3],9:[4,2]}
        
        ans = 0
        
        self.cache = {}
        
        for u in graph.keys():
            
            ans += self.dial(graph,u,n-1)
        
        return ans % (10**9 + 7)
    
    def dial(self,graph,start,n):
        
        if n == 0:
            return 1
        
        ans = 0
        
        key = str(start) + ' ' + str(n)
        
        if key in self.cache.keys():
            
            return self.cache[key]
        
        for v in graph[start]:
            ans += self.dial(graph,v,n-1)
            
        self.cache[key] = ans
            
        return self.cache[key]

class Solution:
    def knightDialer(self, n: int) -> int:
        
        graph = {0:[4,6],1:[6,8],2:[7,9],3:[4,8],4:[0,9,3],5:[],6:[0,7,1],7:[2,6],8:[1,3],9:[4,2]}        
        ans = 0
        self.cache = {}
        for u in list(graph.keys()):
            ans += self.dial(graph,u,n-1)
            
        return ans % (10**9 + 7)
        
    def dial(self,graph,start,n):
        
        if n == 0:
            return 1
        
        ans = 0
        
        key = str(start) + ' ' + str(n)
        
        if key in list(self.cache.keys()):
            
            return self.cache[key]
        
        for v in graph[start]:
            ans += self.dial(graph,v,n-1)
            
        self.cache[key] = ans
            
        return self.cache[key]
#         pkey = str(i) + '-' + str(j) + '-' + str(n)
        
#         if pkey in self.dp.keys():
#             return self.dp[pkey]


#         for dx,dy in self.dirs:
#             x = i + dx
#             y = j + dy
#             temp = 0    
#             if 0 <= x <= self.m -1 and 0 <= y <= self.n-1 and self.numpad[x][y] != -1:
#                 key = str(x) + '-' + str(y) + '-' + str(n-1)
#                 if key in self.dp.keys():
#                     temp =  self.dp[key]
#                 else:
#                     temp =  self.solve(x,y,n-1)           
#                     self.dp[key] = temp
#             ans += temp
            
#         self.dp[pkey] = ans
        

                


class Solution:
    def knightDialer(self, n: int) -> int:
        
        # pad = [['1','2','3'],['4','5','6'],['7','8','9'],['*','0','#']]
        
        graph = {0:[4,6],1:[6,8],2:[7,9],3:[4,8],4:[0,9,3],5:[],6:[0,7,1],7:[2,6],8:[1,3],9:[4,2]}
        
        # self.dirs = [(1,2),(2,1),(-1,2),(-2,1),(-1,-2),(-2,-1),(2,-1),(1,-2)]
        
        ans = 0
        
        self.cache = {}
        
        for u in list(graph.keys()):
            
            ans += self.dial(graph,u,n-1)
        
        return ans % (10**9 + 7)
    
    def dial(self,graph,start,n):
        
        if n == 0:
            return 1
        
        ans = 0
        
        key = str(start) + ' ' + str(n)
        
        if key in list(self.cache.keys()):
            
            return self.cache[key]
        
        for v in graph[start]:
            ans += self.dial(graph,v,n-1)
            
        self.cache[key] = ans
            
        return self.cache[key]
                
            
            
        
        
        
        


class Solution:
    def knightDialer(self, n: int) -> int:
        mod_num = 10 ** 9 + 7
        moves = [(-2, -1), (-1, -2), (1, -2), (2, -1), (-2, 1), (-1, 2), (1, 2), (2, 1)]
        cells = [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2), (3, 1)]
        cell2idx = {}
        for i, cell in enumerate(cells):
            cell2idx[cell] = i 
        # number of sequences end at cell
        sequences = [1 for _ in cells]
        for step in range(n - 1):
            new_sequences = [0 for _ in cells]
            for i, (r, c) in enumerate(cells):
                for rm, cm in moves:
                    newr = r + rm
                    newc = c + cm
                    if (newr, newc) in cell2idx:
                        new_idx = cell2idx[(newr, newc)]
                        new_sequences[new_idx] += sequences[i]
            sequences = [cnt % mod_num for cnt in new_sequences]
        return sum(sequences) % mod_num


class Solution:
    def knightDialer(self, N: int) -> int:
        myMap = {1: [8, 6], 
                 2: [7, 9],
                 3: [4, 8],
                 4: [0, 3, 9],
                 5: [], 
                 6: [0, 1, 7], 
                 7: [2, 6], 
                 8: [1, 3], 
                 9: [2, 4], 
                 0: [4, 6], 
                 -1: list(range(10))}
        cache = {}
        
        def dfs(start, level):
            if level == 0:
                return 1 
            key = str(start) + str(level)

            ans = 0 
            for number in myMap[start]:
                nextK = str(number) + str(level-1)
                if nextK in cache:
                    ans += cache[nextK]
                else:
                    ans += dfs(number, level - 1)
            cache[key] = ans 
            return ans 
            
        total = dfs(-1, N)
        return total % (10**9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 1:
            return 10
        move = [1]*10
        for i in range(n-1):
            new_move = [1]*10
            new_move[0], new_move[1] = (move[4]+move[6])%(10**9 + 7), (move[8]+move[6])%(10**9 + 7)
            new_move[2], new_move[3] = (move[7]+move[9])%(10**9 + 7), (move[8]+move[4])%(10**9 + 7)
            new_move[4], new_move[5] = (move[0]+move[3]+move[9])%(10**9 + 7), 0
            new_move[6], new_move[7] = (move[0]+move[1]+move[7])%(10**9 + 7), (move[2]+move[6])%(10**9 + 7)
            new_move[8], new_move[9] = (move[1]+move[3])%(10**9 + 7), (move[2]+move[4])%(10**9 + 7)
            move = new_move
        return sum(move) % (10**9 + 7)


class Solution:
    def knightDialer(self, N: int) -> int:
        choices = {
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [0, 3, 9],
            5: [],
            6: [0, 1, 7],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4],
            0: [4, 6]
        }
        
        self.memo = dict()
        
        def dfs(curr, n):
            key = (curr, n)
            if key in self.memo:
                return self.memo[key]
            
            if n == 1:
                return 1
            
            sub = 0
            for next in choices[curr]:
                sub += dfs(next, n - 1)
            
            self.memo[key] = sub
            return sub
        
        res = 0
        for s in range(10):
            res += dfs(s, N)
                
        return res % (10 ** 9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        space = {1:[6,8], 2:[7,9], 3:[4,8], 4:[0,3,9], 5:[], 6:[0,7,1], 7:[2,6],8:[1,3],9:[4,2],0:[4,6]}
        memory = {}
        if n < 1:
            return 0
        
        def recurse(number, n):
            if n < 2:
                return 1
            
            key = str([number,n])
            if key in memory:
                return memory[key]
            
            moves = 0
            for i in space[number]:
                moves+= recurse(i,n-1)
    
            memory[key] = moves
            return moves
        
        s = 0
        for number in space:
            s+= recurse(number, n)
        
        return s % (10**9 + 7)

class Solution:
  def knightDialer(self, N: int) -> int:
    if N == 0:
      return 0
    d = {}
    choices = [
      [4, 6],
      [6, 8],
      [7, 9],
      [4, 8],
      [0, 3, 9],
      [],
      [0, 1, 7],
      [2, 6],
      [1, 3],
      [2, 4]
    ]
    def dp(k, n):
      if n == 0:
        return 1
      if n == 1:
        return len(choices[k])
      if (k, n) not in d:
        d[(k, n)] = sum([dp(nxt, n-1) for nxt in choices[k]])
      return d[(k, n)]
    return sum([dp(v, N-1) for v in range(10)]) % (10**9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        
        cell2jump = dict()
        cell2jump[1] = [6, 8]
        cell2jump[2] = [7, 9]
        cell2jump[3] = [4, 8]
        cell2jump[4] = [3, 9, 0]
        cell2jump[5] = []
        cell2jump[6] = [1, 7, 0]
        cell2jump[7] = [2, 6]
        cell2jump[8] = [1, 3]
        cell2jump[9] = [2, 4]
        cell2jump[0] = [4, 6]
        
        # dp[n, i] = helper(n, i)
        dp = defaultdict()
        
        def helper(num_jumps, cell):
            # return number of jumps if place at cell and have num_jumps remaining
            if num_jumps == 1:
                return 1
            elif num_jumps == 2:
                return len(cell2jump[cell])
    
            if (num_jumps, cell) in dp:
                return dp[num_jumps, cell]
            
            res = 0
            for nei in cell2jump[cell]:
                res += helper(num_jumps-1, nei)
            
            dp[num_jumps, cell] = res
            return res
        
        total = []
        for i in range(10):
            total.append(helper(n, i))

    
        return sum(total) % (10**9 + 7)


from functools import lru_cache

class Solution:
    def knightDialer(self, n: int) -> int:
        to = { 0: (4, 6), 1: (6, 8), 2: (7, 9), 3: (4, 8), 4: (0, 3, 9), 5: (), 6: (0, 1, 7), 7: (2, 6), 8: (1, 3), 9: (2, 4) }
        
        @lru_cache(maxsize=None)
        def dfs(i: int, k: int) -> int:
            if i not in to: return 0
            if k == 1: return 1
            return sum([dfs(t, k-1) for t in to[i]])
        return sum([dfs(i, n) for i in range(10)]) % (10**9 + 7)

class Solution:
    
    def knightDialer(self, N: int) -> int:
            
        mod= (10**9)+7
        def getNeighbors(N):
            neighs=[[4,6],[6,8],[7,9],[4,8],[0,3,9],[],[0,1,7],[2,6],[1,3],[2,4]]
            return neighs[N]
        
        def getCount(start,n):
            
            if (start,n) not in dic:
                
                if n==0:
                    dic[(start,n)]=1
                else:
                    count=0
                    for nei in  getNeighbors(start):
                        count+=getCount(nei,n-1)
                    dic[(start,n)]=count
                        
            return dic[(start,n)]
                    
                
                
        dic={}
        val=0
        for i in range(10):
            val+=getCount(i,N-1)
            
        return val%mod

from functools import lru_cache


class Solution:
    def knightDialer(self, N: int) -> int:
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]
        
        @lru_cache(maxsize=None)
        def dfs(s, n):
            if n == 0:
                return 1
            # for v in moves[s]:
            return sum([dfs(v, n-1) for v in moves[s]])
            
        answer = 0
        for i in range(10):
            answer += dfs(i, N-1)
            answer %= 10 ** 9 + 7
            
        return answer % (10 ** 9 + 7)

class Solution:
    def knightDialer(self, N: int) -> int:
        parent_child_dict = {0: [4, 6], 1: [6, 8], 2: [7, 9], 3: [4, 8], 4: [3, 9, 0], 5: [], 6: [1, 7, 0], 7: [2, 6], 8: [1, 3], 9: [2, 4]}
        
        dp = [[0] * 10 for _ in range(N)]
        for j in range(10):
            dp[0][j] = 1
            
        for i in range(N - 1):
            for j in range(10):
                children = parent_child_dict[j]
                for child in children:
                    dp[i + 1][child] += dp[i][j]
                dp[i][j] = dp[i][j] % (10 ** 9 + 7)
        
        return sum(dp[N - 1]) % (10 ** 9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
#         board = [[str(j) for j in (1 + 3*i, 3*i + 2, 3*i + 3)] for i in range(3)]
#         board.append(['*', '0', '#'])
#         direct = [(-2, -1), (-2, 1), (-1, -2), (-1, 2), (1, -2), (1, 2), (2, -1), (2, 1)]
        
#         dp = {}
#         def dfs(i, j, step):
           
#             if i < 0 or i > 3 or j < 0 or j > 2: return 0
#             if board[i][j] in '*#': return 0
#             if step == 1: return 1
#             key = (board[i][j], step)
#             if key in dp: return dp[key]
#             dest = set([(i + dr, j + dc) for  dr, dc in direct])
#             dp[key] = sum([dfs(r, c, step - 1) for r, c in dest])
#             return dp[key]
        
#         res = 0
#         for i in range(10):
#             res += dfs(str(i), n)
#         return res%(10**9 + 7)
        dp  = {}
        def nextStep(k):
            if k == 1: return [6, 8]
            if k == 2: return [7, 9]
            if k == 3: return [4, 8]
            if k == 4: return [9, 3, 0]
            if k == 6: return [7,1,0]
            if k == 7: return [6,2]
            if k == 8: return [1,3]
            if k == 9: return [4,2]
            if k == 0: return [4, 6]
            
        def dfs(k, step):
            if k == 5 and step > 1: return 0
            if step == 1: return 1
            key = (k, step)
            if key in dp: return dp[key]
            dp[key] = sum([dfs(e, step - 1) for e in nextStep(k)])  
            return dp[key]
        res = 0
        for i in range(10):
            # if i ==5:continue
            res += dfs(i, n)
        return res%(10**9 + 7)
            


class Solution:
    def knightDialer(self, n: int) -> int:
        dp = {i:1 for i in range(10)}
        mod = 10**9+7
        for _ in range(1, n):
            dp2 = {}
            dp2[0] = (dp[4]+dp[6])%mod
            dp2[1] = (dp[6]+dp[8])%mod
            dp2[2] = (dp[7]+dp[9])%mod
            dp2[3] = (dp[4]+dp[8])%mod
            dp2[4] = (dp[0]+dp[3]+dp[9])%mod
            dp2[5] = 0
            dp2[6] = (dp[0]+dp[1]+dp[7])%mod
            dp2[7] = (dp[2]+dp[6])%mod
            dp2[8] = (dp[1]+dp[3])%mod
            dp2[9] = (dp[2]+dp[4])%mod
            dp = dp2
            
        return sum(dp.values())%mod

NEIGHBORS_MAP = {
    1: (6, 8),
    2: (7, 9),
    3: (4, 8),
    4: (3, 9, 0),
    5: tuple(),  # 5 has no neighbors
    6: (1, 7, 0),
    7: (2, 6),
    8: (1, 3),
    9: (2, 4),
    0: (4, 6),
}


def neighbors(position):
    return NEIGHBORS_MAP[position]


class Solution:
    def knightDialer(self, num_hops):
        cache = {}
        mod = 10**9 + 7

        def helper(position, num_hops):
            if (position, num_hops) in cache:
                return cache[(position, num_hops)]
            if num_hops == 0 or num_hops == 1:
                return 1
            num_sequences = 0
            for neighbor in neighbors(position):
                num_sequences += helper(neighbor, num_hops - 1)
            cache[(position, num_hops)] = num_sequences
            # print(cache)
            return num_sequences

        res = 0
        for i in range(0, 10):
            res += helper(i, num_hops)
        # print(res, cache)
        return res % mod


class Solution:
    def knightDialer(self, n: int) -> int:
        Mod = 10**9+7
        dirs = [(-2,-1),(-2,1),(-1,-2),(-1,2),(1,-2),(1,2),(2,-1),(2,1)]
        dp = [[1]*3 for _ in range(4)]
        dp[3][0] = 0
        dp[3][2] = 0
        
        for k in range(1,n):
            temp = [[0]*3 for _ in range(4)]
            for i in range(4):
                for j in range(3):
                    if i == 3 and j != 1: continue 
                    for x, y in dirs:
                        nx = i+x
                        ny = j+y
                        if nx<0 or nx>=4 or ny<0 or ny>=3: continue
                        temp[i][j] = (temp[i][j] + dp[nx][ny])%Mod
            dp = temp[:]
        
        print(dp)
        ans = 0
        for i in range(4):
            for j in range(3):
                ans = (ans + dp[i][j])%Mod
        return ans 

class Solution:
    def knightDialer(self, n: int) -> int:
        modulo = pow(10,9)  + 7
        def get_position(pos):
            _map= {0: [4, 6],
                    1: [8, 6],
                    2: [7, 9],
                    3: [4, 8],
                    4: [3, 9, 0],
                    5: [],
                    6: [1,7,0],
                    7: [2,6],
                    8: [1,3],
                    9: [4,2],
                   }
            return _map[pos]
        cache = {}
        def solve(pos, step):
            key = (pos, step)
            if key not in cache:
                if step>=n:
                    return 1
                res = 0
                for i in get_position(pos):
                    res += solve(i, step + 1)
                    res = res % modulo
                cache[key] = res
            return cache[key]
        res = 0
        
        for i in range(10):
            res += solve(i, 1)
        return res % modulo

class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 1: return 10
        self.mod = 1e9 + 7
        self.cache = {}
        self.knight_steps = {
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [0, 3, 9],
            5: [],
            6: [1, 7, 0],
            7: [2, 6],
            8: [1, 3],
            9: [2, 4],
            0: [4, 6]
        }
        count = 0
        for i in range(10):
            count += self.recursive_calc(i, n - 1) 
            count = count % self.mod
            
        # print(self.cache)
        return int(count % self.mod)
        
    
    def recursive_calc(self, current_number, steps):
        if steps == 0: return 1
        if (current_number, steps) in self.cache:
            return self.cache[(current_number, steps)]
        total = 0
        for i in self.knight_steps[current_number]:
            total += self.recursive_calc(i, steps - 1)
            total = total % self.mod
        self.cache[(current_number, steps)] = total
        return self.cache[(current_number, steps)]

class Solution:
    def knightDialer(self, n: int) -> int:
        # https://blog.csdn.net/fuxuemingzhu/article/details/83716573
        self.ans = dict()
        self.ans[0] = 10
        board = [[1] * 3 for _ in range(4)]
        board[3][0] = board[3][2] = 0
        pre_dict = {(i, j) : self.prevMove(i, j) for i in range(4) for j in range(3)}
        for n in range(1, n):
            new_board = copy.deepcopy(board)
            for i in range(4):
                for j in range(3):
                    cur_move = 0
                    for x, y in pre_dict[(i, j)]:
                        cur_move = (cur_move + board[x][y]) % (10 ** 9 + 7)
                    new_board[i][j] = cur_move
            board = new_board
        return sum([board[i][j] for i in range(4) for j in range(3)]) % (10 ** 9 + 7)
        
    def prevMove(self, i, j):
        if (i, j) == (3, 0) or (i, j) == (3, 2):
            return []
        directions = [(-2, 1), (-1, 2), (1, 2), (2, 1), (2, -1), (1, -2), (-1, -2), (-2, -1)]
        res = []
        for d in directions:
            x, y = i + d[0], j + d[1]
            if 0 <= x < 4 and 0 <= y < 3 and (x, y) != (3, 0) and (x, y) != (3, 2):
                res.append((x, y))
        return res


from functools import lru_cache

class Solution:
    def knightDialer(self, N: int) -> int:
        @lru_cache(None)
        def _jump(row, col, remaining):
            if remaining == 1:
                return 1
            total = 0
            for dr, dc in (2, 1), (2, -1), (-2, 1), (-2, -1), (1, 2), (1, -2), (-1, 2), (-1, -2):
                if (
                    0 <= row + dr < m and 0 <= col + dc < n and pad[row + dr][col + dc]
                ):
                    total += _jump(row + dr, col + dc, remaining - 1)
            return total % MAX

        MAX = 10**9 + 7
        pad = [
            [1, 1, 1],
            [1, 1, 1],
            [1, 1, 1],
            [0, 1, 0]
        ]
        m, n = len(pad), len(pad[0])
        total = 0
        for i in range(m):
            for j in range(n):
                if pad[i][j]:
                    total += _jump(i, j, N)
        return total % MAX

class Solution:  
    def knightDialer(self, N: int) -> int:
        total = 0
        places = {1:[6,8], 2:[7,9], 3:[4,8], 4:[3,9,0], 6:[1,7,0], 7:[2,6], 8:[1,3], 9:[2,4], 0: [4,6]}
        if N == 1:
            return 10
        dp = [1]*10
        for i in range(2, N+1):
            tmp_dp = [0]*10
            for i in range(0, 10):
                
                if i != 5:
                    neighbors = places.get(i)
                    curr = 0
                    for n in neighbors:
                        curr += dp[n]
                    tmp_dp[i] = curr
            dp = copy.deepcopy(tmp_dp)
        
        return sum(dp) % (10**9 + 7)
                    
                
        


class Solution:
    def __init__(self):
        self.memory = {}
    def knightDialer(self, n: int) -> int:
        steps = {
            0: [4,6],
            1: [6,8],
            2: [7,9],
            3: [4,8],
            4: [0,9,3],
            5: [],
            6: [7,1,0],
            7: [2,6],
            8: [1,3],
            9: [2,4]
        }
        def kDialer(i, n, steps,c):
            if n==1:
                return 1
            if n==0:
                return 0
            if (i, n) in self.memory:
                return self.memory[(i, n)]
            self.memory[(i, n)] = 0
            for j in steps[i]:
                self.memory[(i, n)]+= kDialer(j, n-1, steps,c)%c
            self.memory[(i, n)] = self.memory[(i, n)]%c
            return self.memory[(i, n)]
        
        combinations = 0
        for i in range(0, 10):
            combinations+=kDialer(i, n, steps, (10**9) + 7)%((10**9) + 7)
        
        return combinations%((10**9) + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        dp = {(0,0):1, (0,1):1, (0,2):1, 
              (1,0):1, (1,1):1, (1,2):1, 
              (2,0):1, (2,1):1, (2,2):1, 
              (3,1):1}
        for x in range(1, n):
            temp = {}
            for r in range(4):
                for c in range(3):
                    if (r == 3 and c == 0) or (r==3 and c == 2):
                        continue
                    sm = 0
                    for i in (1,-1):
                        for j in (2, -2):
                            sm = sm + dp.get((r+i, c+j), 0) + dp.get((r+j, c+i), 0)
                    temp[(r,c)] = sm
            dp = temp
        return sum(dp.values())%(10**9 + 7)      


from functools import reduce

def make_grid():
    g = [[1] * 3 for _ in range(4)]
    g[3][0] = None
    g[3][2] = None
    return g

MOVES = [
    (2, 1),
    (2, -1),
    (1, 2),
    (1, -2),
    (-1, 2),
    (-1, -2),
    (-2, 1),
    (-2, -1),
] 

# def jump(grid):
#     for i in range(4):
#         for j in range(3):
#             if grid[i][j] is not None:
#                 for di, dj in MOVES:
#                     ni = i+di
#                     nj = j+dj
#                     if (0 <= ni < 4) and (0 <= nj < 3) and (grid[ni][nj] is not None):
#                         grid[ni][nj] += 1
                
def jump(grid):
    new_grid = make_grid()
    for i in range(4):
        for j in range(3):
            if grid[i][j] is not None:
                c = 0
                for di, dj in MOVES:
                    ni = i+di
                    nj = j+dj
                    if (0 <= ni < 4) and (0 <= nj < 3) and (grid[ni][nj] is not None):
                        #grid[ni][nj] += 1
                        c += grid[ni][nj]
                new_grid[i][j] = c
    return new_grid
                

class Solution:
    def knightDialer(self, n: int) -> int:
        
        grid = make_grid()
        m = 10**9 + 7
        
        c = 0
        for _ in range(n-1):
            grid = jump(grid)
            c += 10
        
        print(grid)
        
        return sum([sum([c for c in row if c]) for row in grid]) % m#- c
        #for _ in range(n):
        #    jump(grid)
        #
        #return reduce(list.__add__, [[c for c in row] for row in grid])


class Solution:
    def knightDialer(self, n: int) -> int:
        limit = 10**9+7
        # print(limit)
        direction = [(1,2),(-1,2),(1,-2),(-1,-2),(2,-1),(2,1),(-2,1),(-2,-1)]
        dp = [[1 for i in range(3)] for j in range(4)]
        dp[3][0],dp[3][2] = 0,0
        for i in range(n-1):
            temp = [[0 for i in range(3)] for j in range(4)]
            for i in range(4):
                for j in range(3):
                    if i ==3 and j !=1:
                        continue
                    for di,dj in direction:
                        new_i,new_j = di+i,dj+j
                        if 0<=new_i<4 and 0 <= new_j <3:
                            temp[i][j] = (temp[i][j] + dp[new_i][new_j])%limit
            dp = temp[:]
        res = 0
        for i in range(4):
            for j in range(3):
                res+=dp[i][j]
        return res%limit


class Solution:
    def knightDialer(self, n: int) -> int:
        limit = 10**9+7
        dp = [[1 for i in range(3)] for j in range(4)]
        dp[3][0],dp[3][2] = 0,0
        direction = [(1,2),(-1,2),(1,-2),(-1,-2),(2,-1),(2,1),(-2,1),(-2,-1)]
        for k in range(n-1):
            temp = [[0 for i in range(3)] for j in range(4)]
            for i in range(4):
                for j in range(3):
                    if i == 3 and j != 1:
                        continue
                    for di,dj in direction:
                        new_i,new_j = di+i,dj+j
                        if 0<= new_i< 4 and 0<= new_j<3:
                            temp[i][j] = (temp[i][j]+dp[new_i][new_j])%limit
            dp = temp[:]
        res = 0
        for i in range(4):
            for j in range(3):
                res+= dp[i][j]
        return res%limit

class Solution:
    dic = {}
    dic[1] = [6,8]
    dic[2] = [7,9]
    dic[3] = [4,8]
    dic[4] = [0,3,9]
    dic[5] = []
    dic[6] = [0,1,7]
    dic[7] = [2,6]
    dic[8] = [1,3]
    dic[9] = [2,4]
    dic[0] = [4,6]
    
    
    
    def knightDialer(self, n: int) -> int:
        mem = defaultdict(int)
        
        for j in range(10):
            mem[(1,j)] = 1
        
        for i in range(1,n):
            for j in range(10):
                for num in self.dic[j]:
                    mem[(i+1,num)] += mem[(i,j)]
                    mem[(i+1,num)] = mem[(i+1,num)] %(10**9+7)
        
        res = 0
                
        for i in range(10):
            res += mem[(n,i)]
            res = res%(10**9+7)
        
        return res

class Solution:
    def knightDialer(self, N: int) -> int:
        MOD = 10**9 + 7
        # dp = [ [[0]*3 for _2 in range(4)]   for _ in range(N)]
        dp = [[0]*3 for _2 in range(4)]
        for i in range(4):
            for j in range(3):
                if (i,j) in [(3,0),(3,2)]:
                    continue
                dp[i][j] = 1
        
        for k in range(1,N):
            new_dp = [[0]*3 for _2 in range(4)]
            for i in range(3):
                for j in range(i,3):
                    # print(i,j)
                    a = [[i+2,j+1],[i+2,j-1],[i-2,j+1],[i-2,j-1],
                         [i+1,j+2],[i-1,j+2],[i+1,j-2],[i-1,j-2]]
                    for p in a:
                        if not(0 <= p[0] < 4) or not(0 <= p[1] < 3):
                            continue
                        new_dp[i][j] += dp[p[0]][p[1]] % MOD
                        # new_dp[j][i] = new_dp[i][j]
            new_dp[1][0] = new_dp[1][2]
            new_dp[2][0] = new_dp[2][2]
            new_dp[2][1] = new_dp[0][1]
            i = 3
            j = 1
            new_dp[3][1] = (dp[1][2] + dp[1][0]) % MOD
            dp = new_dp
            # print(dp)
            
        s = 0
        # dp[3][0] = dp[N-1][3][2] = 0
        for i in dp:
            for j in i:
                s += j % MOD
        return s % MOD
    
        
        # cac = {}
        # MOD = 10**9 + 7
        # def d(k,i,j):
        #     try:
        #         return cac[(k,i,j)]
        #     except:
        #         pass
        #     if (i,j) in [(3,0),(3,2)]:
        #         return 0
        #     if not(0 <= i < 4) or not(0 <= j < 3):
        #         return 0
        #     if k == 0:
        #         return 1
        #     temp = 0
        #     temp += d(k-1,i+2,j+1) % MOD
        #     temp += d(k-1,i+2,j-1) % MOD
        #     temp += d(k-1,i-2,j+1) % MOD
        #     temp += d(k-1,i-2,j-1) % MOD
        #     temp += d(k-1,i+1,j+2) % MOD
        #     temp += d(k-1,i-1,j+2) % MOD
        #     temp += d(k-1,i+1,j-2) % MOD
        #     temp += d(k-1,i-1,j-2) % MOD
        #     cac[(k,i,j)] = temp
        #     return temp
        # ans = 0
        # for i in range(4):
        #     for j in range(3):
        #         ans += d(N-1,i,j) % MOD
        # return ans % MOD


class Solution:
    def __init__(self):
        self.moves = [ 
            [4,6],
            [8,6],
            [7,9],
            [4,8],
            [9,3,0],
            [],
            [7,1,0],
            [6,2],
            [1,3],
            [2,4],
        ]
        
        self.memoized_results= {}
    
    def knightDialer(self, n: int) -> int:
        total_moves = 0
        for number in range(10):
            moves = self.knightDialerOnOneDigit(number, n-1)
            total_moves += moves
        return(total_moves%(pow(10,9) +7))
        
    
    def knightDialerOnOneDigit(self, current_number, remaining_moves):
        if remaining_moves == 0:
            return 1
        
        moves = 0
        for number in self.moves[current_number]:
            if (number, remaining_moves-1) in list(self.memoized_results.keys()):
                new_moves = self.memoized_results[(number, remaining_moves-1)]
            else:
                new_moves = self.knightDialerOnOneDigit(number, remaining_moves-1)
                self.memoized_results[(number, remaining_moves-1)] = new_moves
            moves += new_moves
        return moves
        
        


MOD = 10**9 + 7
class Solution:
    def knightDialer(self, n: int) -> int:
        @lru_cache(None)
        def dfs(i, j, k):
            # base case
            if k == n - 1:
                return 1
            # recursion
            res = 0
            for di, dj in [(-2, -1), (-2, 1), (2, -1), (2, 1), (-1, -2), (-1, 2), (1, -2), (1, 2)]:
                ni, nj = i + di, j + dj
                if not (0 <= ni < 4 and 0 <= nj < 3):
                    continue
                if (ni, nj) in [(3, 0), (3, 2)]:
                    continue
                res += dfs(ni, nj, k + 1)
                res %= MOD
            return res
    
        ans = 0
        for i, j in product(range(4), range(3)):
            if (i, j) in [(3, 0), (3, 2)]:
                    continue
            ans += dfs(i, j, 0)
        return ans % MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        M = 4
        N = 3
        KMOD = 10 ** 9 + 7
        dp = [[1 for _ in range(N)] for _ in range(M)] # init as 1 for 0/1 hops
        dp[3][0] = dp[3][2] = 0
        directions = [(1, 2), (-1, -2), (1, -2), (-1, 2),
                      (2, 1), (-2, -1), (2, -1), (-2, 1), ]
        for _ in range(1, n): # starts from 1 hop
            cur = [[0 for _ in range(N)] for _ in range(M)] # cur init as 0
            for i in range(M):
                for j in range(N):
                    if i == 3 and (j == 0 or j == 2):
                        continue
                    for d in directions:
                        x = i + d[0]
                        y = j + d[1]
                        if 0 <= x < M and 0 <= y < N:
                            cur[i][j] += dp[x][y]
            dp = cur
        result = 0
        for i in range(M):
            for j in range(N):
                if i == 3 and (j == 0 or j == 2):
                    continue
                result += dp[i][j]
        return result % KMOD

class Solution:
    def knightDialer(self, N: int) -> int:
        d = [1 for n in range(10)]
        for i in range(N - 1):
            (d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9]) = (
                d[4] + d[6], d[6] + d[8], d[7] + d[9], d[4] + d[8], d[0] + d[3] + d[9],
                0, d[0] + d[1] + d[7], d[2] + d[6], d[1] + d[3], d[2] + d[4])
        return sum(d) % (10 ** 9 + 7)        


class Solution:
    def knightDialer(self, N: int) -> int:
        if N == 0:
            return 0
        
        dialer = [[1, 1, 1] for _ in range(4)]
        directions = [[-1, 2], [-2, 1], [-2, -1], [-1, -2], [1, -2], [2, -1], [2, 1], [1, 2]]
        forbidden = set()
        forbidden.add((3, 0))
        forbidden.add((3, 2))
        for _ in range(1, N):
            tmp = [[0, 0, 0] for _ in range(4)]
            for i in range(4):
                for j in range(3):
                    if (i, j) not in forbidden:
                        for direction in directions:
                            new_i, new_j = i + direction[0], j + direction[1]
                            if 0 <= new_i < 4 and 0 <= new_j < 3:
                                tmp[new_i][new_j] += dialer[i][j]
            dialer = tmp
            
        
        return (sum(sum(dialer, [])) - dialer[3][0] - dialer[3][2]) % (10 ** 9 + 7)
        
        


class Solution:
    def knightDialer(self, n: int) -> int:
        valid = {
            1: [8, 6],
            2: [7, 9],
            3: [4, 8],
            4: [3, 9, 0],
            5: [],
            6: [1, 7, 0],
            7: [2, 6],
            8: [1, 3],
            9: [4, 2],
            0: [4, 6]
        }
        
        MOD = 10 ** 9 + 7
        dp = {}
        nums = 0
        
        def dfs(pos, steps):
            if steps == 0:
                return 1
            if (pos, steps,) in dp:
                return dp[(pos, steps,)]
            c = 0
            for next in valid[pos]:
                x = dfs(next, steps - 1)
                dp[(next, steps - 1)] = x
                c += x
                c %= MOD
            dp[(pos, steps,)] = c
            return c
        
        ans = 0
        for i in range(10):
            x = dfs(i, n - 1)
            ans += x
            ans %= MOD
        return ans % MOD


class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10**9 + 7
        dp = [1 for _ in range(10)]
        
        move = [[4,6], [6,8], [7,9], [4,8], [3,9,0], [], [1,7,0], [2,6], [1,3], [4,2]]
        for i in range(n-1):
            dp2 = [0] *10
            for node, count in enumerate(dp):
                for nei in move[node]:
                    dp2[nei] += count
                    dp2[nei] %MOD
            dp = dp2
        print(dp)
        return sum(dp)%MOD

class Solution(object):
    def knightDialer(self, N):
        # Use This Code
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]
        MOD = 10**9 + 7
        
        table = [1]*10 # table[i] = number of way ending in i
        for _ in range(N-1):
            temp = [0] * 10
            for node, count in enumerate(table):
                for nei in moves[node]:
                    temp[nei] += count
                    temp[nei]%MOD
            table = temp
            
        return sum(table)%MOD


class Solution:
    def knightDialer(self, n: int) -> int:
        moves = [(-2, 1),(-1, 2),(1,2),(2,1),(2,-1),(1,-2),(-1,-2),(-2,-1)]
        
        previous = {(r, c): 1 for r, c in ((0,0),(0,1),(0,2),(1,0),(1,1),(1,2),(2,0),(2,1),(2,2),(3,1))}
        current = {(r, c): 0 for r, c in previous}
        
        for i in range(n-1):
            for (r, c), v in previous.items():
                for dr, dc in moves:
                    if (r+dr, c+dc) in current:
                        current[(r+dr, c+dc)] += v
                        current[(r+dr, c+dc)] %= 1000000007
            previous = current
            current = {(r, c): 0 for r, c in previous}
                        
        return sum(previous.values()) % 1000000007

class Solution:
    def knightDialer(self, n: int) -> int:
        keyboard = [[0] * 3 for _ in range(4)]
        k = 1
        for i in range(3):
            for j in range(3):
                keyboard[i][j] = k
                k+=1
        keyboard[-1][0] = -1
        keyboard[-1][-1] = -1
        
        mod = 10**9 + 7
        count = [[1] * 3 for _ in range(4)]
        count[-1][0] = 0
        count[-1][-1] = 0
        moves = [(2,1),(2,-1),(-2,1),(-2,-1),(1,2),(-1,2),(1,-2),(-1,-2)]
        for k in range(n - 1):
            tmp_count = [[0] * 3 for _ in range(4)]
            for i in range(4):
                for j in range(3):
                    if keyboard[i][j] < 0 :
                        continue
                    for mv in moves:
                        x = i + mv[0]
                        y = j + mv[1]
                        if 0<=x<4 and 0<=y<3 and keyboard[x][y]>=0:
                            tmp_count[x][y] = (tmp_count[x][y] + count[i][j]) % mod
                            
            count = tmp_count
        num_count = 0
        for r in count:
            num_count = (num_count + sum(r)) % mod
        return num_count 

class Solution:
    mod = 10 ** 9 + 7
    phone = [[1,1,1],[1,1,1],[1,1,1],[0,1,0]]
    moves = ((2,1),(1,2),(2,-1),(1,-2),(-2,1),(-1,2),(-2,-1),(-1,-2))
    def knightDialer(self, n: int) -> int:
        # memo = {}
        @lru_cache(None)
        def helper(row, col, left):
#             if (row,col,left) in memo:
#                 return memo[(row,col,left)]
                
            # if not 0<=row<=3 or not 0<=col<=2 or Solution.phone[row][col] ==0:
            #     return 0
            if left <= 0:
                return 1
            ans = 0
            for r,c in Solution.moves:
                if 0<=row+r<=3 and 0<=col+c<=2 and Solution.phone[row+r][col+c] ==1:
                    ans += helper(row+r,col+c,left-1)
            # memo[(row,col,left)] = ans
            return ans
        
        ans = 0
        for row in range(4):
            for col in range(3):
                if Solution.phone[row][col] == 1:
                    ans += helper(row, col, n-1)
        
        return ans % Solution.mod

class Solution:
    def knightDialer(self, n: int) -> int:
        
        cell2jump = dict()
        cell2jump[1] = [6, 8]
        cell2jump[2] = [7, 9]
        cell2jump[3] = [4, 8]
        cell2jump[4] = [3, 9, 0]
        cell2jump[5] = []
        cell2jump[6] = [1, 7, 0]
        cell2jump[7] = [2, 6]
        cell2jump[8] = [1, 3]
        cell2jump[9] = [2, 4]
        cell2jump[0] = [4, 6]
        
        # dp[n, i] = helper(n, i)
        dp = defaultdict()
        
        def helper(num_jumps, cell):
            # return number of jumps if place at cell and have num_jumps remaining
            if num_jumps == 0:
                return 1
            elif num_jumps == 1:
                return len(cell2jump[cell])
            
            if (num_jumps, cell) in dp:
                return dp[num_jumps, cell]
            
            res = 0
            for nei in cell2jump[cell]:
                res += helper(num_jumps-1, nei)
            
            dp[num_jumps, cell] = res
            return res
        
        total = []
        for i in range(10):
            total.append(helper(n-1, i))

    
        return sum(total) % (10**9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
        if n ==1:return 10
        f1,f2,f3,f4,f6,f7,f8,f9,f0 = [1]*n,[1]*n,[1]*n,[1]*n,[1]*n,[1]*n,[1]*n,[1]*n,[1]*n
        
        for j in range(1,n):
            f0[j] = (f4[j-1]+f6[j-1])%(1e9+7)
            f1[j] = (f6[j-1]+f8[j-1])%(1e9+7)
            f2[j] = (f7[j-1]+f9[j-1])%(1e9+7)
            f3[j] = (f4[j-1]+f8[j-1])%(1e9+7)
            f4[j] = (f3[j-1]+f9[j-1]+f0[j-1])%(1e9+7)
            f6[j] = (f1[j-1]+f7[j-1]+f0[j-1])%(1e9+7)
            f7[j] = (f6[j-1]+f2[j-1])%(1e9+7)
            f8[j] = (f1[j-1]+f3[j-1])%(1e9+7)
            f9[j] = (f2[j-1]+f4[j-1])%(1e9+7)
        
        # res = 2*(f0[n]+f1[n]+f2[n]+f3[n]+f7[n]+f8[n]+f9[n])+3*(f4[n]+f6[n])
        res = f0[n-1]+f1[n-1]+f2[n-1]+f3[n-1]+f7[n-1]+f8[n-1]+f9[n-1]+f4[n-1]+f6[n-1]
        return int(res%(1e9+7))

class Solution:
    def knightDialer(self, n: int) -> int:
        N = n
        transition = {1:[6,8],
        2:[7,9],
        3:[4,8],
        4:[3,9,0],
        5:[],
        6:[1,7,0],
        7:[2,6],
        8:[1,3],
        9:[2,4],
        0:[4,6]}
        # key:cur position
        # value: next position
        self.count = 0
        self.mem = {}
        
        def dfs(cur,steps):
            if steps==2:
                #self.count+=len(transition[cur])
                return len(transition[cur])
            else:
                tmp = 0
                if (cur,steps) in self.mem:
                    return self.mem[(cur,steps)]
                
                for neigh in transition[cur]:
                    tmp +=dfs(neigh,steps-1)
                    #print(tmp)
                self.mem[(cur,steps)] = tmp
                
                return self.mem[(cur,steps)]
        
        if N==1:
            return 10
        
        for i in range(10):
            self.count+=dfs(i,N)
        
        return self.count%(10**9+7)
    
#         if n==1:
#             return 10
        
#         jump = {0:[4,6],
#                 1:[6,8],
#                2:[7,9],
#                3:[4,8],
#                4:[3,9,0],
#                5:[],
#                6:[1,7,0],
#                7:[2,6],
#                8:[1,3],
#                9:[2,4]}
        
#         def get(n,d):
#             if n==1:
#                 s = 0
#                 for key in d.keys():
#                     s+=d[key]
                    
#                 return s%(10**9+7)
#             new_d = collections.defaultdict(int)
#             for key in d.keys():
#                 nexts = jump[key]
#                 for next in nexts:
#                     new_d[next]+=d[key]
            
#             return get(n-1,new_d)
#         count = 0
#         for i in range(10):
#             d = collections.defaultdict(int)
#             d[i]=1
#             count+=get(n,d)
            
#         return count%(10**9+7)


class Solution:
    def knightDialer(self, n: int) -> int:
        def dp(cur: int, k: int, cache: dict) -> int:
            state = tuple([cur, k])
            if state in cache:
                return cache[state]
            
            if k==0:
                return 1
            
            dic = [[4,6],[6,8],[7,9], [4,8], [0,3,9],[], [0,1,7],[2,6], [1,3], [2,4]]
            res = 0
            for nc in dic[cur]:
                res += dp(nc, k-1, cache)
            
            cache[state] = res
            return cache[state]
        
        result = 0
        cache = {}
        mod = 10**9 + 7
        for i in range(10):
            result += dp(i, n-1, cache)
            result = result%mod
        
        return result%(mod)

class Solution:
    def knightDialer(self, n: int) -> int:
        memo = {}
        return sum(self.hopper(i, n-1, memo) for i in range(10)) % (10 ** 9 + 7)
    
    def hopper(self, cur_ind, hops_left, memo):
        if hops_left == 0:
            return 1
        if (cur_ind, hops_left) in memo:
            return memo[(cur_ind, hops_left)]
        
        counts = 0
        for nbr in self.nbrs(cur_ind):
            res = self.hopper(nbr, hops_left-1, memo)
            counts += res
            memo[(nbr, hops_left-1)] = res
            
        return counts
    
    
    def nbrs(self, ind):
        nbrs = {0: [4,6],
                1: [6, 8],
                2: [9, 7],
                3: [4, 8],
                4: [3, 9, 0],
                5: [],
                6: [1,7, 0],
                7: [6, 2],
                8: [1, 3],
                9: [4, 2]}
        
        return nbrs[ind]


from functools import lru_cache


class Solution:
    def knightDialer(self, N: int) -> int:
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
                     [1,7,0],[2,6],[1,3],[2,4]]
        
        @lru_cache(maxsize=100000)
        def dfs(s, n):
            if n == 0:
                return 1
            # for v in moves[s]:
            return sum([dfs(v, n-1) for v in moves[s]])
            
        answer = 0
        for i in range(10):
            answer += dfs(i, N-1)
            
        return answer % (10 ** 9 + 7)


from functools import reduce
class Solution:
    
    validMoves = {
        0: {4, 6},
        1: {6, 8},
        2: {7, 9},
        3: {4, 8},
        4: {3, 9, 0},
        5: {},
        6: {1, 7, 0},
        7: {2, 6},
        8: {1, 3},
        9: {2, 4}
    }
    
    def knightDialer(self, n: int) -> int:
        cache = {} # from (remainingMoves, location) => numberOfPaths
        
        def reducer(acc: int, x: int) -> int:
            return (acc + x) % 1000000007 #10^9+7
        
        def helper(remainingMoves: int, location: int) -> int:
            depth = n - remainingMoves
            insert = '\\t' * depth
            # print('{}ENTER: at {} with {} remaining'.format('\\t' * (depth - 1), location, remainingMoves))
            
            if remainingMoves == 0:
                # print('{}Ran out of moves in location {}'.format(insert, location))
                return 1
            else:
                if (remainingMoves, location) in cache:
                    answer = cache[(remainingMoves, location)]
                    # print('{}Found ({}, {}) in cache: returning {}'.format(insert, remainingMoves, location, answer))
                    return answer
                else:
                    nextMoves = self.validMoves[location]
                    answers = [helper(remainingMoves - 1, newLocation) for newLocation in nextMoves]
                    reduced = reduce(reducer, answers, 0)
                    cache[(remainingMoves, location)] = reduced
                    # print('{}Calculated ({}, {}) = {}'.format(insert, remainingMoves, location, reduced))
                    return reduced
        
        answers = [helper(n-1, x) for x in range(0, 10)]
        reduced = reduce(reducer, answers, 0)
        return reduced

class Solution:
    def knightDialer(self, n: int) -> int:
        grid = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [-1, 0, -1]]
        R, C = len(grid), len(grid[0])
        dp = [[1] * C for _ in range(R)]
        invalid = set([(3, 0), (3, 2)])
        for r, c in invalid:
            dp[r][c] = 0
        dirs = [
            (2, 1), (-2, 1), (2, -1), (-2, -1),
            (1, 2), (-1, 2), (1, -2), (-1, -2)
        ]
        for _ in range(n - 1):
            dp2 = [[0] * C for _ in range(R)]
            for r, row in enumerate(dp):
                for c, val in enumerate(row):
                    if (r, c) in invalid:
                        continue
                    for dr, dc in dirs:
                        nr, nc = r + dr, c + dc
                        if (nr, nc) in invalid:
                            continue
                        if 0 <= nr < R and 0 <= nc < C:
                            dp2[nr][nc] += val
            dp = dp2
            
        return sum(map(sum, dp)) % (pow(10, 9) + 7)

class Solution:
    def knightDialer(self, N: int) -> int:
        
        m,n = 4,3
        
        
        
        dp = {}
        ans = 0
        for k in range(1,N+1):
            count = 0
            for i in range(m):
                for j in range(n):
                    if i==3 and j in [0,2]: continue
                    
                    temp = 0
                            
                    if 1==k:
                        temp+=1

                    else:
                        for a,b in [(2,1),(2,-1),(-2,1),(-2,-1),(1,2),(1,-2),(-1,2),(-1,-2)]:
                            r,c =i+a, j+b
                            if 0<=r<m and 0<=c<n and (r,c) not in [(3,0), (3,2)]:
                                # print(r,c,k-1)
                                temp+=dp[(r,c,k-1)]
                                    
                    dp[(i,j,k)] = temp
                    count+=temp 
            ans = count
        # print(dp)
        return ans%(10**9+7)

class Solution:
    def knightDialer(self, n: int) -> int:
        mod = 10 ** 9 + 7
        phone = [[1,1,1],[1,1,1],[1,1,1],[0,1,0]]
        moves = ((2,1),(1,2),(2,-1),(1,-2),(-2,1),(-1,2),(-2,-1),(-1,-2))
        # memo = {}
        @lru_cache(None)
        def helper(row, col, left):
#             if (row,col,left) in memo:
#                 return memo[(row,col,left)]
                
            if not 0<=row<=3 or not 0<=col<=2 or phone[row][col] ==0:
                return 0
            if left <= 0:
                return 1
            ans = 0
            for r,c in moves:
                if 0<=row+r<=3 and 0<=col+c<=2 and phone[row+r][col+c] ==1:
                    ans += helper(row+r,col+c,left-1)
            # memo[(row,col,left)] = ans
            return ans
        
        ans = 0
        for row in range(4):
            for col in range(3):
                if phone[row][col] == 1:
                    ans += helper(row, col, n-1)
        
        return ans % mod

class Solution:
    def knightDialer(self, n: int) -> int:
#         board = [[str(j) for j in (1 + 3*i, 3*i + 2, 3*i + 3)] for i in range(3)]
#         board.append(['*', '0', '#'])
#         direct = [(-2, -1), (-2, 1), (-1, -2), (-1, 2), (1, -2), (1, 2), (2, -1), (2, 1)]
        
#         dp = {}
#         def dfs(i, j, step):
           
#             if i < 0 or i > 3 or j < 0 or j > 2: return 0
#             if board[i][j] in '*#': return 0
#             if step == 1: return 1
#             key = (board[i][j], step)
#             if key in dp: return dp[key]
#             dest = set([(i + dr, j + dc) for  dr, dc in direct])
#             dp[key] = sum([dfs(r, c, step - 1) for r, c in dest])
#             return dp[key]
        
#         res = 0
#         for i in range(10):
#             res += dfs(str(i), n)
#         return res%(10**9 + 7)

#         dp  = {}
#         def nextStep(k):
#             if k == 1: return [6, 8]
#             if k == 2: return [7, 9]
#             if k == 3: return [4, 8]
#             if k == 4: return [9, 3, 0]
#             if k == 6: return [7,1,0]
#             if k == 7: return [6,2]
#             if k == 8: return [1,3]
#             if k == 9: return [4,2]
#             if k == 0: return [4, 6]
            
#         def dfs(k, step):
#             if k == 5 and step > 1: return 0
#             if step == 1: return 1
#             key = (k, step)
#             if key in dp: return dp[key]
#             dp[key] = sum([dfs(e, step - 1) for e in nextStep(k)])  
#             return dp[key]
#         res = 0
#         for i in range(10):
#             res += dfs(i, n)
#         return res%(10**9 + 7)
    
        dp = [1]*10
        if n == 1: return 10
        for i in range(n-1):
            dpc = dp[:]
            dpc[0] = dp[4] + dp[6]
            dpc[1] = dp[6] + dp[8]
            dpc[2] = dp[7] + dp[9]
            dpc[3] = dp[4] + dp[8]
            dpc[4] = dp[9] + dp[3] + dp[0]
            dpc[5] = 0
            dpc[6] = dp[7] + dp[1] + dp[0]
            dpc[7] = dp[6] + dp[2]
            dpc[8] = dp[1] + dp[3]
            dpc[9] = dp[2] + dp[4]
            dp = dpc
        return sum(dp)%(10**9 + 7)
            


class Solution:
    def knightDialer(self, N: int) -> int:
        dp = [[None] * 10 for _ in range(N + 1)]
        edges = [[1,6], [1,8], [2, 7], [2, 9],
                 [3, 4], [3, 8], [4, 9], [4, 0], 
                 [6, 7], [6, 0]]
        
        graph = {}
        for edge0, edge1 in edges:
            graph[edge0] = graph.get(edge0, []) + [edge1]
            graph[edge1] = graph.get(edge1, []) + [edge0]
            
        def count(n, x):
            if n == 0:
                return 1
            
            if dp[n][x] is not None:
                return dp[n][x]
            
            dp[n][x] = sum([count(n - 1, y) for y in graph.get(x, [])])
            return dp[n][x]
        
        return sum([count(N - 1, x) for x in range(10)]) % (10 ** 9 + 7)


class Solution:
    def knightDialer(self, N: int) -> int:
        arr = [1]*10
        mul = [[0,0,0,0,1,0,1,0,0,0],
               [0,0,0,0,0,0,1,0,1,0],
               [0,0,0,0,0,0,0,1,0,1],
               [0,0,0,0,1,0,0,0,1,0],
               [1,0,0,1,0,0,0,0,0,1],
               [0,0,0,0,0,0,0,0,0,0],
               [1,1,0,0,0,0,0,1,0,0],
               [0,0,1,0,0,0,1,0,0,0],
               [0,1,0,1,0,0,0,0,0,0],
               [0,0,1,0,1,0,0,0,0,0]]
        for n in range(N-1):
            newarr = [0]*10
            for i in range(10):
                for j in range(10):
                    newarr[i] += mul[i][j]*arr[j]
                    newarr[i] %= 10**9+7
            arr = newarr
        s = 0
        for x in arr:
            s = (s+x)%(10**9+7)
        return s

class Solution:
    def knightDialer(self, N: int) -> int:
        d = {(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2), (3, 1)}
        dirs = [(-2, -1), (-2, 1), (2, -1), (2, 1), (-1, 2), (1, 2), (-1, -2), (1, -2)]
        m = 10**9 + 7
        dp = {}
        for x in d:
            dp[x] = [0] * (N + 1)
            dp[x][1] = 1

        for n in range(2, N + 1):
            for r, c in d:
                for z in dirs:
                    rz, cz = r + z[0], c + z[1]
                    if (rz, cz) in d:
                        dp[(r, c)][n] = (dp[(r, c)][n] + dp[(rz, cz)][n - 1]) %m
        return sum(x[N] for x in dp.values()) % m

class Solution:
    def knightDialer(self, N: int) -> int:
        
        m,n = 4,3
        
        dp = {}
        ans = 0
        for k in range(1,N+1):
            count = 0
            for i in range(m):
                for j in range(n):
                    if i==3 and j in [0,2]: continue
                    
                    temp = 0
                            
                    if 1==k:
                        temp+=1

                    else:
                        for a,b in [(2,1),(2,-1),(-2,1),(-2,-1),(1,2),(1,-2),(-1,2),(-1,-2)]:
                            r,c =i+a, j+b
                            if 0<=r<m and 0<=c<n and (r,c) not in [(3,0), (3,2)]:
                                temp+=dp[(r,c,k-1)]
                                    
                    dp[(i,j,k)] = temp
                    count+=temp 
            ans = count%(10**9+7)
        
        return ans

class Solution:
    def knightDialer(self, n: int) -> int:
        @lru_cache(None)
        def dp(i, j, k):
            if k == 0:
                return 1
            result = 0
            for di in [-2, -1, 1, 2]:
                for dj in [3 - abs(di), abs(di) - 3]:
                    ii, jj = i + di, j + dj
                    if 0 <= ii < m and 0 <= jj < n and not (ii == 3 and (jj == 0 or jj == 2)):
                        result = (result + dp(ii, jj, k - 1)) % MOD
            return result
        MOD = 10 ** 9 + 7
        k = n
        m, n = 4, 3
        result = 0
        for i in range(m):
            for j in range(n):
                if i == 3 and (j == 0 or j == 2):
                    continue
                result = (result + dp(i, j, k - 1)) % MOD
        return result

class Solution:
    def knightDialer(self, left: int) -> int:
        moves = [(2,-1),(2,1),(-2,1),(-2,-1),(-1,2),(-1,-2),(1,2),(1,-2)]
        n = 4
        m = 3
        @lru_cache(None)
        def back(i,j,left):
            if left==1:
                return 1
            ans = 0
            for a,b in moves:
                if 0<=i+a<n and 0<=j+b<m and (i+a,j+b)!=(3,0) and (i+a,j+b)!=(3,2):
                    ans+=back(i+a, j+b, left-1)
            return ans
        main = 0
        for i in range(3):
            for j in range(3):
                main+= back(i,j, left)
        main+=back(3, 1,left)
        
        return main%(10**9+7)

class Solution:
    def knightDialer(self, n: int) -> int:
        def get_position(pos):
            _map= {0: [4, 6],
                    1: [8, 6],
                    2: [7, 9],
                    3: [4, 8],
                    4: [3, 9, 0],
                    5: [],
                    6: [1,7,0],
                    7: [2,6],
                    8: [1,3],
                    9: [4,2],
                   }
            return _map[pos]
        cache = {}
        def solve(pos, step):
            key = (pos, step)
            if key not in cache:
                if step>=n:
                    return 1
                res = 0
                for i in get_position(pos):
                    res += solve(i, step + 1)
                    res = res % (pow(10,9)  + 7)
                cache[key] = res
            return cache[key]
        res = 0
        
        for i in range(0, 10):
            res += solve(i, 1)
        return res % (pow(10,9)  + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        
        
        def knightPos(i,j):
            #left top bot
            lt = (i+2,j-1)
            lb = (i-2, j-1)
            #right top bot
            rt = (i+2, j+1)
            rb = (i-2, j+1)
            #top left right
            tl = (i+1, j-2)
            tr = (i+1, j+2)
            #bot left right
            bl = (i-1, j-2)
            br = (i-1, j+2)
            
            return (lt,lb,rt,rb,tl,tr,bl,br)
        
        dp = [[1]*3 for _ in range(4)]
        dp[3][0] = dp[3][2] = 0
        mod = (10**9)+7
        
        for k in range(1,n):
            tmp = [[0]*3 for _ in range(4)]
            for i in range(4):
                for j in range(3):
                    if (i==3 and j==0) or (i==3 and j==2):
                        continue
                    for x,y in knightPos(i,j):
                        if 0 <= x <= 3 and 0 <= y <= 2:
                            tmp[i][j] += dp[x][y]
            dp = tmp
            
        
        return sum([sum(i) for i in dp]) % mod

class Solution:
    @lru_cache(maxsize=None)
    def startFrom(self, i, l):
        if l <= 1:
            return 1 if l == 1 else 0
        else:
            return sum([self.startFrom(j, l-1) for j in self.mapping[i]]) % (10**9+7)
        
    def knightDialer(self, n: int) -> int:
        self.mapping = {1:[6, 8], 2:[7, 9], 3:[4, 8], 4:[3, 9, 0], 5:[], 6:[1,7,0], 7:[2, 6], 8:[1,3], 9:[2, 4], 0:[4, 6]}
        return sum([self.startFrom(i, n) for i in range(10)]) % (10**9+7)

import numpy as np

class Solution:
    def knightDialer(self, N: int) -> int:
        mod = 10**9 + 7
        if N == 1: return 10
        M = np.matrix([[0, 0, 0, 0, 1, 0, 1, 0, 0, 0],
                       [0, 0, 0, 0, 0, 0, 1, 0, 1, 0],
                       [0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
                       [0, 0, 0, 0, 1, 0, 0, 0, 1, 0],
                       [1, 0, 0, 1, 0, 0, 0, 0, 0, 1],
                       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                       [1, 1, 0, 0, 0, 0, 0, 1, 0, 0],
                       [0, 0, 1, 0, 0, 0, 1, 0, 0, 0],
                       [0, 1, 0, 1, 0, 0, 0, 0, 0, 0],
                       [0, 0, 1, 0, 1, 0, 0, 0, 0, 0]])
        
        res = np.matrix([[1]*10])
        N -= 1
        while N:
            if N % 2 != 0: 
                res = res * M % mod                
                N -= 1
            else:
                M = M * M % mod
                N /= 2
        return int(np.sum(res)) % mod


class Solution:
    def knightDialer(self, n: int) -> int:
        ans = [1 for x in range(10)]
        mod = 1000_000_007
        for i in range(n-1):
            ans[0], ans[1], ans[2], ans[3], ans[4], ans[5], ans[6], ans[7], ans[8], ans[9] = ans[4]+ans[6], ans[8]+ans[6], ans[7]+ans[9], ans[8]+ans[4], ans[9]+ans[3]+ans[0], 0, ans[7]+ans[1]+ans[0], ans[6]+ans[2], ans[1]+ans[3], ans[4]+ans[2]
            
        return sum(ans)%mod


class Solution:
    from collections import defaultdict
    def knightDialer(self, N: int) -> int:
        pos_mapping=[[4, 6], [6, 8], [9, 7], [4, 8], [9, 3, 0], [], [7, 1, 0], [6, 2], [1, 3], [4, 2]]

        
        total_count = 0
        for i in range(10):
            prev_arr = [0]*10
            prev_arr[i] = 1
            for ii in range(N - 1):
                new_arr = [0]*10
                for idx,count in enumerate(prev_arr):
                    if count == 0:
                        continue
                    for next_pos in pos_mapping[idx]:
                        new_arr[next_pos] += count
                prev_arr = new_arr
            total_count += sum(prev_arr)
        MOD = 10**9 + 7
        return total_count % MOD

class Solution:
    def knightDialer(self, N: int) -> int:
        dirs = [(2, 1), (1, 2), (2, -1), (1, -2), (-2, -1), (-1, -2), (-2, 1), (-1, 2)]
        dp = [[0 for j in range(N)] for i in range(10)]
        for num in range(10):
            dp[num][0] = 1
        for i in range(1, N):
            for num in range(10):
                if num == 0:
                    pos = (1, 3)
                else:
                    pos = ((num - 1) % 3, (num - 1) // 3)
                x = pos[0]
                y = pos[1]
                for d in dirs:
                    new_x = x - d[0]
                    new_y = y - d[1]
                    if new_x < 0 or new_x > 2 or new_y < 0  or new_y > 3:
                        continue
                    if (new_x == 0 and new_y == 3) or (new_x == 2 and new_y == 3):
                        continue
                    new_num = 0 if (new_x == 1 and new_y == 3) else new_y * 3 + new_x + 1
                    dp[num][i] += dp[new_num][i-1]
        res = 0
        for num in range(10):
            res += dp[num][N-1]
        return res % (pow(10, 9) + 7)


class Solution:
    def helper(self, n, board, row, col, cache):
        if n == 0:
            return 1
        
        if (row, col, n) in cache:
            return cache[(row, col, n)]
        
        rows = len(board)
        cols = len(board[0])
        result = 0
        for rMove, cMove in [(-1, -2), (-2, -1), (2, 1), (1, 2), (-2, 1), (1, -2), (2, -1), (-1, 2)]:
            if 0 <= row + rMove < rows and 0 <= col + cMove < cols and board[row+rMove][col+cMove] not in ['*', '#']:
                result += self.helper(n-1, board, row+rMove, col+cMove, cache)
        
        cache[(row, col, n)] = result
        return result
    
    def knightDialer(self, n: int) -> int:
        board = [
            ['1', '2', '3'],
            ['4', '5', '6'],
            ['7', '8', '9'],
            ['*', '0', '#']
        ]
        
        totalResult = 0
        cache = {}
        rows = len(board)
        cols = len(board[0])
        for r in range(rows):
            for c in range(cols):
                if board[r][c] not in ['*', '#']:
                    totalResult += self.helper(n-1, board, r, c, cache)
        return totalResult % (10**9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        def dp(cur: int, k: int, cache: dict) -> int:
            state = tuple([cur, k])
            if state in cache:
                return cache[state]
            
            if k==0:
                return 1
            
            dic = {
                0: [4,6],
                1: [6,8],
                2: [7,9],
                3: [4,8],
                4: [0,3,9],
                6: [0,1,7],
                7: [2,6],
                8: [1,3],
                9: [2,4]
            }
            res = 0
            for nc in dic.get(cur,[]):
                res += dp(nc, k-1, cache)
            
            cache[state] = res
            return cache[state]
        
        result = 0
        cache = {}
        mod = 10**9 + 7
        for i in range(10):
            result += dp(i, n-1, cache)
        
        return result%(mod)

class Solution:
    mod = 10 ** 9 + 7
    phone = [[1,1,1],[1,1,1],[1,1,1],[0,1,0]]
    moves = ((2,1),(1,2),(2,-1),(1,-2),(-2,1),(-1,2),(-2,-1),(-1,-2))
    def knightDialer(self, n: int) -> int:
        # memo = {}
        @lru_cache(None)
        def helper(row, col, left):
#             if (row,col,left) in memo:
#                 return memo[(row,col,left)]
                
            # if not 0<=row<=3 or not 0<=col<=2 or Solution.phone[row][col] ==0:
            #     return 0
            if left <= 0:
                return 1
            ans = 0
            for r,c in Solution.moves:
                if 0<=row+r<=3 and 0<=col+c<=2 and Solution.phone[row+r][col+c] ==1:
                    ans = (ans + helper(row+r,col+c,left-1)) % Solution.mod
            # memo[(row,col,left)] = ans
            return ans
        
        ans = 0
        for row in range(4):
            for col in range(3):
                if Solution.phone[row][col] == 1:
                    ans = (ans + helper(row, col, n-1)) % Solution.mod
        
        return ans# % Solution.mod

class Solution:
    def knightDialer(self, n: int) -> int:
         board=[[1,2,3],[4,5,6],[7,8,9],['*',0,'#']]
         dirc=[[-2,-1],[-2,1],[-1,-2],[-1,2],[1,-2],[1,2],[2,-1],[2,1]]
         mod=10**9+7;mem={}
         def dfs(i,j,k):
             if k==1:
                return 1
             if (i,j,k) in mem:
                    return mem[(i,j,k)]
             ans=0
             for x,y in dirc:
                if -1<i+x<4 and -1<j+y<3 and board[i+x][j+y]!='#' and board[i+x][j+y]!='*':
                  ans+=dfs(i+x,j+y,k-1)%mod
             ans%=mod
             mem[(i,j,k)]=ans
             return ans
         res=0
         for i in range(3):
             for j in range(3):
                 res+=dfs(i,j,n)%mod
         res=(res+dfs(3,1,n))%mod
         return res


class Solution:
    def knightDialer(self, N: int) -> int:
#         MOD = 10**9 + 7
#         # dp = [ [[0]*3 for _2 in range(4)]   for _ in range(N)]
#         dp = [[0]*3 for _2 in range(4)]
#         for i in range(4):
#             for j in range(3):
#                 if (i,j) in [(3,0),(3,2)]:
#                     continue
#                 dp[i][j] = 1
        
#         for k in range(1,N):
#             new_dp = [[0]*3 for _2 in range(4)]
#             for i in range(3):
#                 for j in range(i,3):
#                     # print(i,j)
#                     a = [[i+2,j+1],[i+2,j-1],[i-2,j+1],[i-2,j-1],
#                          [i+1,j+2],[i-1,j+2],[i+1,j-2],[i-1,j-2]]
#                     for p in a:
#                         if not(0 <= p[0] < 4) or not(0 <= p[1] < 3):
#                             continue
#                         new_dp[i][j] += dp[p[0]][p[1]] % MOD
#                         # new_dp[j][i] = new_dp[i][j]
#             new_dp[1][0] = new_dp[1][2]
#             new_dp[2][0] = new_dp[2][2]
#             new_dp[2][1] = new_dp[0][1]
#             i = 3
#             j = 1
#             new_dp[3][1] = (dp[1][2] + dp[1][0]) % MOD
#             dp = new_dp
#             # print(dp)
            
#         s = 0
#         # dp[3][0] = dp[N-1][3][2] = 0
#         for i in dp:
#             for j in i:
#                 s += j % MOD
#         return s % MOD
    
        
        cac = {}
        MOD = 10**9 + 7
        pmvs = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],[1,7,0],[2,6],[1,3],[4,2]]
        def d(k,i):
            try:
                # 1/0
                return cac[(k,i)]
            except:
                pass
            if k == 0:
                return 1
            s = 0
            for j in pmvs[i]:
                s += d(k-1,j) % MOD
            cac[(k,i)] = s % MOD
            return cac[(k,i)]
        ans = 0
        for i in range(10):
            ans += d(N-1,i) % MOD
        return ans % MOD


class Solution:
    
    def __init__(self):
        self.helper = {(1,2),(1,-2),(-1,2),(-1,-2),(2,1),(2,-1),(-2,1),(-2,-1)}
    
    def dynamic(self,r,c,dp):
        
        curr = 0
        for s in self.helper:
            x,y = r+s[0],c+s[1]
            
            if 0<=x<4 and 0<=y<3 and ((x,y) != (3,0) or (x,y) != (3,2)):
                curr += dp[x][y]
        return curr#%(10**9+7)
    
    def knightDialer(self, n: int) -> int:
        
        dp = [[1]*3 for _ in range(4)]
        
        dp[3][0] = dp[3][2] = 0
        
        for i in range(n-1):
            dp2 = [[0]*3 for _ in range(4)]
                
            for r in range(4):
                for c in range(3):
                    if (r,c) == (3,0) or (r,c) == (3,2): continue
                        
                    dp2[r][c] = self.dynamic(r,c,dp)
                    
            dp = dp2[:]

        return sum([dp[i][j] for i in range(4) for j in range(3)])%(10**9+7)


class Solution:

    adjacency = {
            0: {4, 6},
            1: {8, 6},
            2: {7, 9},
            3: {8, 4},
            4: {3, 9, 0},
            5: {},
            6: {1, 7, 0},
            7: {2, 6},
            8: {1, 3},
            9: {2, 4}
        }

    def matrixExponentiation(self, a: List[List[int]], k: int) -> List[List[int]]:
        if k == 0:
            return [[1 if r == c else 0 for c in range(len(a[0]))] for r in range(len(a))]

        result = self.matrixExponentiation(a, k // 2)
        result = self.matrixMultiplication(result, result)

        if k % 2 == 1:
            result = self.matrixMultiplication(a, result)

        return result

    def matrixMultiplication(self, a: List[List[int]], b: List[List[int]]) -> List[List[int]]:
        m, n, p = len(a), len(a[0]), len(b[0])
        assert len(a[0]) == len(b)

        matrix = [[0] * p for _ in range(m)]

        for r in range(m):
            for c in range(p):
                for i in range(n):
                    matrix[r][c] += a[r][i] * b[i][c]

        return matrix

    def knightDialer(self, n: int):
        matrix = [[(1 if r in Solution.adjacency[c] else 0) for c in range(10)] for r in range(10)]
        matrix = self.matrixExponentiation(matrix, n - 1)

        count = [[1] for _ in range(10)]
        count = self.matrixMultiplication(matrix, count)

        return sum((sum(r) for r in count)) % (10 ** 9 + 7)


    def knightDialerDP(self, n: int):
        count = [1 for _ in range(10)]

        for _ in range(n - 1):
            count = [sum(count[next_digit] for next_digit in Solution.adjacency[digit]) for digit in range(10)]

        return sum(count) % (10 ** 9 + 7)



class Solution:
    def knightDialer(self, N: int) -> int:
        nos = [[1,2,3], [4,5,6], [7,8,9], [None, 0, None]]
        if N == 0:
            return 0
        
        memo = {}
        
        def calculate(currentIndex, remainingSteps):
            if remainingSteps == 0:
                return 1
            if (currentIndex, remainingSteps) in memo:
                return memo[(currentIndex, remainingSteps)] 
            
            i, j = currentIndex
            
            possibleMoves = []
            
            if i+2 < 4 and j - 1 >= 0 and nos[i+2][j-1] is not None:
                possibleMoves.append((i+2, j-1))
                
            if i+2 < 4 and j + 1 < 3 and nos[i+2][j+1] is not None:
                possibleMoves.append((i+2, j+1))
            
            if i - 1 >= 0 and j+2 < 3 and nos[i-1][j+2] is not None:
                possibleMoves.append((i-1,j+2))
            
            if i+1 < 4 and j+2 < 3 and nos[i+1][j+2] is not None:
                possibleMoves.append((i+1, j+2))
            
            if i-2 >= 0 and j+1 < 3 and nos[i-2][j+1] is not None:
                possibleMoves.append((i-2,j+1))
            
            if i-2 >=0 and j-1 >= 0 and nos[i-2][j-1] is not None:
                possibleMoves.append((i-2, j-1))
            
            if i-1>=0 and j-2>=0 and nos[i-1][j-2] is not None:
                possibleMoves.append((i-1,j-2))
                
            if i+1 < 4 and j-2 >=0 and nos[i+1][j-2] is not None:
                possibleMoves.append((i+1,j-2))
                
            if remainingSteps == 1:
                memo[(currentIndex, remainingSteps)]  = len(possibleMoves)
                return len(possibleMoves) 
            
            
            
            totalNos = 0
            
            for nextInd in possibleMoves:
                if (nextInd, remainingSteps-1) in memo:
                    totalNos += memo[nextInd, remainingSteps-1]
                else:
                    totalNos += calculate(nextInd, remainingSteps-1)
                # if totalNos >= 10**9 + 7:
                #     totalNos = totalNos % (10**9 + 7)
            
            memo[(currentIndex, remainingSteps)] = totalNos
            return memo[(currentIndex, remainingSteps)] 
        
        
        total = 0
        for i in range(0, 4):
            for j in range(0, 3):
                if nos[i][j] is not None:
                    total += calculate((i,j), N-1)
        return total % (10**9 + 7)

class Solution:
    
    def __init__(self):
        self.helper = {(1,2),(1,-2),(-1,2),(-1,-2),(2,1),(2,-1),(-2,1),(-2,-1)}
    
    def dynamic(self,r,c,dp):
        
        curr = 0
        for s in self.helper:
            x,y = r+s[0],c+s[1]
            
            if 0<=x<4 and 0<=y<3 and ((x,y) != (3,0) or (x,y) != (3,2)):
                curr += dp[x][y]
        return curr
    
    def knightDialer(self, n: int) -> int:
        
        dp = [[1]*3 for _ in range(4)]
        
        dp[3][0] = dp[3][2] = 0
        
        
        for i in range(n-1):
            dp2 = [[0]*3 for _ in range(4)]
                
            for r in range(4):
                for c in range(3):
                    if (r,c) == (3,0) or (r,c) == (3,2): continue
                        
                    dp2[r][c] = self.dynamic(r,c,dp)
            dp = dp2[:]
        #print(dp)
        return sum([dp[i][j] for i in range(4) for j in range(3)])%(10**9+7)

class Solution:
    def knightDialer(self, n: int) -> int:
        P = 10**9 + 7
        def wrap(x):
            return x - P if x >= P else x
        s = 0
        for k in range(10):
            d = [0] * 10
            d2 = [0] * 10
            d[k] = 1
            for i in range(n - 1):
                d2[0] = wrap(d[4] + d[6])
                d2[1] = wrap(d[6] + d[8])
                d2[2] = wrap(d[7] + d[9])
                d2[3] = wrap(d[4] + d[8])
                d2[4] = wrap(d[3] + d[9] + d[0])
                d2[5] = 0
                d2[6] = wrap(d[1] + d[7] + d[0])
                d2[7] = wrap(d[2] + d[6])
                d2[8] = wrap(d[1] + d[3])
                d2[9] = wrap(d[2] + d[4])
                d, d2 = d2, d
            s += sum(d)
        return s % (10 ** 9 + 7)



class Solution:
    from collections import defaultdict
    def knightDialer(self, N: int) -> int:
        pos_mapping=[[4, 6], [6, 8], [9, 7], [4, 8], [9, 3, 0], [], [7, 1, 0], [6, 2], [1, 3], [4, 2]]

        
        total_count = 0
        for i in range(10):
            prev_arr = [0]*10
            prev_arr[i] = 1
            for _ in range(N - 1):
                new_arr = [0]*10
                for idx in range(10):
                    if prev_arr[idx] == 0:
                        continue
                    for next_pos in pos_mapping[idx]:
                        new_arr[next_pos] += prev_arr[idx]
                prev_arr = new_arr
            total_count += sum(prev_arr)
        MOD = 10**9 + 7
        return total_count % MOD

class Solution:
    DIAL = [
        [1,   2,  3],
        [4,   5,  6],
        [7,   8,  9],
        ['*', 0, '#']
    ]
    def knightDialer(self, n: int) -> int:
        directions = [(1, -2), (2, -1), (2, 1), (1, 2), (-1, 2), (-2, 1), (-2, -1), (-1, -2)]

        count = 0
        m = len(self.DIAL)
        nn = len(self.DIAL[0])
        cache = {}

        def jump(i, j, path_length):
            if path_length == n:
                return 1
            else:
                total = 0
                if (i, j, path_length) in cache:
                    return cache[i, j, path_length]
                for inc_r, inc_c in directions:
                    r = i + inc_r
                    c = j + inc_c
                    if 0 <= r < m and 0 <= c < nn and isinstance(self.DIAL[r][c], int):
                        total += jump(r, c, path_length+1)
                cache[i, j, path_length] = total
                return total

        res = 0

        for i in range(m):
            for j in range(nn):
                if isinstance(self.DIAL[i][j], int):
                    res += jump(i, j, 1)

        return res % (10**9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        path={
            0:[4,6],
            1:[6,8],
            2:[7,9],
            3:[4,8],
            4:[0,3,9],
            5:[],
            6:[0,1,7],
            7:[2,6],
            8:[1,3],
            9:[2,4]
        }
        M=10**9+7
        @lru_cache
        def paths(i,n):
            #number of ways to jump from i n times          
            if n==1:
                return len(path[i])
            if n==0:
                return 1
            s=0
            for v in path[i]:
                s+=paths(v,n-1)
            return s%M
        ans=0
        for k in path:
            ans+=paths(k,n-1)
        return ans%(M)
                
            


class Solution:
    def knightDialer(self, N: int) -> int:
        nos = [[1,2,3], [4,5,6], [7,8,9], [None, 0, None]]
        if N == 0:
            return 0
        
        memo = {}
        
        def calculate(currentIndex, remainingSteps):
            if remainingSteps == 0:
                return 1
            if (currentIndex, remainingSteps) in memo:
                return memo[(currentIndex, remainingSteps)] 
            i, j = currentIndex
            
            possibleMoves = []
            
            if i+2 < 4 and j - 1 >= 0 and nos[i+2][j-1] is not None:
                possibleMoves.append((i+2, j-1))
                
            if i+2 < 4 and j + 1 < 3 and nos[i+2][j+1] is not None:
                possibleMoves.append((i+2, j+1))
            
            if i - 1 >= 0 and j+2 < 3 and nos[i-1][j+2] is not None:
                possibleMoves.append((i-1,j+2))
            
            if i+1 < 4 and j+2 < 3 and nos[i+1][j+2] is not None:
                possibleMoves.append((i+1, j+2))
            
            if i-2 >= 0 and j+1 < 3 and nos[i-2][j+1] is not None:
                possibleMoves.append((i-2,j+1))
            
            if i-2 >=0 and j-1 >= 0 and nos[i-2][j-1] is not None:
                possibleMoves.append((i-2, j-1))
            
            if i-1>=0 and j-2>=0 and nos[i-1][j-2] is not None:
                possibleMoves.append((i-1,j-2))
                
            if i+1 < 4 and j-2 >=0 and nos[i+1][j-2] is not None:
                possibleMoves.append((i+1,j-2))
                
            if remainingSteps == 1:
                memo[(currentIndex, remainingSteps)]  = len(possibleMoves)
                return len(possibleMoves) 
            
            
            
            totalNos = 0
            
            for nextInd in possibleMoves:
                totalNos += calculate(nextInd, remainingSteps-1)
                # if totalNos >= 10**9 + 7:
                #     totalNos = totalNos % (10**9 + 7)
            
            memo[(currentIndex, remainingSteps)] = totalNos
            return memo[(currentIndex, remainingSteps)] 
        
        
        total = 0
        for i in range(0, 4):
            for j in range(0, 3):
                if nos[i][j] is not None:
                    total += calculate((i,j), N-1)
        return total % (10**9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        modulo = 10**9 + 7
        self.count = 0
        self.cache = {}
        
        for digit in range(0,10):
            self.count += self.getWays(digit, n-1)
        
        return self.count % modulo
    
    def getWays(self, digit, n):
        if n == 0:
            return 1
        
        if (digit,n) in self.cache:
            return self.cache[(digit,n)]
        
        temp = 0
        for neighbor in self.neighbors(digit):
            temp += self.getWays(neighbor, n-1)
    
        self.cache[(digit, n)] = temp
        return self.cache[(digit,n)]
    
    def neighbors(self, digit):
        neighbors = {
            0: (4, 6),
            1: (6, 8),
            2: (7, 9),
            3: (4, 8),
            4: (0, 3, 9),
            5: (),
            6: (0, 1, 7),
            7: (2, 6),
            8: (1, 3),
            9: (2,4)

        }
        
        return neighbors[digit]

import math
class Solution:
    def knightDialer(self, N: int) -> int:
        dp = [[[0 for _ in range(3)] for _ in range(4)] for _ in range(N)]
        
        
        direction = [(1,2),(1,-2),(-1,2),(-1,-2),(2,1),(2,-1),(-2,1),(-2,-1)]
        
        for k in range(N):
            for i in range(4):
                for j in range(3):
                    if k == 0:
                        if (i == 3 and j == 0) or (i == 3 and j == 2):
                            dp[0][i][j] = None
                        else:
                            dp[0][i][j] = 1
                    else:
                        if dp[k-1][i][j] == None:
                            dp[k][i][j] = None
                            continue

                        if i == 1 and j == 1:
                            dp[k][i][j] = 0
                            continue

                        for d in direction:
                            fromi = i + d[0]
                            fromj = j + d[1]
                            #check fromi and fromj are valid
                            if 0 <= fromi <= 3 and 0 <= fromj <= 2 and dp[k-1][fromi][fromj] != None:
                                dp[k][i][j] += dp[k-1][fromi][fromj]
        res = 0
        for i in range(4):
            for j in range(3):
                if dp[-1][i][j] == None:
                    continue
                res += dp[-1][i][j]
        t = pow(10,9)+7
        return res % t
                        
                        
                        


class Solution:
    def __init__(self):
        self.memo = {}
        
    def getOrCreate(self, i, n):
        if (i,n) not in self.memo:
            self.memo[(i, n)] = self.__knightDialerDP(i, n)
        return self.memo[(i, n)]

    def __knightDialerDP(self, i, n):
        if n == 0:
            return 0
        if n == 1:
            return 1
        
        # if i in set([0,1,2,3,7,8,9]):
        #     return self.getOrCreate(i, n-1) + 2
        # elif i in set([4,6]): 
        #     return self.getOrCreate(i, n-1) + 3
        # else:
        #     return 0

        if i == 0:
            return self.getOrCreate(4, n-1) + self.getOrCreate(6, n-1)
        elif i == 1: 
            return self.getOrCreate(6, n-1) + self.getOrCreate(8, n-1)
        elif i == 2:
            return self.getOrCreate(7, n-1) +  self.getOrCreate(9, n-1)
        elif i == 3: 
            return self.getOrCreate(4, n-1) +  self.getOrCreate(8, n-1)
        elif i == 4: 
            return self.getOrCreate(0, n-1) +  self.getOrCreate(3, n-1) + self.getOrCreate(9, n-1)
        elif i == 6:
            return self.getOrCreate(0, n-1) +  self.getOrCreate(1, n-1) + self.getOrCreate(7, n-1)
        elif i == 7: 
            return self.getOrCreate(2, n-1) +  self.getOrCreate(6, n-1)
        elif i == 8: 
            return self.getOrCreate(1, n-1) +  self.getOrCreate(3, n-1)
        elif i == 9: 
            return self.getOrCreate(2, n-1) +  self.getOrCreate(4, n-1)
        else:
            return 0
        
    
    def knightDialer(self, n: int) -> int:
        if n == 0:
            return 0
        
        for k in range(n):
            total_count = 0
            for i in range(10):
                total_count += self.__knightDialerDP(i, k+1)
        return total_count % ((10 ** 9) + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        dp = [1]*10
        mod = 10**9 + 7
        for i in range(1,n):
            dp_old = dp.copy()
            dp[0] = dp_old[4]+dp_old[6]
            dp[1] = dp_old[6]+dp_old[8]
            dp[2] = dp_old[7]+dp_old[9]
            dp[3] = dp_old[4]+dp_old[8]
            dp[4] = dp_old[3]+dp_old[9]+dp_old[0]
            dp[5] = 0
            dp[6] = dp_old[1]+dp_old[7]+dp_old[0]
            dp[7] = dp_old[2]+dp_old[6]
            dp[8] = dp_old[1]+dp_old[3]
            dp[9] = dp_old[2]+dp_old[4]
    
        return sum(dp)%mod

import math
class Solution:
    def knightDialer(self, N: int) -> int:
        dp = [[[0 for _ in range(3)] for _ in range(4)] for _ in range(N)]
        
        
        direction = [(1,2),(1,-2),(-1,2),(-1,-2),(2,1),(2,-1),(-2,1),(-2,-1)]
        
        for k in range(N):
            for i in range(4):
                for j in range(3):
                    if k == 0:
                        if (i == 3 and j == 0) or (i == 3 and j == 2):
                            dp[k][i][j] = None
                        else:
                            dp[k][i][j] = 1
                    else:
                        if dp[k-1][i][j] == None:
                            dp[k][i][j] = None
                            continue

                        if i == 1 and j == 1:
                            dp[k][i][j] = 0
                            continue

                        for d in direction:
                            fromi = i + d[0]
                            fromj = j + d[1]
                            #check fromi and fromj are valid
                            if 0 <= fromi <= 3 and 0 <= fromj <= 2 and dp[k-1][fromi][fromj] != None:
                                dp[k][i][j] += dp[k-1][fromi][fromj]
        res = 0
        for i in range(4):
            for j in range(3):
                if dp[-1][i][j] == None:
                    continue
                res += dp[-1][i][j]
        t = pow(10,9)+7
        return res % t
                        
                        
                        


class Solution:
    def helper(self,cache,position,num_hops):
        neighbors = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],
             [1,7,0],[2,6],[1,3],[2,4]]
        if (position, num_hops) in cache:
            return cache[ (position, num_hops) ]

        if num_hops == 0:
            return 1

        else:
            num_sequences = 0
            for neighbor in neighbors[position]:
                num_sequences += self.helper(cache,neighbor, num_hops - 1)
            cache[ (position, num_hops) ] = num_sequences
        return num_sequences
        
    def knightDialer(self, n: int) -> int:
        cache = {}
        res = 0      
        for start in range(10):
            res += self.helper(cache,start, n-1)
        return res % (10**9 + 7)
    



        
        
                    
                    
                    
                


class Solution:
    def knightDialer(self, n: int) -> int:
        movesMap=dict()
        MOD=10**9+7
        movesMap[0]=[4,6]
        movesMap[1]=[6,8]
        movesMap[2]=[7,9]
        movesMap[3]=[4,8]
        movesMap[4]=[0,3,9]
        movesMap[5]=[]
        movesMap[6]=[0,1,7]
        movesMap[7]=[2,6]
        movesMap[8]=[1,3]
        movesMap[9]=[2,4]
        totalCount=0
        for i in range(10):
            curPos=[0]*10
            curPos[i]=1
            for count in range(n-1):
                nextPos=[0]*10
                for curIndex in range(10):
                    if curPos[curIndex]>0:
                        for nextIndex in movesMap[curIndex]: 
                            nextPos[nextIndex]+=curPos[curIndex]
                            nextPos[nextIndex]=nextPos[nextIndex]%MOD
                curPos=nextPos
            for finIndex in range(10):
                totalCount+=curPos[finIndex]
                totalCount=totalCount%MOD
        return totalCount

class Solution:
    def knightDialer(self, n: int) -> int:
        movesMap=dict()
        MOD=10**9+7
        movesMap[0]=[4,6]
        movesMap[1]=[6,8]
        movesMap[2]=[7,9]
        movesMap[3]=[4,8]
        movesMap[4]=[0,3,9]
        movesMap[5]=[]
        movesMap[6]=[0,1,7]
        movesMap[7]=[2,6]
        movesMap[8]=[1,3]
        movesMap[9]=[2,4]
        totalCount=0
        for i in range(10):
            curPos=[0]*10
            curPos[i]=1
            for count in range(n-1):
                nextPos=[0]*10
                for curIndex in range(10):
                    if curPos[curIndex]>0:
                        for nextIndex in movesMap[curIndex]: 
                            nextPos[nextIndex]+=curPos[curIndex]
                            nextPos[nextIndex]%=MOD
                curPos=nextPos
            for finIndex in range(10):
                totalCount+=curPos[finIndex]
                totalCount%=MOD
        return totalCount

class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 0:
            return 0
        
        pad = [['1', '2', '3'], ['4', '5', '6'], ['7', '8', '9'], ['*', '0', '#']]
        dirs = [[-1, -2], [-2, -1], [1, -2], [2, -1], [-1, 2], [-2, 1], [1, 2], [2, 1]]
        
        memo = dict()
        for i in range(10):
            memo[str(i)] = [0 for j in range(n + 1)]
            memo[str(i)][1] = 1
            
        for j in range(2, n + 1):
            for r in range(4):
                for c in range(3):
                    number = pad[r][c]
                    if number == '*' or number == '#':
                        continue
                    memo[number][j] = 0
                    for dir0 in dirs:
                        x = r + dir0[0]
                        y = c + dir0[1]
                        if x < 0 or x >= 4 or y < 0 or y >= 3 or pad[x][y] == '*' or pad[x][y] == '#':
                            continue
                            
                        parent = pad[x][y]
                        memo[number][j] += memo[parent][j - 1]
        
        res = 0
        for i in range(10):
            number = str(i)
            res += memo[number][n]
        return res % 1_000_000_007
                        
        
        
# Idea:     use 2D dp array memo[10][n + 1] to store the number of distinct phone numbers
#           memo[i][0] = 0
#           memo[i][j] = sum(memo[parent][j - 1])
#           Res = sum(memo[i][n])
# Time:     O(n)
# Space:    O(n)


class Solution:
    def knightDialer(self, n: int) -> int:
        MOD = 10**9 + 7
        # Move records at each idex, which numbers it can jump to
        # 0 can jump to 4 and 6, 1 can jump to 6 and 8, etc
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],[1,7,0],[2,6],[1,3],[2,4]]
        dp = [1]*10
        for hops in range(n-1):
            dp2 = [0]*10
            for node, count in enumerate(dp):
                for nei in moves[node]:
                    dp2[nei] += count
                    dp2[nei] % MOD
            dp = dp2
        return sum(dp)%MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        moves = [(x, y) for x in range(-2, 3, 2) for y in range(-2, 3, 2) if abs(x) != abs(y)]
        MOD = 10 ** 9 + 7 
        res = 0 
        mappings = {
            1: [6, 8],
            2: [7, 9],
            3: [4, 8],
            4: [0, 3, 9], 
            5: [], 
            6: [0, 1, 7], 
            7: [2, 6], 
            8: [1, 3], 
            9: [2, 4], 
            0: [4, 6],
        }
        
        @lru_cache
        def dfs(num_jumps, cell): 
            if num_jumps == 1:
                return 1
            cur = 0
            for i in mappings[cell]:
                cur += dfs(num_jumps - 1, i)
            return cur
        
        for i in range(0, 10):
            res += dfs(n, i)
        
        return res % MOD

class Solution:
    def knightDialer(self, n: int) -> int:
        
        dialer_map = {0: [4, 6],
                      1: [6, 8],
                      2: [7, 9],
                      3: [4, 8],
                      4: [0, 3, 9],
                      5: [],
                      6: [0, 1, 7],
                      7: [2, 6],
                      8: [1, 3],
                      9: [2, 4]}
        
        total = 0
        for i in range(10):
            if i == 5 and n==1:
                total += 1
                continue
            
            level = {i:1}
            curr = 1
            while curr<n:
                next_level = defaultdict(lambda:0)
                for l in list(level.keys()):
                    for d in dialer_map[l]:
                        next_level[d]+=level[l]
                
                level = next_level
                curr += 1
            count = sum(level.values())
            total += count
            total = total%(10**9+7)
        
        return total
                    
                    
            
        


class Solution:
    def knightDialer(self, n: int) -> int:
        mod = 10 ** 9 + 7
        dp = [1] * 10
        
        for _ in range(2, n + 1):
            dpc = dp.copy()
            dp[0] = dpc[4] + dpc[6]
            dp[1] = dpc[6] + dpc[8]
            dp[2] = dpc[7] + dpc[9]
            dp[3] = dpc[4] + dpc[8]
            dp[4] = dpc[3] + dpc[9] + dpc[0]
            dp[5] = 0
            dp[6] = dpc[1] + dpc[7] + dpc[0]
            dp[7] = dpc[2] + dpc[6]
            dp[8] = dpc[1] + dpc[3]
            dp[9] = dpc[4] + dpc[2]
            
        res = sum(dp) % mod
        return res
            
        
            
            
            
        
        


class Solution:
    def knightDialer(self, n: int) -> int:
        
        dialer_map = {0: [4, 6],
                      1: [6, 8],
                      2: [7, 9],
                      3: [4, 8],
                      4: [0, 3, 9],
                      5: [],
                      6: [0, 1, 7],
                      7: [2, 6],
                      8: [1, 3],
                      9: [2, 4]}
        
        total = 0
        for i in range(10):
            if i == 5 and n==1:
                total += 1
                continue
            
            level = {i:1}
            curr = 1
            while curr<n:
                next_level = defaultdict(lambda:0)
                for l in list(level.keys()):
                    for d in dialer_map[l]:
                        next_level[d]+=level[l]
                
                level = next_level
                curr += 1
            count = sum(level.values())
            total += count
        
        return total%(10**9+7)
                    
                    
            
        


class Solution:
    def knightDialer(self, n: int) -> int:
        valid_positions = {
            (0, 0): 1,
            (1, 0): 2,
            (2, 0): 3,
            (0, 1): 4,
            (1, 1): 5,
            (2, 1): 6,
            (0, 2): 7,
            (1, 2): 8,
            (2, 2): 9,
            (1, 3): 0
        }
        
        mod_val = 10**9 + 7
        
        cache = {}
        def find_numbers(start, length):
            if start not in valid_positions:
                return 0
            x,y = start
            
            if (x,y,length) in cache:
                return cache[(x,y,length)]
                
            if length == n:
                return 1
            
            x,y = start
            nums_found = sum(
                        [find_numbers((x+1, y-2), length+1),
                        find_numbers((x+2, y-1), length+1),
                        find_numbers((x-1, y-2), length+1),
                        find_numbers((x-2, y-1), length+1),
                        find_numbers((x-2, y+1), length+1),
                        find_numbers((x-1, y+2), length+1),
                        find_numbers((x+2, y+1), length+1),
                        find_numbers((x+1, y+2), length+1)]
            ) % mod_val
            
            cache[(x,y,length)] = nums_found
            return nums_found
                
                
            
        numbers_found = 0
        for position in valid_positions:
            numbers_found += find_numbers(position, 1)
            numbers_found %= mod_val
            
        # print(sorted(nums))
        
        return numbers_found
            
        
        


class Solution:
    def knightDialer(self, n: int) -> int:
        self.mod = 10**9 + 7
        total_path = 0
        self.d = {}
        for i in range(0,4):
            for j in range(0,3):
                total_path = (total_path + self.dfs(i,j,n) )%self.mod
                #print(total_path)
        return total_path        
     
    def dfs(self,i,j,n):
        if i<0 or j<0 or j>=3 or i>=4 or (i==3 and j!=1):
            return 0
        
        if (i,j,n) in self.d:
            return self.d[(i,j,n)]
        
        if n==1:
            return 1
        
        total=self.dfs(i-1,j+2,n-1)%self.mod+self.dfs(i-1,j-2,n-1)%self.mod+self.dfs(i+1,j-2,n-1)%self.mod+self.dfs(i+1,j+2,n-1)%self.mod+self.dfs(i+2,j+1,n-1)%self.mod+self.dfs(i+2,j-1,n-1)%self.mod+self.dfs(i-2,j+1,n-1)%self.mod+self.dfs(i-2,j-1,n-1)%self.mod
        
        self.d[(i,j,n)] = total
        return total
        
        
        
        


class Solution:
    def knightDialer(self, N: int) -> int:
        
        memo = {}
        maxi = (10**9)+7
        def paths(i,j,n):
            if i>3 or j>2 or i<0 or j <0 or (i==3 and j != 1):
                return 0
            if n == 1:
                return 1
            if (i,j,n) in memo:
                return memo[(i,j,n)]
            result = paths(i - 1, j - 2, n - 1) % maxi + paths(i - 2, j - 1, n - 1) % maxi + paths(i - 2, j + 1, n - 1) % maxi+ paths(i - 1, j + 2, n - 1) % maxi + paths(i + 1, j + 2, n - 1) % maxi + paths(i + 2, j + 1, n - 1) % maxi + paths(i + 2, j - 1, n - 1) % maxi + paths(i + 1, j - 2, n - 1) % maxi
            
            memo[(i,j,n)] = result
            return result

        totalPaths = 0
        for i in range(4):
            for j in range(3):
                totalPaths = (totalPaths+paths(i,j,N))%maxi
                
        return totalPaths
    
# Inspired from Sriram's Java Solution
# https://leetcode.com/problems/knight-dialer/discuss/190787/How-to-solve-this-problem-explained-for-noobs!!!


class Solution:
    def knightDialer(self, n: int) -> int:
        self.mod = 10**9 + 7
        total_path = 0
        self.d = {}
        for i in range(0,4):
            for j in range(0,3):
                total_path = (total_path + self.dfs(i,j,n) )%self.mod
                
        return total_path        
     
    def dfs(self,i,j,n):
        if i<0 or j<0 or j>=3 or i>=4 or (i==3 and j!=1):
            return 0
        
        if (i,j,n) in self.d:
            return self.d[(i,j,n)]
        
        if n==1:
            return 1
        
        total=self.dfs(i-1,j+2,n-1)%self.mod+self.dfs(i-1,j-2,n-1)%self.mod+self.dfs(i+1,j-2,n-1)%self.mod+self.dfs(i+1,j+2,n-1)%self.mod+self.dfs(i+2,j+1,n-1)%self.mod+self.dfs(i+2,j-1,n-1)%self.mod+self.dfs(i-2,j+1,n-1)%self.mod+self.dfs(i-2,j-1,n-1)%self.mod
        
        self.d[(i,j,n)] = total
        return total
        
        
        
        


class Solution:  
    def knightDialer(self, N: int) -> int:
        total = 0
        places = {1:[6,8], 2:[7,9], 3:[4,8], 4:[3,9,0], 6:[1,7,0], 7:[2,6], 8:[1,3], 9:[2,4], 0: [4,6]}
        if N == 1:
            return 10
        dp = [1]*10
        for i in range(2, N+1):
            tmp = copy.deepcopy(dp)
            for i in range(0, 10):
                if i!=5:
                    vals = places.get(i)
                    new_tot = 0
                    for v in vals:
                        new_tot += dp[v]
                    tmp[i] = new_tot
            dp = copy.deepcopy(tmp)
        ans = 0
        for d in dp:
            ans+=d
        return (ans-1) % (10**9 + 7)
                    
                
        


class Solution:
    def nextPositions(self,n):
        x,y = self.x_y_map[n]
        arr = [(x-2,y+1),(x-1,y+2),(x+1,y+2),(x+2,y+1),(x+2,y-1),(x+1,y-2),(x-1,y-2),(x-2,y-1)]
        return [self.reverse_map[v] for v in arr if v in self.reverse_map]
    def build_x_y_map(self):
        r,c = 0,0
        ht = {}
        
        for i in range(1,10):
            ht[i] = (r,c)
            c+=1
            if c == 3:
                r+=1
                c = 0
        
        ht[0] = (3,1)
        return ht
    
    def knightDialer(self, n: int) -> int:
        self.x_y_map = self.build_x_y_map()
        self.reverse_map = {v:k for k,v in list(self.x_y_map.items())}
        
        def count_moves(curr_cell,hops,memo):
            if hops == 0:
                return 1
            key = (curr_cell,hops)
            if key not in memo:
                ways = 0
                for pos in self.nextPositions(curr_cell):
                    ways += count_moves(pos,hops-1,memo)
                memo[key] = ways
            return memo[key]  
        total = 0
        memo = {}
        for i in range(0,10):
            total += count_moves(i,n-1,memo)
        return total % (10**9 + 7)
        


class Solution:
    def knightDialer(self, n: int) -> int:
        keyboard = [
            [1, 2, 3],
            [4, 5, 6],
            [7, 8, 9],
            [-1, 0, -1],
        ]
        dp = [[
            [1, 1, 1],
            [1, 1, 1],
            [1, 1, 1],
            [0, 1, 0]
        ]]
        modulo = 10**9+7
        for k in range(1, n):
            dp.append([[0 for _ in range(3)] for _ in range(4)])
            for i in range(4):
                for j in range(3):
                    for (x, y) in [(i+2, j+1),
                                   (i+2, j-1),
                                   (i-2, j+1),
                                   (i-2, j-1),
                                   (i+1, j+2),
                                   (i+1, j-2),
                                   (i-1, j+2),
                                   (i-1, j-2)]:
                        if 0 <= x < 4 and 0 <= y < 3 and keyboard[x][y] != -1:
                            dp[k][x][y] = (dp[k][x][y]+dp[k-1][i][j])%modulo
        return sum(sum(row) for row in dp[n-1])%modulo

class Solution:
    def knightDialer(self, n: int) -> int:
        if(n == 0):
            return 0
        if(n == 1):
            return 10
        total = 9
        digit = {}
        for j in range(0,10):
            if(j == 5):
                continue
            digit[j] = 1
        const = 10 ** 9 + 7
        for i in range(1,n):
            num_1 = (digit[6] + digit[8]) % const
            num_2 = (digit[7] + digit[9]) % const
            num_3 = (digit[4] + digit[8]) % const
            num_4 = (digit[3] + digit[9] + digit[0]) % const
            num_6 = (digit[1] + digit[7] + digit[0]) % const
            num_7 = (digit[2] + digit[6]) % const
            num_8 = (digit[1] + digit[3]) % const
            num_9 = (digit[2] + digit[4]) % const
            num_0 = (digit[4] + digit[6]) % const
            digit[0] = num_0
            digit[1] = num_1
            digit[2] = num_2
            digit[3] = num_3
            digit[4] = num_4
            digit[6] = num_6
            digit[7] = num_7
            digit[8] = num_8
            digit[9] = num_9
            total = (num_0 + num_1 + num_2 + num_3 + num_4 + num_6 + num_7  + num_8 + num_9) % const
        return total
            
            


class Solution:
    def knightDialer(self, n: int) -> int:
        path={
            0:[4,6],
            1:[6,8],
            2:[7,9],
            3:[4,8],
            4:[0,3,9],
            5:[],
            6:[0,1,7],
            7:[2,6],
            8:[1,3],
            9:[2,4]
        }
        
        @lru_cache
        def paths(i,n):
            #number of ways to jump from i n times          
            if n==1:
                return len(path[i])
            if n==0:
                return 1
            s=0
            for v in path[i]:
                s+=paths(v,n-1)
            return s
        ans=0
        for k in path:
            ans+=paths(k,n-1)
        return ans%(10**9+7)
                
            


class Solution:
    def knightDialer(self, N: int) -> int:
        if N==0: return 0
        
        dp = [1]*10
        
        for i in range(N-1):
            temp = [0]*10
            temp[1], temp[2], temp[3] = dp[6]+dp[8], dp[7]+dp[9], dp[4]+dp[8]
            temp[4], temp[5], temp[6]  = dp[3]+dp[0]+dp[9], 0, dp[1]+dp[7]+dp[0]
            temp[7], temp[8], temp[9]  = dp[2]+dp[6], dp[1]+dp[3], dp[2]+dp[4]
            temp[0] = dp[4]+dp[6]
            dp = temp
            
        
        
        return sum(dp)%(10**9+7)


class Solution:
    def knightDialer(self, N: int) -> int:
        D = [[0] * 10 for _ in range(2)]
        D[0] = [1] * 10
        for i in range(1, N):
            idx = i % 2
            P = D[(i-1)%2]
            D[idx][1] = P[8] + P[6]
            D[idx][2] = P[7] + P[9]
            D[idx][3] = P[4] + P[8]
            D[idx][4] = P[3] + P[9] + P[0]
            D[idx][5] = 0
            D[idx][6] = P[1] + P[7] + P[0]
            D[idx][7] = P[2] + P[6]
            D[idx][8] = P[1] + P[3]
            D[idx][9] = P[2] + P[4]
            D[idx][0] = P[4] + P[6]
            
        return sum(D[(N+1)%2]) % (10**9 + 7)

mexp = 10 ** 9 + 7

class Solution:
    def knightDialer(self, n: int) -> int:
        dp = [1 for x in range(10)]
        for _ in range(n - 1):
            ndp = [0 for x in range(10)]
            ndp[0] = (dp[4] + dp[6]) % mexp
            ndp[1] = (dp[6] + dp[8]) % mexp
            ndp[2] = (dp[7] + dp[9]) % mexp
            ndp[3] = (dp[4] + dp[8]) % mexp
            ndp[4] = (dp[3] + dp[9] + dp[0]) % mexp
            ndp[5] = 0
            ndp[6] = (dp[1] + dp[7] + dp[0]) % mexp
            ndp[7] = (dp[2] + dp[6]) % mexp
            ndp[8] = (dp[1] + dp[3]) % mexp
            ndp[9] = (dp[2] + dp[4]) % mexp
            dp = ndp
        return sum(dp) % mexp

import numpy as np
class Solution:
    def knightDialer(self, N: int) -> int:
        
        mod = 10**9 + 7
        M = np.matrix([[0, 0, 0, 0, 1, 0, 1, 0, 0, 0],
                       [0, 0, 0, 0, 0, 0, 1, 0, 1, 0],
                       [0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
                       [0, 0, 0, 0, 1, 0, 0, 0, 1, 0],
                       [1, 0, 0, 1, 0, 0, 0, 0, 0, 1],
                       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                       [1, 1, 0, 0, 0, 0, 0, 1, 0, 0],
                       [0, 0, 1, 0, 0, 0, 1, 0, 0, 0],
                       [0, 1, 0, 1, 0, 0, 0, 0, 0, 0],
                       [0, 0, 1, 0, 1, 0, 0, 0, 0, 0]])
        res = np.matrix([[1]*10])

        N -= 1
        while N:
            if N % 2 != 0: 
                res = res * M % mod     
                N -= 1
            else:
                M = M * M % mod
                N /= 2
        return int(np.sum(res)) % mod
                
        


class Solution:
    def knightDialer(self, n: int) -> int:
        mexp = 10 ** 9 + 7
        dp = [1 for x in range(10)]
        for i in range(n - 1):
            ndp = [0 for x in range(10)]
            ndp[0] = (dp[4] + dp[6]) % mexp
            ndp[1] = (dp[6] + dp[8]) % mexp
            ndp[2] = (dp[7] + dp[9]) % mexp
            ndp[3] = (dp[4] + dp[8]) % mexp
            ndp[4] = (dp[0] + dp[3] + dp[9]) % mexp
            ndp[5] = 0
            ndp[6] = (dp[0] + dp[1] + dp[7]) % mexp
            ndp[7] = (dp[2] + dp[6]) % mexp
            ndp[8] = (dp[1] + dp[3]) % mexp
            ndp[9] = (dp[2] + dp[4]) % mexp
            dp = ndp
        return sum(dp) % mexp

class Solution:
    def knightDialer(self, n: int) -> int:
        if n==1:
            return 10
        a_0 = 1
        a_1 = 1
        a_2 = 1
        a_3 = 1
        a_4 = 1
        a_5 = 0
        a_6 = 1
        a_7 = 1
        a_8 = 1
        a_9 = 1
        A= [a_0,a_1,a_2,a_3,a_4,a_5,a_6,a_7,a_8,a_9]
        def count_next_moves(A):
            result =[]
            result.append(A[6]+A[4])
            result.append(A[6]+A[8])
            result.append(A[7]+A[9])
            result.append(A[4]+A[8])
            result.append(A[3]+A[9]+A[0])
            result.append(0)
            result.append(A[1]+A[7]+A[0])
            result.append(A[6]+A[2])
            result.append(A[1]+A[3])
            result.append(A[2]+A[4])
            return result
        for i in range(n-1):
            A = count_next_moves(A)
        result = (sum(A)%((10**9) + 7))
        return result
                
                

        
        
                    
                                


class Solution:
    def knightDialer(self, N: int) -> int:
        D = [[0] * 10 for _ in range(N)]
        D[0] = [1] * 10
        for i in range(1, N):
            P = D[i-1]
            D[i][1] = P[8] + P[6]
            D[i][2] = P[7] + P[9]
            D[i][3] = P[4] + P[8]
            D[i][4] = P[3] + P[9] + P[0]
            D[i][5] = 0
            D[i][6] = P[1] + P[7] + P[0]
            D[i][7] = P[2] + P[6]
            D[i][8] = P[1] + P[3]
            D[i][9] = P[2] + P[4]
            D[i][0] = P[4] + P[6]
            
        return sum(D[-1]) % (10**9 + 7)

class Solution:
    def knightDialer(self, N: int) -> int:
#         if N < 1: return 0
#         modnum = 10**9 + 7
#         memo = defaultdict(lambda:0)

#         def dfs(y, x, cnt):
#             nonlocal modnum, memo, N
#             if (y,x) == (3,0) or (y,x) == (3,2):
#                 return 0
#             elif cnt == N:
#                 return 1
#             elif (y, x, cnt) in memo:
#                 return memo[(y, x, cnt)]
            
#             tmpcnt = 0

#             for (nxy, nxx) in ((y-1, x-2), (y-2, x-1), (y-2, x+1), (y-1, x+2), (y+1, x+2), (y+2, x+1), (y+2, x-1), (y+1, x-2)):
#                 if(0<=nxy<4 and 0<=nxx<3):
#                     tmpcnt += dfs(nxy, nxx, cnt+1)
#                     tmpcnt %= modnum
            
#             memo[(y, x, cnt)] = tmpcnt
#             return memo[(y, x, cnt)]
            
#         return sum(dfs(y,x,1) for y in range(4) for x in range(3))%modnum
        
        #超级快的版本
    #     self.moves = [(4,6),(6,8),(7,9),(4,8),(3,9,0),(),(1,7,0),(2,6),(1,3),(2,4)]
    #     return sum(self.dfs(N, i) for i in range(10)) % (10**9+7)
    # def dfs(self, N, i, dp={}):
    #     if N == 1: return 1
    #     if (N,i) not in dp:
    #         dp[(N,i)] = sum(self.dfs(N-1, j) for j in self.moves[i])%(10**9+7)
    #     return dp[(N,i)]
        
        #O(N) solution no dfs
        if N == 1: return 10;
        # current number of hops that end in index i, skip 5 because it is terminal
        ends_in = [0 if i == 5 else 1 for i in range(10)]
        mod = 1e9+7
        
        for i in range(N-1):
            next_ends_in = [0 for _ in range(10)]
            next_ends_in[0] = (ends_in[4] + ends_in[6]) % mod
            next_ends_in[1] = (ends_in[6] + ends_in[8]) % mod
            next_ends_in[2] = (ends_in[7] + ends_in[9]) % mod
            next_ends_in[3] = (ends_in[4] + ends_in[8]) % mod
            next_ends_in[4] = (ends_in[3] + ends_in[9] + ends_in[0]) % mod
            # skip 5 because we can never get to it
            next_ends_in[6] = (ends_in[1] + ends_in[7] + ends_in[0]) % mod
            next_ends_in[7] = (ends_in[2] + ends_in[6]) % mod
            next_ends_in[8] = (ends_in[1] + ends_in[3]) % mod
            next_ends_in[9] = (ends_in[2] + ends_in[4]) % mod
            ends_in = next_ends_in
        
        return int(sum(ends_in) % mod)
        
        
        
        
        
        
        
        


class Solution:
    def knightDialer(self, n: int) -> int:
        dp = [1] * 10
        MOD = 10 ** 9 + 7
        
        for i in range(2, n+1):
            old_dp = dp.copy()
            
            dp[0] = old_dp[4] + old_dp[6]
            dp[1] = old_dp[6] + old_dp[8]
            dp[2] = old_dp[7] + old_dp[9]
            dp[3] = old_dp[4] + old_dp[8]
            dp[4] = old_dp[3] + old_dp[9] + old_dp[0]
            dp[5] = 0
            dp[6] = old_dp[1] + old_dp[7] + old_dp[0]
            dp[7] = old_dp[2] + old_dp[6]
            dp[8] = old_dp[1] + old_dp[3]
            dp[9] = old_dp[2] + old_dp[4]
        
        ans = sum(dp) % MOD
        
        return ans

class Solution:
    def knightDialer(self, n: int) -> int:
        dialer = {}
        for i in range(10):
            dialer[i] = 1
        for j in range(n):
            store = [dialer[k] for k in dialer]
            dialer[0] = store[4] + store[6]
            dialer[1] = store[8] + store[6]
            dialer[2] = store[9] + store[7]
            dialer[3] = store[8] + store[4]
            dialer[4] = store[0] + store[9] + store[3]
            dialer[5] = 0
            dialer[6] = store[0] + store[7] + store[1]
            dialer[7] = store[2] + store[6]
            dialer[8] = store[1] + store[3]
            dialer[9] = store[2] + store[4]
        return sum(store) % (10 ** 9 + 7)

import numpy as np
class Solution:
    def knightDialer(self, N: int) -> int:
        
        mod = 10**9 + 7
        M = np.matrix([[0, 0, 0, 0, 1, 0, 1, 0, 0, 0],
                       [0, 0, 0, 0, 0, 0, 1, 0, 1, 0],
                       [0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
                       [0, 0, 0, 0, 1, 0, 0, 0, 1, 0],
                       [1, 0, 0, 1, 0, 0, 0, 0, 0, 1],
                       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                       [1, 1, 0, 0, 0, 0, 0, 1, 0, 0],
                       [0, 0, 1, 0, 0, 0, 1, 0, 0, 0],
                       [0, 1, 0, 1, 0, 0, 0, 0, 0, 0],
                       [0, 0, 1, 0, 1, 0, 0, 0, 0, 0]])
        res = np.matrix([[1]*10])

        N -= 1
        while N:
            if N % 2 != 0: 
                res = res * M % mod     
                N -= 1
            else:
                print(M)
                M = M * M % mod
                print(M)
                N /= 2
        return int(np.sum(res)) % mod
                
        


class Solution:
    def knightDialer(self, n: int) -> int:
        len_start_number = {}
        mod_num = 1000000007
        len_start_number = {(1,i): 1 for i in range(0,10)}
        for i in range(2,n+1):
            len_start_number[(i,1)] = (len_start_number[(i-1,4)] + len_start_number[(i-1,8)]) % mod_num 
            len_start_number[(i,2)] = (len_start_number[(i-1,7)] * 2) % mod_num
            len_start_number[(i,4)] = (len_start_number[(i-1,1)] + len_start_number[(i-1,7)] + len_start_number[(i-1,0)]) % mod_num
            len_start_number[(i,5)] = 0
            len_start_number[(i,7)] = (len_start_number[(i-1,2)] + len_start_number[(i-1,4)]) % mod_num
            len_start_number[(i,8)] = (len_start_number[(i-1,1)] * 2) % mod_num
            len_start_number[(i,0)] = (len_start_number[(i-1,4)] * 2) % mod_num
        
        count = 0
        for k in [0,1,2,4,5,7,8]:
            if k in [1,4,7]:
                count += (2 * len_start_number[(n,k)]) % mod_num
            else:
                count += len_start_number[(n,k)] % mod_num
        return count % mod_num
            


import numpy as np

class Solution:
    def knightDialer(self, n: int) -> int:
        M = np.matrix([
            [0,0,0,0,1,0,1,0,0,0],
            [0,0,0,0,0,0,1,0,1,0], 
            [0,0,0,0,0,0,0,1,0,1], 
            [0,0,0,0,1,0,0,0,1,0], 
            [1,0,0,1,0,0,0,0,0,1], 
            [0,0,0,0,0,0,0,0,0,0], 
            [1,1,0,0,0,0,0,1,0,0], 
            [0,0,1,0,0,0,1,0,0,0], 
            [0,1,0,1,0,0,0,0,0,0], 
            [0,0,1,0,1,0,0,0,0,0]
        ])

        dp = [1,1,1,1,1,1,1,1,1,1]
        f = M
        n = n - 1
        while n > 0:
            if n % 2:
                dp = dp * M % 1000000007
            n = n // 2
            M = M * M % 1000000007
        return np.sum(dp) % 1000000007
            
# class Solution:
#     def knightDialer(self, n: int) -> int:
#         path = [(4, 6), (6, 8), (7, 9), (4, 8),
#                (0, 3, 9), (), (0, 1, 7),
#                (2, 6), (1, 3), (2, 4)]
#         memo = []
#         for i in range(n+1):
#             memo.append({})
#             for j in range(10):
#                 memo[i][j] = -1
        
#         def dp(num, steps):
#             if steps == 1:
#                 return 1
#             if memo[steps][num] != -1:
#                 return memo[steps][num]
#             ret = 0
#             for i in path[num]:
#                 ret += dp(i, steps-1)
#             memo[steps][num] = ret
#             return ret % 1000000007
        
#         res = 2 * (dp(1, n) + dp(4, n) + dp(7, n)) + dp(2, n) + dp(5, n) + dp(8, n) + dp(0, n)
#         res %= 1000000007
#         return res


#bfs solution

#graph problem



class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 1: return 10
        chessmap = {1:[4,2], 2:[1,3], 3:[4,2], 4:[3,1,0], 0:[4,4]}
        table = [1]*5
        for i in range(2, n+1):
            tmp = [0] * 5
            for j in range(5):
                for k in chessmap[j]:
                    tmp[j] += table[k]
            table = tmp
        return (sum(table)*2-table[0]) % (10**9+7)

class Solution:
    def knightDialer(self, l: int) -> int:
        dpTable = [1] * 10
        for _ in range(l - 1):
            newTable = [0] * 10
            for i in [0, 1, 2, 3, 4, 6, 7, 8, 9]:
                if i == 0:
                    ret = dpTable[4] + dpTable[6]
                elif i == 1:
                    ret = dpTable[6] + dpTable[8]
                elif i == 2:
                    ret = dpTable[7] + dpTable[9]
                elif i == 3:
                    ret = dpTable[4] + dpTable[8]
                elif i == 4:
                    ret = dpTable[3] + dpTable[9] + dpTable[0]
                elif i == 6:
                    ret = dpTable[1] + dpTable[7] + dpTable[0]
                elif i == 7:
                    ret = dpTable[2] + dpTable[6]
                elif i == 8:
                    ret = dpTable[1] + dpTable[3]
                elif i == 9:
                    ret = dpTable[2] + dpTable[4]
                newTable[i] = ret % 1000000007
            dpTable = newTable
        return sum(dpTable) % 1000000007


class Solution:
    def knightDialer(self, N: int) -> int:
        D = 10**9 + 7
        l = [1 for _ in range(10)]
        for _ in range(N-1):
            l = self.transform_list(l)
            l = [x % D for x in l]
        return sum(l) % D
        
        
    def transform_list(self, l: List[int]) -> List[int]:
        # 0 -> 4, 6
        # 1 -> 6, 8
        # 2 -> 7, 9
        # 3 -> 4, 8
        # 4 -> 3, 9, 0
        # 5 -> None
        # 6 -> 1, 7, 0
        # 7 -> 2, 6
        # 8 -> 1, 3
        # 9 -> 2, 4
        nl = [0 for _ in range(10)]
        nl[0] = l[4] + l[6]
        nl[1] = l[6] + l[8]
        nl[2] = l[7] + l[9]
        nl[3] = l[4] + l[8]
        nl[4] = l[3] + l[9] + l[0]
        nl[6] = l[1] + l[7] + l[0]
        nl[7] = l[2] + l[6]
        nl[8] = l[1] + l[3]
        nl[9] = l[2] + l[4]
        return nl


class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 0:
            return n
        pad = []
        for i in range(4):
            pad.append([1]*3)
        pad[3][0] = 0
        pad[3][2] = 0
        for k in range(n-1):
            newPad = []
            for i in range(4):
                newPad.append([1]*3)
            newPad[0][0] = (pad[1][2] + pad[2][1])%(10**9 + 7)
            newPad[0][1] = (pad[2][0] + pad[2][2])%(10**9 + 7)
            newPad[0][2] = (pad[1][0] + pad[2][1])%(10**9 + 7)
            newPad[1][0] = (pad[0][2] + pad[2][2] + pad[3][1])%(10**9 + 7)
            newPad[1][1] = 0
            newPad[1][2] = (pad[0][0] + pad[2][0] + pad[3][1])%(10**9 + 7)
            newPad[2][0] = (pad[1][2] + pad[0][1])%(10**9 + 7)
            newPad[2][1] = (pad[0][0] + pad[0][2])%(10**9 + 7)
            newPad[2][2] = (pad[0][1] + pad[1][0])%(10**9 + 7)
            newPad[3][0] = 0
            newPad[3][1] = (pad[1][0] + pad[1][2])%(10**9 + 7)
            newPad[3][2] = 0
            pad = newPad
        total = 0
        for i in range(len(pad)):
            total += sum(pad[i])
        return total%(10**9 + 7)

class Solution:
    def knightDialer(self, N: int) -> int:
        dp = [[0] * 10 for _ in range(N)]
        for i in range(N):
            if i == 0:
                dp[i] = [1] * 10
                continue
            dp[i][0] = dp[i-1][4] + dp[i-1][6]
            dp[i][1] = dp[i-1][8] + dp[i-1][6]
            dp[i][2] = dp[i-1][7] + dp[i-1][9]
            dp[i][3] = dp[i-1][4] + dp[i-1][8]
            dp[i][4] = dp[i-1][0] + dp[i-1][3] + dp[i-1][9]
            dp[i][5] = 0
            dp[i][6] = dp[i-1][0] + dp[i-1][1] + dp[i-1][7]
            dp[i][7] = dp[i-1][2] + dp[i-1][6]
            dp[i][8] = dp[i-1][1] + dp[i-1][3]
            dp[i][9] = dp[i-1][2] + dp[i-1][4]
        #print(dp)
        return sum(dp[-1]) % (10**9 + 7)


class Solution:
    def knightDialer(self, N: int) -> int:
        
        dp = [0] * 10
        
        for j in range(10):
            dp[j] = 1

        for i in range(1, N):
            tmp0 = (dp[4] + dp[6]) % (math.pow(10,9) + 7)
            tmp1 = (dp[6] + dp[8]) % (math.pow(10,9) + 7)
            tmp2 = (dp[7] + dp[9]) % (math.pow(10,9) + 7)
            tmp3 = (dp[4] + dp[8]) % (math.pow(10,9) + 7)
            tmp4 = (dp[0] + dp[3] + dp[9]) % (math.pow(10,9) + 7)
            tmp5 = 0
            tmp6 = (dp[0] + dp[1] + dp[7]) % (math.pow(10,9) + 7)
            tmp7 = (dp[2] + dp[6]) % (math.pow(10,9) + 7)
            tmp8 = (dp[1] + dp[3]) % (math.pow(10,9) + 7)
            tmp9 = (dp[2] + dp[4]) % (math.pow(10,9) + 7)
            
            dp[0] = tmp0
            dp[1] = tmp1
            dp[2] = tmp2
            dp[3] = tmp3
            dp[4] = tmp4
            dp[5] = tmp5
            dp[6] = tmp6
            dp[7] = tmp7
            dp[8] = tmp8
            dp[9] = tmp9
            
        total = 0
        for j in range(10):
            if N > 1 and j == 5: continue
            total += dp[j]
            
                
        total = int(total % (math.pow(10,9) + 7))
        return total
            
                


class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 0:
            return n
        pad = []
        for i in range(4):
            pad.append([1]*3)
        pad[3][0] = 0
        pad[3][2] = 0
        for k in range(n-1):
            newPad = []
            for i in range(4):
                newPad.append([1]*3)
            newPad[0][0] = pad[1][2] + pad[2][1]
            newPad[0][1] = pad[2][0] + pad[2][2]
            newPad[0][2] = pad[1][0] + pad[2][1]
            newPad[1][0] = pad[0][2] + pad[2][2] + pad[3][1]
            newPad[1][1] = 0
            newPad[1][2] = pad[0][0] + pad[2][0] + pad[3][1]
            newPad[2][0] = pad[1][2] + pad[0][1]
            newPad[2][1] = pad[0][0] + pad[0][2]
            newPad[2][2] = pad[0][1] + pad[1][0]
            newPad[3][0] = 0
            newPad[3][1] = pad[1][0] + pad[1][2]
            newPad[3][2] = 0
            pad = newPad
        total = 0
        for i in range(len(pad)):
            total += sum(pad[i])
        return total%(10**9 + 7)

class Solution:
    def knightDialer(self, N: int) -> int:
        T = [[0] * (N+1) for i in range(10)]
        for i in range(10):
            T[i][1] = 1
        for step in range(2, N+1):
            T[0][step] = T[4][step-1] + T[6][step-1]
            T[1][step] = T[8][step-1] + T[6][step-1]
            T[2][step] = T[7][step-1] + T[9][step-1]
            T[3][step] = T[4][step-1] + T[8][step-1]
            T[4][step] = T[3][step-1] + T[9][step-1] + T[0][step-1]
            T[5][step] = 0
            T[6][step] = T[1][step-1] + T[7][step-1] + T[0][step-1]
            T[7][step] = T[6][step-1] + T[2][step-1]
            T[8][step] = T[1][step-1] + T[3][step-1]
            T[9][step] = T[2][step-1] + T[4][step-1]
        return sum([T[i][N] for i in range(10)]) % (pow(10, 9) + 7)


class Solution:
        
    def knightDialer(self, n: int) -> int:
        import numpy as np
        mod = 10**9 + 7
        if n == 1: return 10
        M = np.matrix([[0, 0, 0, 0, 1, 0, 1, 0, 0, 0],
                       [0, 0, 0, 0, 0, 0, 1, 0, 1, 0],
                       [0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
                       [0, 0, 0, 0, 1, 0, 0, 0, 1, 0],
                       [1, 0, 0, 1, 0, 0, 0, 0, 0, 1],
                       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                       [1, 1, 0, 0, 0, 0, 0, 1, 0, 0],
                       [0, 0, 1, 0, 0, 0, 1, 0, 0, 0],
                       [0, 1, 0, 1, 0, 0, 0, 0, 0, 0],
                       [0, 0, 1, 0, 1, 0, 0, 0, 0, 0]])
        res = np.matrix([[1]*10])
        n -= 1
        while n:
            if n % 2 != 0: 
                res = res * M % mod                
                n -= 1
            else:
                M = M * M % mod
                n /= 2
        return int(np.sum(res)) % mod

class Solution:
    def knightDialer(self, n: int) -> int:
        if n == 1:
            return 10
        dp = [[1,1,1,1,1,0,1,1,1,1] for _ in range(n+1)]
        for i in range(2, n+1):
            dp[i][0] = dp[i-1][4] + dp[i-1][6]
            dp[i][1] = dp[i-1][8] + dp[i-1][6]
            dp[i][2] = dp[i-1][7] + dp[i-1][9]
            dp[i][3] = dp[i-1][4] + dp[i-1][8]
            dp[i][4] = dp[i-1][0] + dp[i-1][9] + dp[i-1][3]
            dp[i][6] = dp[i-1][1] + dp[i-1][7] + dp[i-1][0]
            dp[i][7] = dp[i-1][6] + dp[i-1][2]
            dp[i][8] = dp[i-1][1] + dp[i-1][3]
            dp[i][9] = dp[i-1][4] + dp[i-1][2]
        return sum(dp[-1]) % (10**9 + 7)

class Solution:
    def knightDialer(self, n: int) -> int:
        num = 0
        stack = [(1, i, i) for i in range(10)]
        pos = {1: [6, 8], 2: [7, 9], 3: [4, 8], 4: [0, 3, 9], 5: [], 6: [0, 1, 7], 7: [2, 6], 8: [1, 3], 9: [2, 4], 0: [4, 6]}
        memo = [[1]*10 for _ in range(n)]
        for i in range(1,n):
            memo[i][0] = memo[i-1][4] + memo[i-1][6]
            memo[i][1] = memo[i-1][6] + memo[i-1][8]
            memo[i][2] = memo[i-1][7] + memo[i-1][9]
            memo[i][3] = memo[i-1][4] + memo[i-1][8]
            memo[i][4] = memo[i-1][0] + memo[i-1][3] + memo[i-1][9]
            memo[i][5] = 0
            memo[i][6] = memo[i-1][1] + memo[i-1][7] + memo[i-1][0]
            memo[i][7] = memo[i-1][2] + memo[i-1][6]
            memo[i][8] = memo[i-1][1] + memo[i-1][3]
            memo[i][9] = memo[i-1][2] + memo[i-1][4]

        return sum(memo[-1]) % (10**9 + 7)


class Solution:
    def knightDialer(self, n: int) -> int:
#         moveable = {
#         1: [6, 8],
#         2: [7, 9],
#         3: [4, 8],
#         4: [0, 3, 9],
#         5: [],
#         6: [0, 1, 7],
#         7: [2, 6],
#         8: [1, 3],
#         9: [2, 4],
#         0: [4, 6]
#         }
#         MOD = 7 + 1e9
#         @lru_cache(maxsize=None)
#         def helper(step, num=-1):
#             if step == n:
#                 return 1

#             result = 0
#             if num == -1:
#                 for i in range(10):
#                     result = (result + helper(step + 1, i)) % MOD
#             else:
#                 for move in moveable[num]:
#                     result = (result + helper(step + 1, move)) % MOD
#             return result

#         return int(helper(0))
    
        moveable = {
        1: [6, 8],
        2: [7, 9],
        3: [4, 8],
        4: [0, 3, 9],
        5: [],
        6: [0, 1, 7],
        7: [2, 6],
        8: [1, 3],
        9: [2, 4],
        0: [4, 6]
        }
        MOD = 7 + 1e9

        dp = [1] * 10
        for step in range(n - 1):
            newDP = [0] * 10
            for key in range(10):
                for move in moveable[key]:
                    newDP[move] = (newDP[move] + dp[key]) % MOD
            dp = newDP

        return int(sum(dp) % MOD)

class Solution:
    def knightDialer(self, n: int) -> int:
        jump = {
            1: [6,8],
            2: [7,9],
            3: [4,8],
            4: [3,9,0],
            5: [],
            6: [1,7,0],
            7: [6,2],
            8: [1,3],
            9: [2,4],
            0: [4,6]
        }
        
        dp = [1]*10
        for _ in range(n-1):
            newDp = [1]*10
            for i in range(10):
                res = 0
                for item in jump[i]:
                    res += dp[item]
                res %= 1000000007
                newDp[i] = res
            dp = newDp
        return sum(dp)%1000000007

class Solution:
    def knightDialer(self, n: int) -> int:
        a, M = [1]*10, 10**9 + 7
        moves = [(4,6), (6,8), (7,9), (4,8), (0,3,9), (), (0,1,7), (2,6), (1,3), (2,4)]
        for _ in range(1, n):
            b = [0]*10
            for i in range(10):
                for j in moves[i]:
                    b[i] = (b[i] + a[j]) % M
            a = b
        
        return sum(a)%M

class Solution:
    def knightDialer(self, N: int) -> int:
        dp = [1] * 10
        MOD = 10 ** 9 + 7
        moves = [[4, 6], [6, 8], [7, 9], [4, 8], [0, 3, 9], [], [1, 7, 0], [2, 6], [1, 3], [2, 4]]
        
        for hop in range(N - 1):
            new_dp = [0] * 10
            for num, count in enumerate(dp):
                for neigh in moves[num]:
                    new_dp[neigh] = (new_dp[neigh] + count) % MOD
            dp = new_dp
        
        return sum(dp) % MOD

class Solution:
    def knightDialer(self, N: int) -> int:
        # Space O(10)
        moves = [[4,6],[6,8],[7,9],[4,8],[3,9,0],[],[1,7,0],[2,6],[1,3],[2,4]]
        dp = [1] * 10
        MOD = 10**9 + 7
        for i in range(N - 1):
            next_dp = [0] * 10
            for j in range(10):
                for next_digit in moves[j]:
                    next_dp[j] = (next_dp[j] + dp[next_digit]) % MOD
            dp = next_dp
        return sum(dp) % MOD
        
        # space O(10 * N)
        # mapping = {1:[6,8], 
        #            2:[7,9], 
        #            3:[4,8], 
        #            4:[3,9,0],
        #            5:[],
        #            6:[1,7,0],
        #            7:[2,6], 
        #            8:[1,3], 
        #            9:[2,4], 
        #            0:[4,6]}
        # dp = [[0] * 10 for _ in range(N)]
        # dp[0] = [1] * 10
        # for i in range(1, N):
        #     for j in range(10):
        #         for next_digit in mapping[j]:
        #             dp[i][j] += dp[i - 1][next_digit]
        # return sum(dp[-1]) % (10**9 + 7)


class Solution:
    def knightDialer(self, N: int) -> int:
        moves = [(4,6),(6,8),(7,9),(4,8),(3,9,0),(),(1,7,0),(2,6),(1,3),(2,4)]
        memo = [1]*10
        maxV = (10**9+7)
        for _ in range(N-1):
            temp = [0]*10
            for i in range(10):
                for dest in moves[i]:
                    temp[i] += memo[dest]
                temp[i] %= maxV
            memo = temp
                    
        return sum(memo)%maxV


class Solution:
    def knightDialer(self, n: int) -> int:
        neighbors = {
            0: [4,6],
            1: [6,8],
            2: [7,9],
            3: [4,8],
            4: [0,3,9],
            5: [],
            6: [0,1,7],
            7: [2,6],
            8: [1,3],
            9: [2,4]
        }
        # def helper(pos, hops_left):
        #     if hops_left == 1: return 1
        #     if (pos, hops_left) in cache:
        #         return cache[(pos, hops_left)]
        #     else:
        #         sequences = 0
        #         for ne in neighbors[pos]:
        #             sequences += helper(ne, hops_left-1)
        #         cache[(pos, hops_left)] = sequences
        #         # print(f\"seq {sequences} for (pos {pos}, hops_left {hops_left})\")
        #         return sequences
        # cache = {}
        # counts = [0]*10
        # for start in range(10):
        #     counts[start] = helper(start, n)
        #     # print(f\"counts[{start}] = {counts[start]}\")
        # return sum(counts)%(10**9+7)
        current_counts = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
        for _ in range(n-1):
            next_counts = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
            for src_key in range(10):
                for dst_key in neighbors[src_key]:
                    next_counts[dst_key] = (next_counts[dst_key] + current_counts[src_key]) % (10**9 + 7)
            current_counts = next_counts
        return sum(current_counts) % (10**9 + 7)