#include <bits/stdc++.h>
using namespace std;
const double PI = acos(-1.0);
const double EPS = (1e-10);
bool comp(unsigned long long x, unsigned long long y) { return x > y; }
int dx[] = {0, 0, 1, -1, 1, 1, -1, -1};
int dy[] = {1, -1, 0, 0, -1, 1, 1, -1};
class UnionFind {
 private:
  vector<int> p, rank;

 public:
  UnionFind(int N) {
    rank.assign(N, 0);
    p.assign(N, 0);
    for (int i = 0; i < N; i++) p[i] = i;
  }
  int findSet(int i) { return (p[i] == i) ? i : (p[i] = findSet(p[i])); }
  bool isSameSet(int i, int j) { return findSet(i) == findSet(j); }
  void unionSet(int i, int j) {
    if (!isSameSet(i, j)) {
      int x = findSet(i), y = findSet(j);
      if (rank[x] > rank[y]) {
        p[y] = x;
      } else {
        p[x] = y;
        if (rank[x] == rank[y]) rank[y]++;
      }
    }
  }
};
struct point {
  double x, y;
  point() { x = y = 0.0; }
  point(double _x, double _y) {
    x = _x;
    y = _y;
  }
  bool operator==(point other) const {
    return (fabs(x - other.x) < EPS && fabs(y - other.y) < EPS);
  }
  double dist(point p1, point p2) { return hypot(p1.x - p2.x, p1.y - p2.y); }
};
struct line {
  double a, b, c;
};
void pointsToLine(point p1, point p2, line &l) {
  if (fabs(p1.x - p2.x) < EPS) {
    l.a = 1.0;
    l.b = 0.0;
    l.c = -p1.x;
  } else {
    l.a = -(double)(p1.y - p2.y) / (p1.x - p2.x);
    l.b = 1.0;
    l.c = -(double)(l.a * p1.x) - p1.y;
  }
}
bool areParallel(line l1, line l2) {
  return (fabs(l1.a - l2.a) < EPS) && (fabs(l1.b - l2.b) < EPS);
}
bool areSame(line l1, line l2) {
  return areParallel(l1, l2) && (fabs(l1.c - l2.c) < EPS);
}
bool areIntersect(line l1, line l2, point &p) {
  if (areParallel(l1, l2)) return false;
  p.x = (l2.b * l1.c - l1.b * l2.c) / (l2.a * l1.b - l1.a * l2.b);
  if (fabs(l1.b) > EPS)
    p.y = -(l1.a * p.x + l1.c);
  else
    p.y = -(l2.a * p.x + l2.c);
  return true;
}
struct vec {
  double x, y;
  vec(double _x, double _y) {
    x = _x;
    y = _y;
  }
};
vec toVec(point a, point b) { return vec(b.x - a.x, b.y - a.y); }
double cross(vec a, vec b) { return a.x * b.y - a.y * b.x; }
bool ccw(point p, point q, point r) {
  return cross(toVec(p, q), toVec(p, r)) > 0;
}
bool colinear(point p, point q, point r) {
  return fabs(cross(toVec(p, q), toVec(p, r))) < EPS;
}
bool isprime(long long n) {
  if (n < 2) return false;
  for (long long i = 2; i * i <= n; i++) {
    if (n % i == 0) {
      return false;
    }
  }
  return true;
}
vector<int> getdividors(int n) {
  vector<int> dividors;
  int i;
  for (i = 1; i * i < n; i++) {
    if (n % i == 0) {
      dividors.push_back(i);
      dividors.push_back(n / i);
    }
  }
  if (i * i == n) dividors.push_back(i);
  return dividors;
}
long long gcd(long long a, long long b) { return b ? gcd(b, a % b) : a; }
long long C(long long a, long long b) {
  if (b > a - b) return C(a, a - b);
  vector<long long> nom, den;
  for (long long i = a; i > a - b; i--) nom.push_back(i);
  for (long long i = 2; i <= b; i++) den.push_back(i);
  long long lenNom = nom.size();
  long long lenDen = den.size();
  for (int i = 0; i < lenNom; i++) {
    for (int j = 0; j < lenDen; j++) {
      long long g = gcd(nom[i], den[j]);
      if (g > 1) {
        nom[i] /= g;
        den[j] /= g;
      }
    }
  }
  long long top = 1;
  long long bot = 1;
  for (int i = 0; i < lenNom; i++) top *= nom[i];
  for (int i = 0; i < lenDen; i++) bot *= den[i];
  return top / bot;
}
vector<int> factorize(long long n) {
  vector<int> factors;
  for (long long i = 2; i * i <= n; i++) {
    while (n % i == 0) factors.push_back(i), n /= i;
  }
  if (n > 1) factors.push_back(n);
  return factors;
}
void solveC() {
  int n;
  cin >> n;
  string s;
  cin >> s;
  vector<int> present(10, 0);
  int maxi = 0;
  for (int i = 0; i < n; i++) {
    int num = (int)(s[i] - '0');
    for (int i = 2; i <= num; i++) {
      vector<int> factors = factorize(i);
      for (int j = 0; j < factors.size(); j++) {
        present[factors[j]]++;
        maxi = max(maxi, factors[j]);
      }
    }
  }
  int lastMinus = 0;
  int minus = 0;
  for (int i = maxi; i >= 2; i--) {
    for (int j = 0; j < present[i]; j++) {
      cout << i;
      for (int fact = 2; fact < i; fact++) {
        vector<int> factors = factorize(fact);
        for (int k = 0; k < factors.size(); k++) present[factors[k]]--;
      }
    }
  }
  cout << endl;
}
int main() {
  solveC();
  return 0;
}

