诶总结晚点发
#include <iostream>
#include <cstdio>
#include <cassert>
#include <cstring>
#define mod 1000000007
#define N 66*2
using namespace std;
int F[10000050],n,p,q,E;
struct Matrix{
int a,d[N][N];
void print() {
for (int i=1;i<=a;i++){
printf("::debug row%d::",i%10);
for (int j=1;j<=a;j++) printf("%d%c",d[i][j],j==a?'\n':' ');
}
for (int i=1;i<=a;i++) printf("-"); puts("");
}
void clear() {
for (int i=1;i<=a;i++)
for (int j=1;j<=a;j++) d[i][j] = 0;
}
}id,A,B;
inline void inc(int &x,int y) { x = (x + y) % mod; }
inline int rd() { int r; scanf("%d",&r); return r; }
Matrix operator* (Matrix p1,Matrix p2) {
Matrix ret = id; ret.a = p1.a;
for (int i=1;i<=p1.a;i++)
for (int j=1;j<=p1.a;j++)
for (int k=1;k<=p1.a;k++) inc( ret.d[i][j] , 1LL * p1.d[i][k] * p2.d[k][j] % mod);
return ret;
}
inline Matrix qp(Matrix a,int b) {
Matrix ret = id; ret.a = a.a;
for (int i=1;i<=ret.a;i++) ret.d[i][i] = 1;
while (b) {
if (b&1) ret = ret * a;
b >>= 1 , a = a * a;
}
return ret;
}
inline void calc() {
A.a = B.a = 2;
A.d[1][1] = 3 , A.d[1][2] = 1;
B.d[1][1] = B.d[1][2] = B.d[2][1] = 1;
B = qp(B,q-2);
A = A * B;
printf("%d\n",A.d[1][1]);
}
inline int momsen(int p1,int p2) {
int R = p2 & 1;
for (int _=1;_<=p;_++) {
int cur = 0;
if ((p1>>_)&1) cur++;
if (R > 0) cur++;
if ((p2>>_)&1) cur++;
if (_==p) {
if (p2&1)
return cur == 1;
else
return cur == 2;
}
if (cur == 3 || cur == 0) return 0;
if (cur == 1) R = 1; else R = 0;
}
assert(0); return 1;
}
inline Matrix get_Matrix() {
Matrix ret = id;
ret.a = E;
for (int i=0;i<E;i++)
for (int j=0;j<E;j++)
ret.d[i+1][j+1] = momsen(i,j);
return ret;
}
inline void solve() {
E = ( 1<<(p+1) );
B = get_Matrix();
// B.print();
B = qp(B,q);
int ans = 0;
// B.print();
for (int _=1;_<=E;_++) inc(ans,B.d[_][_]);
printf("%d\n",ans);
}
int main() {
p = rd() , q = rd();
if (p > q) swap(p,q);
if (p == 1) { puts("1"); return 0; }
if (p == 2) { calc(); return 0; }
solve();
return 0;
}