#include <cstdio>
#include <cstdint>
#include <cassert>
#include <vector>
#include <string>
#include <algorithm>
#include <utility>
#include <type_traits>

constexpr intmax_t  operator ""_jd(unsigned long long n) { return n; }
constexpr uintmax_t operator ""_ju(unsigned long long n) { return n; }
constexpr size_t    operator ""_zu(unsigned long long n) { return n; }
// constexpr ptrdiff_t operator ""_td(unsigned long long n) { return n; }

namespace detail {
template <typename Tp, size_t N>
std::vector<Tp> make_vector(
    std::vector<size_t>& sizes,
    typename std::enable_if<(N == 1), Tp const&>::type x
) {
  return std::vector<Tp>(sizes[0], x);
}
template <typename Tp, size_t N>
auto make_vector(
    std::vector<size_t>& sizes,
    typename std::enable_if<(N > 1), Tp const&>::type x
) {
  size_t size = sizes[N-1];
  sizes.pop_back();
  return std::vector<decltype(make_vector<Tp, N-1>(sizes, x))>(
      size, make_vector<Tp, N-1>(sizes, x)
  );
}
}  // detail::

template <typename Tp, size_t N>
auto make_vector(size_t const(&sizes)[N], Tp const& x) {
  std::vector<size_t> s(N);
  for (size_t i = 0; i < N; ++i) s[i] = sizes[N-i-1];
  return detail::make_vector<Tp, N>(s, x);
}

template <typename Tp, Tp modulo>
class modint {
  // FIXME to implement with Montgomery multiplication

public:
  using value_type = typename std::make_signed<Tp>::type;

private:
  static constexpr value_type S_mod = modulo;
  value_type M_value = 0;
  value_type M_mod;  // runtime value (used if S_mod == 0)

  static constexpr value_type S_normalize(value_type n) {
    if ((n %= S_mod) < 0) n += S_mod;
    return n;
  }

  static constexpr value_type S_normalize(value_type n, value_type m) {
    if ((n %= m) < 0) n += m;
    return n;
  }

  static constexpr value_type S_gcd(
      value_type a, value_type b, value_type& x, value_type& y
  ) {
    x = 1;
    y = 0;
    for (value_type u = y, v = x; a;) {
      value_type q = b / a;
      std::swap(x -= q*u, u);
      std::swap(y -= q*v, v);
      std::swap(b -= q*a, a);
    }
    return b;
  }

  static constexpr value_type S_inv(value_type n) {
    value_type x, y;
    S_gcd(n, S_mod, x, y);
    if ((x %= S_mod) < 0) x += S_mod;
    return x;
  }

  static constexpr value_type S_inv(value_type n, value_type m) {
    value_type x, y;
    S_gcd(n, m, x, y);
    if ((x %= m) < 0) x += m;
    return x;
  }

public:
  modint() = default;
  modint(modint const&) = default;
  modint(modint&&) = default;
  modint(value_type n): M_value(S_normalize(n)) {
    assert(S_mod > 0);
  }
  modint(value_type n, value_type m): M_value(S_normalize(n, m)), M_mod(m) {
    assert(S_mod == 0);
    assert(m > 0);
  }

  modint& operator =(modint const&) = default;
  modint& operator =(modint&&) = default;
  modint& operator =(value_type n) {
    M_value = S_normalize(n, S_mod);
    return *this;
  }

  modint& operator +=(modint const& other) {
    if (S_mod > 0) {
      if ((M_value += other.M_value) >= S_mod) M_value -= S_mod;
    } else {
      assert(M_mod == other.M_mod);
      if ((M_value += other.M_value) >= M_mod) M_value -= M_mod;
    }
    return *this;
  }
  modint& operator -=(modint const& other) {
    if (S_mod > 0) {
      if ((M_value -= other.M_value) < 0) M_value += S_mod;
    } else {
      assert(M_mod == other.M_mod);
      if ((M_value -= other.M_value) < 0) M_value += M_mod;
    }
    return *this;
  }
  modint& operator *=(modint const& other) {
    if (S_mod > 0) {
      (M_value *= other.M_value) %= S_mod;
    } else {
      assert(M_mod == other.M_mod);
      (M_value *= other.M_value) %= M_mod;
    }
    return *this;
  }
  modint& operator /=(modint const& other) {
    if (S_mod > 0) {
      (M_value *= S_inv(other.M_value)) %= S_mod;
    } else {
      assert(M_mod == other.M_mod);
      (M_value *= S_inv(other.M_value, M_mod)) %= M_mod;
    }
    return *this;
  }

  modint& operator +=(value_type const& n) {
    if (S_mod > 0) return (*this += modint(n));
    return (*this += modint(n, M_mod));
  }
  modint& operator -=(value_type const& n) {
    if (S_mod > 0) return (*this -= modint(n));
    return (*this -= modint(n, M_mod));
  }
  modint& operator *=(value_type const& n) {
    if (S_mod > 0) return (*this *= modint(n));
    return (*this *= modint(n, M_mod));
  }
  modint& operator /=(value_type const& n) {
    if (S_mod > 0) return (*this /= modint(n));
    return (*this /= modint(n, M_mod));
  }

