public class Solution {
static final int M = 1000000007;
public int checkRecord(int n) {
long[] PorL = new long[n + 1]; // ending with P or L, no A
long[] P = new long[n + 1]; // ending with P, no A
PorL[0] = P[0] = 1; PorL[1] = 2; P[1] = 1;
for (int i = 2; i <= n; i++) {
P[i] = PorL[i - 1];
PorL[i] = (P[i] + P[i - 1] + P[i - 2]) % M;
}
long res = PorL[n];
for (int i = 0; i < n; i++) { // inserting A into (n-1)-length strings
long s = (PorL[i] * PorL[n - i - 1]) % M;
res = (res + s) % M;
}
return (int) res;
}
}
public class Solution {
final int MOD = 1000000007;
final int M = 6;
int[][] mul(int[][] A, int[][] B) {
int[][] C = new int[M][M];
for (int i = 0; i < M; i++)
for (int j = 0; j < M; j++)
for (int k = 0; k < M; k++)
C[i][j] = (int) ((C[i][j] + (long) A[i][k] * B[k][j]) % MOD);
return C;
}
int[][] pow(int[][] A, int n) {
int[][] res = new int[M][M];
for (int i = 0; i < M; i++)
res[i][i] = 1;
while (n > 0) {
if (n % 2 == 1)
res = mul(res, A);
A = mul(A, A);
n /= 2;
}
return res;
}
public int checkRecord(int n) {
int[][] A = {
{0, 0, 1, 0, 0, 0},
{1, 0, 1, 0, 0, 0},
{0, 1, 1, 0, 0, 0},
{0, 0, 1, 0, 0, 1},
{0, 0, 1, 1, 0, 1},
{0, 0, 1, 0, 1, 1},
};
return pow(A, n + 1)[5][2];
}
}