1 /*
2 题意:n位数字,任意连续的三位数字组成的数字是素数,这样的n位数有多少个
3 最优子结构:考虑3位数的数字,可以枚举出来,第4位是和第3位,第2位组成的数字判断是否是素数
4 所以,dp[i][j][k] 表示i位数字,最高位数字j,第二高位数字k
5 状态转移方程:dp[i][j][k] += dp[i-1][k][l]
6 注意:最高位从1开始枚举:)
7 详细解释:http://blog.csdn.net/zhangyanxing666/article/details/9628563
8 */
9 #include <cstdio>
10 #include <iostream>
11 #include <algorithm>
12 #include <cstring>
13 #include <cmath>
14 using namespace std;
15
16 const int MAXN = 1e4 + 10;
17 const int INF = 0x3f3f3f3f;
18 const int MOD = 1e9 + 9;
19 int prime[11][11][11];
20 int vis[1010];
21 int dp[MAXN][11][11];
22
23 void solve(void)
24 {
25 memset (prime, 0, sizeof (prime));
26 memset (vis, 0, sizeof (vis));
27 memset (dp, 0, sizeof (dp));
28 for (int i=2; i<=1000; ++i)
29 {
30 if (!vis[i])
31 {
32 vis[i] = true;
33 for (int j=i*2; j<=1000; j+=i)
34 {
35 vis[j] = true;
36 }
37 prime[i/100][i/10%10][i%10] = 1;
38 }
39 }
40
41 for (int i=1; i<=9; ++i)
42 {
43 for (int j=0; j<=9; ++j)
44 {
45 for (int k=0; k<=9; ++k) if (prime[i][j][k]) dp[3][i][j]++;
46 }
47 }
48
49 for (int i=4; i<=10000; ++i)
50 {
51 for (int j=1; j<=9; ++j)
52 {
53 for (int k=0; k<=9; ++k)
54 {
55 for (int l=0; l<=9; ++l)
56 if (prime[j][k][l]) dp[i][j][k] = (dp[i][j][k] + dp[i-1][k][l]) % MOD;
57 }
58 }
59 }
60 }
61
62 int main(void) //URAL 1586 Threeprime Numbers
63 {
64 //freopen ("M.in", "r", stdin);
65
66 solve ();
67 int n;
68 while (scanf ("%d", &n) == 1)
69 {
70 int ans = 0;
71 for (int i=1; i<=9; ++i)
72 {
73 for (int j=0; j<=9; ++j)
74 ans = (ans + dp[n][i][j]) % MOD;
75 }
76
77 printf ("%d\n", ans);
78 }
79
80 return 0;
81 }