/*
求二维矩阵的b次幂:(a[x][y]^b) mod p
*/
#include<iostream>
#include<cstring>
using namespace std;
#define ll long long
#define N 2//矩阵列数
//返回值写法
struct node{//用结构体来做返回值,避免直接返回二维数组
ll a[N][N];
};
node multi(node a,node b,ll p){
node t;
memset(t.a,0,sizeof(t.a));
for(int i=0;i<N;++i)//行
for(int j=0;j<N;++j)//列
for(int z=0;z<N;++z)
t.a[i][j]+=a.a[i][z]*b.a[z][j],t.a[i][j]%=p;
return t;
}
ll qpow(node a,ll n,ll p){
node ans;
ans.a[0][0]=1,ans.a[0][1]=0,ans.a[1][0]=0,ans.a[1][1]=1;//单位矩阵
while(n){
if(n&1) ans=multi(ans,a,p);
a=multi(a,a,p);
n>>=1;
}
return ans.a[0][1];
}
//无返回值写法
void multi(ll a[N][N],ll b[N][N],ll p){
ll t[N][N]={0};
for(int i=0;i<N;++i)//行
for(int j=0;j<N;++j)//列
for(int z=0;z<N;++z)
t[i][j]+=a[i][z]*b[z][j];
for(int i=0;i<N;++i)
for(int j=0;j<N;++j)
a[i][j]=t[i][j]%p;
}
ll qpow(ll a[N][N],ll n,ll p){
ll ans[N][N]={{1,0},{0,1}};//单位矩阵
while(n){
if(n&1) multi(ans,a,p);
multi(a,a,p);
n>>=1;
}
return ans[0][1];
}
int main(){
ll a[N][N]={{2,2},{0,1}};
cout<<qpow(a,1000,1007)<<endl;;
node ans;
ans.a[0][0]=2,ans.a[0][1]=2,ans.a[1][0]=0,ans.a[1][1]=1;
cout<<qpow(ans,1000,1007);
return 0;
}