### Prompt

Generate a cpp solution to the following problem:

Drazil is playing a math game with Varda.

Let's define <image> for positive integer x as a product of factorials of its digits. For example, <image>.

First, they choose a decimal number a consisting of n digits that contains at least one digit larger than 1. This number may possibly start with leading zeroes. Then they should find maximum positive number x satisfying following two conditions:

1. x doesn't contain neither digit 0 nor digit 1.

2. <image> = <image>.

Help friends find such number.

Input

The first line contains an integer n (1 ≤ n ≤ 15) — the number of digits in a.

The second line contains n digits of a. There is at least one digit in a that is larger than 1. Number a may possibly contain leading zeroes.

Output

Output a maximum possible integer satisfying the conditions above. There should be no zeroes and ones in this number decimal representation.

Examples

Input

4
1234


Output

33222


Input

3
555


Output

555

Note

In the first case, <image>

### Response

```cpp
#include <bits/stdc++.h>
using namespace std;
const double PI = acos(-1.0);
const double EPS = (1e-10);
bool comp(unsigned long long x, unsigned long long y) { return x > y; }
int dx[] = {0, 0, 1, -1, 1, 1, -1, -1};
int dy[] = {1, -1, 0, 0, -1, 1, 1, -1};
class UnionFind {
 private:
  vector<int> p, rank;

 public:
  UnionFind(int N) {
    rank.assign(N, 0);
    p.assign(N, 0);
    for (int i = 0; i < N; i++) p[i] = i;
  }
  int findSet(int i) { return (p[i] == i) ? i : (p[i] = findSet(p[i])); }
  bool isSameSet(int i, int j) { return findSet(i) == findSet(j); }
  void unionSet(int i, int j) {
    if (!isSameSet(i, j)) {
      int x = findSet(i), y = findSet(j);
      if (rank[x] > rank[y]) {
        p[y] = x;
      } else {
        p[x] = y;
        if (rank[x] == rank[y]) rank[y]++;
      }
    }
  }
};
struct point {
  double x, y;
  point() { x = y = 0.0; }
  point(double _x, double _y) {
    x = _x;
    y = _y;
  }
  bool operator==(point other) const {
    return (fabs(x - other.x) < EPS && fabs(y - other.y) < EPS);
  }
  double dist(point p1, point p2) { return hypot(p1.x - p2.x, p1.y - p2.y); }
};
struct line {
  double a, b, c;
};
void pointsToLine(point p1, point p2, line &l) {
  if (fabs(p1.x - p2.x) < EPS) {
    l.a = 1.0;
    l.b = 0.0;
    l.c = -p1.x;
  } else {
    l.a = -(double)(p1.y - p2.y) / (p1.x - p2.x);
    l.b = 1.0;
    l.c = -(double)(l.a * p1.x) - p1.y;
  }
}
bool areParallel(line l1, line l2) {
  return (fabs(l1.a - l2.a) < EPS) && (fabs(l1.b - l2.b) < EPS);
}
bool areSame(line l1, line l2) {
  return areParallel(l1, l2) && (fabs(l1.c - l2.c) < EPS);
}
bool areIntersect(line l1, line l2, point &p) {
  if (areParallel(l1, l2)) return false;
  p.x = (l2.b * l1.c - l1.b * l2.c) / (l2.a * l1.b - l1.a * l2.b);
  if (fabs(l1.b) > EPS)
    p.y = -(l1.a * p.x + l1.c);
  else
    p.y = -(l2.a * p.x + l2.c);
  return true;
}
struct vec {
  double x, y;
  vec(double _x, double _y) {
    x = _x;
    y = _y;
  }
};
vec toVec(point a, point b) { return vec(b.x - a.x, b.y - a.y); }
double cross(vec a, vec b) { return a.x * b.y - a.y * b.x; }
bool ccw(point p, point q, point r) {
  return cross(toVec(p, q), toVec(p, r)) > 0;
}
bool colinear(point p, point q, point r) {
  return fabs(cross(toVec(p, q), toVec(p, r))) < EPS;
}
bool isprime(long long n) {
  if (n < 2) return false;
  for (long long i = 2; i * i <= n; i++) {
    if (n % i == 0) {
      return false;
    }
  }
  return true;
}
vector<int> getdividors(int n) {
  vector<int> dividors;
  int i;
  for (i = 1; i * i < n; i++) {
    if (n % i == 0) {
      dividors.push_back(i);
      dividors.push_back(n / i);
    }
  }
  if (i * i == n) dividors.push_back(i);
  return dividors;
}
long long gcd(long long a, long long b) { return b ? gcd(b, a % b) : a; }
long long C(long long a, long long b) {
  if (b > a - b) return C(a, a - b);
  vector<long long> nom, den;
  for (long long i = a; i > a - b; i--) nom.push_back(i);
  for (long long i = 2; i <= b; i++) den.push_back(i);
  long long lenNom = nom.size();
  long long lenDen = den.size();
  for (int i = 0; i < lenNom; i++) {
    for (int j = 0; j < lenDen; j++) {
      long long g = gcd(nom[i], den[j]);
      if (g > 1) {
        nom[i] /= g;
        den[j] /= g;
      }
    }
  }
  long long top = 1;
  long long bot = 1;
  for (int i = 0; i < lenNom; i++) top *= nom[i];
  for (int i = 0; i < lenDen; i++) bot *= den[i];
  return top / bot;
}
vector<int> factorize(long long n) {
  vector<int> factors;
  for (long long i = 2; i * i <= n; i++) {
    while (n % i == 0) factors.push_back(i), n /= i;
  }
  if (n > 1) factors.push_back(n);
  return factors;
}
void solveC() {
  int n;
  cin >> n;
  string s;
  cin >> s;
  vector<int> present(10, 0);
  int maxi = 0;
  for (int i = 0; i < n; i++) {
    int num = (int)(s[i] - '0');
    for (int i = 2; i <= num; i++) {
      vector<int> factors = factorize(i);
      for (int j = 0; j < factors.size(); j++) {
        present[factors[j]]++;
        maxi = max(maxi, factors[j]);
      }
    }
  }
  int lastMinus = 0;
  int minus = 0;
  for (int i = maxi; i >= 2; i--) {
    for (int j = 0; j < present[i]; j++) {
      cout << i;
      for (int fact = 2; fact < i; fact++) {
        vector<int> factors = factorize(fact);
        for (int k = 0; k < factors.size(); k++) present[factors[k]]--;
      }
    }
  }
  cout << endl;
}
int main() {
  solveC();
  return 0;
}

```