Problem: While walking down the street Vanya saw a label "Hide&Seek". Because he is a programmer, he used & as a bitwise AND for these two words represented as a integers in base 64 and got new word. Now Vanya thinks of some string s and wants to know the number of pairs of words of length |s| (length of s), such that their bitwise AND is equal to s. As this number can be large, output it modulo 109 + 7.

To represent the string as a number in numeral system with base 64 Vanya uses the following rules:

  * digits from '0' to '9' correspond to integers from 0 to 9; 
  * letters from 'A' to 'Z' correspond to integers from 10 to 35; 
  * letters from 'a' to 'z' correspond to integers from 36 to 61; 
  * letter '-' correspond to integer 62; 
  * letter '_' correspond to integer 63. 

Input

The only line of the input contains a single word s (1 ≤ |s| ≤ 100 000), consisting of digits, lowercase and uppercase English letters, characters '-' and '_'.

Output

Print a single integer — the number of possible pairs of words, such that their bitwise AND is equal to string s modulo 109 + 7.

Examples

Input

z


Output

3


Input

V_V


Output

9


Input

Codeforces


Output

130653412

Note

For a detailed definition of bitwise AND we recommend to take a look in the corresponding article in Wikipedia.

In the first sample, there are 3 possible solutions: 

  1. z&_ = 61&63 = 61 = z
  2. _&z = 63&61 = 61 = z
  3. z&z = 61&61 = 61 = z

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
double sqr(double a) { return a * a; }
bool doubleEqual(double a, double b) { return fabs(a - b) < 1e-9; }
bool doubleLessOrEqual(double a, double b) {
  return a < b || doubleEqual(a, b);
}
bool doubleLess(double a, double b) { return a < b && !doubleEqual(a, b); }
bool doubleGreaterOrEqual(double a, double b) {
  return a > b || doubleEqual(a, b);
}
bool doubleGreater(double a, double b) { return a > b && !doubleEqual(a, b); }
double mySqrt(double a) {
  if (doubleLess(a, 0)) throw "sqrt(-1)";
  if (a < 0) return 0;
  return sqrt(a);
}
struct Point {
  double x, y;
  Point() : x(0), y(0) {}
  Point(double x, double y) : x(x), y(y) {}
  void scan() { scanf("%lf %lf", &x, &y); }
  void print() const { printf("%.10lf %.10lf\n", x, y); }
  Point operator+(const Point &p) const { return Point(x + p.x, y + p.y); }
  Point operator-(const Point &p) const { return Point(x - p.x, y - p.y); }
  Point operator-() const { return Point(-x, -y); }
  Point operator*(double k) const { return Point(x * k, y * k); }
  Point operator/(double k) const { return Point(x / k, y / k); }
  double operator%(const Point &p) const { return x * p.x + y * p.y; }
  double operator*(const Point &p) const { return x * p.y - y * p.x; }
  double length() const { return mySqrt(*this % *this); }
  double distTo(const Point &p) const { return (*this - p).length(); }
  double distTo(const Point &A, const Point &B) const {
    double d = A.distTo(B);
    if (doubleEqual(d, 0)) {
      throw "A = B";
    }
    double s = (*this - A) * (*this - B);
    return fabs(s) / d;
  }
  Point normalize(double k = 1) const {
    double len = length();
    if (doubleEqual(len, 0)) {
      if (doubleEqual(k, 0)) {
        return Point();
      }
      throw "zero-size vector";
    }
    return *this * (k / len);
  }
  Point getH(const Point &A, const Point &B) const {
    Point C = *this;
    Point v = B - A;
    Point u = C - A;
    double k = v % u / v.length();
    v = v.normalize(k);
    Point H = A + v;
    return H;
  }
  Point rotate() const { return Point(-y, x); }
  Point rotate(double alpha) const { return rotate(cos(alpha), sin(alpha)); }
  Point rotate(double cosa, double sina) const {
    Point v = *this;
    Point u = v.rotate();
    Point w = v * cosa + u * sina;
    return w;
  }
  bool isZero() const { return doubleEqual(x, 0) && doubleEqual(y, 0); }
  bool isOnline(const Point &A, const Point &B) const {
    return doubleEqual((A - *this) * (B - *this), 0);
  }
  bool isInSegment(const Point &A, const Point &B) const {
    return doubleLessOrEqual((A - *this) % (B - *this), 0);
  }
  bool isInSegmentStricly(const Point &A, const Point &B) const {
    return doubleLess((A - *this) % (B - *this), 0);
  }
  double getAngle() const { return atan2(y, x); }
  double getAngle(Point u) const { return atan2(*this * u, *this % u); }
};
int getIntersection(const Point &A, const Point &B, const Point &C,
                    const Point &D, Point &O) {
  Point v = B - A;
  double s1 = (C - A) * (D - A);
  double s2 = (D - B) * (C - B);
  double s = s1 + s2;
  if (doubleEqual(s, 0)) {
    if (!A.isOnline(C, D)) return 0;
    return 2;
  }
  v = v / s;
  v = v * s1;
  O = A + v;
  return 1;
}
int getIntersection(const Point &A, double rA, const Point &B, double rB,
                    Point &M, Point &N) {
  double d = A.distTo(B);
  if (doubleLess(rA + rB, d) || doubleLess(d, fabs(rA - rB))) {
    return 0;
  }
  double a = (sqr(rA) - sqr(rB) + sqr(d)) / 2 / d;
  double h = mySqrt(sqr(rA) - sqr(a));
  Point v = B - A;
  Point u = v.rotate();
  v = v.normalize(a);
  u = u.normalize(h);
  Point H = A + v;
  M = H + u;
  N = H - u;
  if (u.isZero()) return 1;
  return 2;
}
int getIntersection(const Point &A, const Point &B, const Point &O, double r,
                    Point &M, Point &N) {
  double h = O.distTo(A, B);
  if (doubleLess(r, h)) {
    return 0;
  }
  Point H = O.getH(A, B);
  Point v = B - A;
  double k = mySqrt(sqr(r) - sqr(h));
  v = v.normalize(k);
  M = H + v;
  N = H - v;
  if (v.isZero()) return 1;
  return 2;
}
struct cmp {
  bool operator()(const string &a, const string &b) { return a + b < b + a; }
};
long long GCD(long long a, long long b) { return (!b ? a : GCD(b, a % b)); }
long long POW(long long a, long long b) {
  long long res = 1;
  while (b) {
    if (b % 2) res = (res * a) % 1000000007;
    a = (a * a) % 1000000007;
    b /= 2;
  }
  return res % 1000000007;
}
int main() {
  ifstream fin("file.in");
  ofstream fout("file.out");
  cin.sync_with_stdio(false);
  cout.sync_with_stdio(false);
  fin.sync_with_stdio(false);
  fout.sync_with_stdio(false);
  long long n, k, x, m, p, q, h, a, b, res = 1, fres = 10e9;
  bool boo;
  string s;
  long long mas[1000002]{};
  string ss;
  cin >> s;
  for (int i = '0'; i <= '9'; i++) ss.push_back(i);
  for (int i = 'A'; i <= 'Z'; i++) ss.push_back(i);
  for (int i = 'a'; i <= 'z'; i++) ss.push_back(i);
  ss.push_back('-');
  ss.push_back('_');
  for (int i = 0; i < 64; i++) {
    mas[ss[i]] = i;
  }
  for (int i = 0; i < s.length(); i++) {
    for (int j = 0; j < 6; j++) {
      if (!(mas[s[i]] & (1 << j))) res = res * 3 % 1000000007;
    }
  }
  cout << res;
  fin.close();
  fout.close();
  return 0;
}