// Original C++ solution (slower):
#include <bits/stdc++.h>



using namespace std;



#define ALL(x) (x).begin(), (x).end()

#define ALLTRUE(xs) all_of(ALL(xs),[](bool x){return x;})

#define AND(x,y,z) set_intersection((x).begin(),(x).end(),(y).begin(),(y).end(),inserter((z),(z).end()))

#define ANYTRUE(xs) any_of(ALL(xs),[](bool x){return x;})

#define CONCAT(x,y) (x).insert((x).end(),(y).begin(),(y).end())

#define DUMP(xs) for (auto x:xs) cout<<x<<' ';cout<<endl

#define DUMPP(xs) for (auto x:xs) cout<<'('<<x.first<<','<<x.second<<')';cout<<endl

#define FOR(i,a,b) for (ll i=(ll)(a);i<(ll)(b);++i)

#define OR(x,y,z) set_union((x).begin(),(x).end(),(y).begin(),(y).end(),inserter((z),(z).end()))

#define OUT(x) cout<<x<<endl

#define REP(i,n) FOR(i,0,n)



typedef long long ll;

typedef pair<ll, ll> P;



struct edge { int to,cost; };

const int MOD=1e9+7;



int N;

vector<char> cs{'A','C','G','T'};

vector<map<string, ll>> memo;



bool checker(string last4) {

  REP(i,4) {

    string tmp = last4;

    if (i>0) swap(tmp[i-1],tmp[i]);

    if (tmp.find("AGC")!=string::npos) return false;

  }

  return true;

}



ll dfs(int cur, string last3) {

  if (memo[cur][last3]) return memo[cur][last3];

  if (cur==N) return 1;



  ll ret = 0;

  for (char c:cs) {

    if (checker(last3+c)) {

      ret = (ret+dfs(cur+1,last3.substr(1,2)+c))%MOD;

    }

  }

  memo[cur][last3] = ret;

  return ret;

}



int main() {

  cin>>N;

  memo.resize(N+1);

  OUT(dfs(0,"TTT"));



  return 0;

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>



using namespace std;



#define ALL(x) (x).begin(), (x).end()

#define ALLTRUE(xs) all_of(ALL(xs),[](bool x){return x;})

#define AND(x,y,z) set_intersection((x).begin(),(x).end(),(y).begin(),(y).end(),inserter((z),(z).end()))

#define ANYTRUE(xs) any_of(ALL(xs),[](bool x){return x;})

#define CONCAT(x,y) (x).insert((x).end(),(y).begin(),(y).end())

#define DUMP(xs) for (auto x:xs) cout<<x<<' ';cout<<endl

#define DUMPP(xs) for (auto x:xs) cout<<'('<<x.first<<','<<x.second<<')';cout<<endl

#define FOR(i,a,b) for (ll i=(ll)(a);i<(ll)(b);++i)

#define OR(x,y,z) set_union((x).begin(),(x).end(),(y).begin(),(y).end(),inserter((z),(z).end()))

#define OUT(x) cout<<x<<endl

#define REP(i,n) FOR(i,0,n)



typedef long long ll;

typedef pair<ll, ll> P;



struct edge { int to,cost; };

const int MOD=1e9+7;



int N;

vector<char> cs{'A','C','G','T'};

set<string> outs{"AGGC","ATGC","AGTC"};

vector<map<string, ll>> memo;



bool checker(string last4) {

  return outs.find(last4)==outs.end();

}



ll dfs(int cur, string last3) {

  if (memo[cur][last3]) return memo[cur][last3];

  if (cur==N) return 1;



  ll ret = 0;

  for (char c:cs) {

    if (checker(last3+c)) {

      ret = (ret+dfs(cur+1,last3.substr(1,2)+c))%MOD;

    }

  }

  memo[cur][last3] = ret;

  return ret;

}



int main() {

  cin>>N;

  memo.resize(N+1);



  // 並べ替えでアウトも含めて以下の文字列が出てきたらだめ

  // AGC

  // ACG

  // GAC

  // AGGC

  // AGTC

  // ATGC

  vector<string> out_three{"AGC","GAC","ACG"};

  for (string ot:out_three) {

    for (char c:cs) outs.insert(c+ot);

  }

  OUT(dfs(0,"TTT"));



  return 0;

}

// Fastest known solution for this problem: