#include <bits/stdc++.h>
using namespace std;
const int inf = (1 << 28);
const double eps = 1e-9;
const double pi = acos(-1.0);
template <class T>
T lowbit(const T &n) {
  return (n ^ (n - 1)) & n;
}
template <class T>
int countbit(const T &n) {
  return (n == 0) ? 0 : (countbit(n & (n - 1)) + 1);
}
template <class T>
inline T sqr(T x) {
  return x * x;
}
template <class T>
inline T abs(T x) {
  return x < 0 ? -x : x;
}
template <class T>
inline void checkmin(T &a, const T &b) {
  if (b < a) a = b;
}
template <class T>
inline void checkmax(T &a, const T &b) {
  if (b > a) a = b;
}
double distR(double x1, double y1, double x2, double y2) {
  return sqr(x1 - x2) + sqr(y1 - y2);
}
double dist(double x1, double y1, double x2, double y2) {
  return sqrt(sqr(x1 - x2) + sqr(y1 - y2));
}
template <class T>
T cross(T x0, T y0, T x1, T y1, T x2, T y2) {
  return (x1 - x0) * (y2 - y0) - (x2 - x0) * (y1 - y0);
}
int crossOper(double x0, double y0, double x1, double y1, double x2,
              double y2) {
  double t = (x1 - x0) * (y2 - y0) - (x2 - x0) * (y1 - y0);
  if (fabs(t) <= eps) return 0;
  return (t < 0) ? -1 : 1;
}
bool isIntersect(double x1, double y1, double x2, double y2, double x3,
                 double y3, double x4, double y4) {
  return crossOper(x1, y1, x2, y2, x3, y3) * crossOper(x1, y1, x2, y2, x4, y4) <
             0 &&
         crossOper(x3, y3, x4, y4, x1, y1) * crossOper(x3, y3, x4, y4, x2, y2) <
             0;
}
bool isMiddle(long long m, long long l, long long h) {
  if (m >= l && m < h) return true;
  return false;
}
bool isMiddlei(long long m, long long l, long long h) {
  if (m >= l && m <= h) return true;
  return false;
}
bool isMiddle(double s, double m, double t) {
  return fabs(s - m) <= eps || fabs(t - m) <= eps || (s < m) != (t < m);
}
template <class T>
inline T gcd2(T a, T b, T &x, T &y) {
  if (a < 0) {
    T d = gcd2(-a, b, x, y);
    x = -x;
    return d;
  }
  if (b < 0) {
    T d = gcd2(a, -b, x, y);
    y = -y;
    return d;
  }
  if (b == 0) {
    x = 1;
    y = 0;
    return a;
  } else {
    T d = gcd2(b, a % b, x, y);
    T t = x;
    x = y;
    y = t - (a / b) * y;
    return d;
  }
}
template <class T>
inline T gcd(T a, T b) {
  if (a < 0) return gcd(-a, b);
  if (b < 0) return gcd(a, -b);
  return (b == 0) ? a : gcd(b, a % b);
}
template <class T>
inline T lcm(T a, T b) {
  if (a < 0) return lcm(-a, b);
  if (b < 0) return lcm(a, -b);
  return a * (b / gcd(a, b));
}
template <class T>
inline vector<pair<T, int> > factorize(T n) {
  vector<pair<T, int> > R;
  for (T i = 2; n > 1;) {
    if (n % i == 0) {
      int C = 0;
      for (; n % i == 0; C++, n /= i)
        ;
      R.push_back(make_pair(i, C));
    }
    i++;
    if (i > n / i) i = n;
  }
  if (n > 1) R.push_back(make_pair(n, 1));
  return R;
}
template <class T>
inline T checkMod(T n, T m) {
  return (n % m + m) % m;
}
template <class T>
inline T multiplyMod(T a, T b, T m) {
  return (
      T)((((long long)(a) * (long long)(b) % (long long)(m)) + (long long)(m)) %
         (long long)(m));
}
template <class T>
inline bool isPrime(T n) {
  if (n <= 1) return false;
  for (T i = 2; i * i <= n; i++)
    if (n % i == 0) return false;
  return true;
}
template <class T>
inline T powerMod(T p, int e, T m) {
  if (e == 0)
    return 1 % m;
  else if (e % 2 == 0) {
    T t = powerMod(p, e / 2, m);
    return multiplyMod(t, t, m);
  } else
    return multiplyMod(powerMod(p, e - 1, m), p, m);
}
const int MaxMatrixSize = 40;
template <class T>
inline void showMatrix(int n, T A[MaxMatrixSize][MaxMatrixSize]) {
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) cout << A[i][j] << ',';
    cout << endl;
  }
}
template <class T>
inline void identityMatrix(int n, T A[MaxMatrixSize][MaxMatrixSize]) {
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++) A[i][j] = (i == j) ? 1 : 0;
}
template <class T>
inline void addMatrix(int n, T C[MaxMatrixSize][MaxMatrixSize],
                      T A[MaxMatrixSize][MaxMatrixSize],
                      T B[MaxMatrixSize][MaxMatrixSize]) {
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++) C[i][j] = A[i][j] + B[i][j];
}
template <class T>
inline void subMatrix(int n, T C[MaxMatrixSize][MaxMatrixSize],
                      T A[MaxMatrixSize][MaxMatrixSize],
                      T B[MaxMatrixSize][MaxMatrixSize]) {
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++) C[i][j] = A[i][j] - B[i][j];
}
template <class T>
inline void mulMatrix(int n, T C[MaxMatrixSize][MaxMatrixSize],
                      T _A[MaxMatrixSize][MaxMatrixSize],
                      T _B[MaxMatrixSize][MaxMatrixSize]) {
  T A[MaxMatrixSize][MaxMatrixSize], B[MaxMatrixSize][MaxMatrixSize];
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
      A[i][j] = _A[i][j], B[i][j] = _B[i][j], C[i][j] = 0;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
      for (int k = 0; k < n; k++) C[i][j] += A[i][k] * B[k][j];
}
template <class T>
inline void addModMatrix(int n, T m, T C[MaxMatrixSize][MaxMatrixSize],
                         T A[MaxMatrixSize][MaxMatrixSize],
                         T B[MaxMatrixSize][MaxMatrixSize]) {
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++) C[i][j] = checkMod(A[i][j] + B[i][j], m);
}
template <class T>
inline void subModMatrix(int n, T m, T C[MaxMatrixSize][MaxMatrixSize],
                         T A[MaxMatrixSize][MaxMatrixSize],
                         T B[MaxMatrixSize][MaxMatrixSize]) {
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++) C[i][j] = checkMod(A[i][j] - B[i][j], m);
}
template <class T>
inline void mulModMatrix(int n, T m, T C[MaxMatrixSize][MaxMatrixSize],
                         T _A[MaxMatrixSize][MaxMatrixSize],
                         T _B[MaxMatrixSize][MaxMatrixSize]) {
  T A[MaxMatrixSize][MaxMatrixSize], B[MaxMatrixSize][MaxMatrixSize];
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
      A[i][j] = _A[i][j], B[i][j] = _B[i][j], C[i][j] = 0;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
      for (int k = 0; k < n; k++)
        C[i][j] = (C[i][j] + multiplyMod(A[i][k], B[k][j], m)) % m;
}
template <class T>
inline void powerMatrix(int n, T p, T C[MaxMatrixSize][MaxMatrixSize],
                        T _A[MaxMatrixSize][MaxMatrixSize]) {
  if (p == 0) {
    identityMatrix(n, C);
    return;
  }
  T B[MaxMatrixSize][MaxMatrixSize];
  powerMatrix(n, p / 2, B, _A);
  mulMatrix(n, C, B, B);
  if (p % 2) {
    memcpy(B, C, sizeof(B));
    mulMatrix(n, C, B, _A);
  }
}
template <class T>
inline void powerModMatrix(int n, T p, T m, T C[MaxMatrixSize][MaxMatrixSize],
                           T _A[MaxMatrixSize][MaxMatrixSize]) {
  if (p == 0) {
    identityMatrix(n, C);
    return;
  }
  T B[MaxMatrixSize][MaxMatrixSize];
  powerModMatrix(n, p / 2, m, B, _A);
  mulModMatrix(n, m, C, B, B);
  if (p % 2) {
    memcpy(B, C, sizeof(B));
    mulModMatrix(n, m, C, B, _A);
  }
}
template <class T>
struct Fraction {
  T a, b;
  Fraction(T a = 0, T b = 1);
  string toString();
};
template <class T>
bool operator<(Fraction<T> p, Fraction<T> q) {
  return p.a * q.b < p.b * q.a;
}
template <class T>
bool operator==(Fraction<T> p, Fraction<T> q) {
  return p.a * q.b == p.b * q.a;
}
template <class T>
string Fraction<T>::toString() {
  ostringstream sout;
  sout << a << "/" << b;
  return sout.str();
}
template <class T>
Fraction<T> operator*(Fraction<T> p, Fraction<T> q) {
  return Fraction<T>(p.a * q.a, p.b * q.b);
}
template <class T>
Fraction<T> operator/(Fraction<T> p, Fraction<T> q) {
  return Fraction<T>(p.a * q.b, p.b * q.a);
}
template <class T>
Fraction<T>::Fraction(T a, T b) {
  T d = gcd(a, b);
  a /= d;
  b /= d;
  if (b < 0) a = -a, b = -b;
  this->a = a;
  this->b = b;
}
template <class T>
Fraction<T> operator+(Fraction<T> p, Fraction<T> q) {
  return Fraction<T>(p.a * q.b + q.a * p.b, p.b * q.b);
}
template <class T>
Fraction<T> operator-(Fraction<T> p, Fraction<T> q) {
  return Fraction<T>(p.a * q.b - q.a * p.b, p.b * q.b);
}
template <class T>
int toInt(T n) {
  stringstream ost;
  ost << n;
  int ret;
  ost >> ret;
  return ret;
}
template <class T>
long long toInt64(T n) {
  stringstream ost;
  ost << n;
  long long ret;
  ost >> ret;
  return ret;
}
template <class T>
string toString(T n) {
  stringstream ost;
  ost << n;
  ost.flush();
  return ost.str();
}
template <class T>
double toDouble(T n) {
  stringstream ost;
  ost << n;
  double ret;
  ost >> ret;
  return ret;
}
template <class T>
static void split(const string &s, vector<T> &out) {
  istringstream in(s);
  out.clear();
  copy(istream_iterator<T>(in), istream_iterator<T>(), back_inserter(out));
}
char buffer[10009];
inline void getString() { scanf("%s", &buffer); }
inline void getStringN() { scanf("%[^\n]", buffer); }
inline int getInt() {
  static int ret;
  scanf("%d", &ret);
  return ret;
}
inline long long getInt64() {
  static long long ret;
  scanf("%lld", &ret);
  return ret;
}
inline double getDouble() {
  static double ret;
  scanf("%lf", &ret);
  return ret;
}
template <typename T, typename TT>
ostream &operator<<(ostream &s, pair<T, TT> t) {
  return s << '(' << t.first << ',' << t.second << ')';
}
int main() {
  long long mat[MaxMatrixSize][MaxMatrixSize];
  long long ret[MaxMatrixSize][MaxMatrixSize];
  mat[0][0] = mat[1][1] = 3;
  mat[1][0] = mat[0][1] = 1;
  const long long mod = 1000000007LL;
  long long p;
  cin >> p;
  powerModMatrix(2, p, mod, ret, mat);
  cout << ret[0][0] << endl;
  return 0;
}