  modint operator +(modint const& other) const { return modint(*this) += other; }
  modint operator -(modint const& other) const { return modint(*this) -= other; }
  modint operator *(modint const& other) const { return modint(*this) *= other; }
  modint operator /(modint const& other) const { return modint(*this) /= other; }
  modint operator +(value_type const& n) const { return modint(*this) += n; }
  modint operator -(value_type const& n) const { return modint(*this) -= n; }
  modint operator *(value_type const& n) const { return modint(*this) *= n; }
  modint operator /(value_type const& n) const { return modint(*this) /= n; }

  modint operator +() const { return *this; }
  modint operator -() const {
    if (S_mod > 0) return modint(0) -= *this;
    return modint(0, M_mod) -= *this;
  }

  modint pow(intmax_t iexp) const {
    modint res = ((S_mod > 0)? modint(1): modint(1, M_mod));
    for (modint dbl = *this; iexp; iexp >>= 1) {
      if (iexp & 1) res *= dbl;
      dbl *= dbl;
    }
    return res;
  }
  modint& pow_eq(intmax_t iexp) { return *this = this->pow(iexp); }

  value_type get() const { return M_value; }
};

template <typename Tp>
class range {
public:
  using value_type = Tp;
  using difference_type = typename std::make_signed<value_type>::type;

private:
  value_type M_start = 0;
  value_type M_stop;
  difference_type M_stride = 1;
  bool M_fail = false;

public:
  range(value_type stop): M_stop(stop) {}
  range(value_type start, value_type stop, difference_type stride = 1):
    M_start(start), M_stop(stop), M_stride(stride)
  {}

  class iterator {
  public:
    using value_type = Tp;
    using difference_type = typename std::make_signed<value_type>::type;

  private:
    value_type M_start, M_stop;
    difference_type M_stride;
    value_type M_index;
    bool M_fail = false;
    static constexpr value_type S_min = std::numeric_limits<value_type>::min();
    static constexpr value_type S_max = std::numeric_limits<value_type>::max();

  public:
    iterator(value_type start, value_type stop, difference_type stride,
             value_type index):
      M_start(start), M_stop(stop), M_stride(stride), M_index(index)
    {}
    value_type operator *() const { return M_index; }
    iterator& operator ++() {
      if ((0 < M_stride && __builtin_add_overflow(M_index, M_stride, &M_index))
          || (M_stride < 0 && __builtin_sub_overflow(M_index, -M_stride, &M_index)))
        M_fail = true;
      return *this;
    }
    bool operator !=(iterator const& other) const {
      if (M_fail || other.M_fail) return false;

      if (0 < M_stride && M_stop == S_min) return !M_fail;
      if (M_stride < 0 && M_stop == S_max) return !M_fail;
      return ((0 < M_stride && M_index < M_stop)
              || (M_stride < 0 && M_stop < M_index));
    }
  };

  iterator begin() const { return iterator(M_start, M_stop, M_stride, M_start); }
  iterator end() const { return iterator(M_start, M_stop, M_stride, M_stop); }
};

constexpr intmax_t mod = 1'000'000'007;  // '
using mi = modint<intmax_t, mod>;

bool valid(size_t i0, size_t i1, size_t i2, size_t i3) {
  enum: size_t {T, A, G, C};

  // AGC
  // AXGC (ACGC, ATGC, AGGC)
  // AGXC (AGAC, AGTC)
  // GAC
  // ACG

  if (i1 == A && i2 == G && i3 == C) return false;
  if (i0 == A && i2 == G && i3 == C) return false;
  if (i0 == A && i1 == G && i3 == C) return false;
  if (i1 == G && i2 == A && i3 == C) return false;
  if (i1 == A && i2 == C && i3 == G) return false;
  return true;
}

int main() {
  size_t n;
  scanf("%zu", &n);

  auto dp = make_vector<mi>({n, 4_zu, 4_zu, 4_zu}, mi(0));
  for (size_t j = 0; j < 4; ++j) dp[0][0][0][j] = 1;
  for (size_t i = 1; i < n; ++i)
    for (auto j0: range<size_t>(4_zu))
      for (auto j1: range<size_t>(4_zu))
        for (auto j2: range<size_t>(4_zu))
          for (auto j3: range<size_t>(4_zu)) {
            if (!valid(j0, j1, j2, j3)) continue;
            dp[i][j1][j2][j3] += dp[i-1][j0][j1][j2];
          }

  mi res = 0;
  for (auto j0: range<size_t>(4_zu))
    for (auto j1: range<size_t>(4_zu))
      for (auto j2: range<size_t>(4_zu))
        res += dp[n-1][j0][j1][j2];

  printf("%jd\n", res.get());
}


Measured memory_bytes: 384