#include <bits/stdc++.h>
template <class C, class E>
inline bool contains(const C& container, const E& element) {
  return container.find(element) != container.end();
}
template <class T>
inline void checkmin(T& a, T b) {
  if (b < a) a = b;
}
template <class T>
inline void checkmax(T& a, T b) {
  if (b > a) a = b;
}
using namespace std;
long long InverseIncImp(long long x, long long minV, long long maxV,
                        std::function<long long(long long)> func) {
  if (func(minV) == x) return minV;
  if (func(maxV) == x) return maxV;
  long long minLess = minV, maxGreater = maxV;
  while (minLess < maxGreater) {
    long long mid = minLess + (maxGreater - minLess) / 2;
    long long midFunc = func(mid);
    if ((midFunc <= x) && (x < func(mid + 1))) return mid;
    if (midFunc > x)
      maxGreater = mid - 1;
    else
      minLess = mid + 1;
  }
  return minLess;
}
long long Int3SqrtImp(long long x) {
  return InverseIncImp(x, 0, 1260000, [=](long long v) { return v * v * v; });
}
long long IntSqrtImp(long long x) {
  return InverseIncImp(x, 0, 1420000000, [=](long long v) { return v * v; });
}
long long IntSqrt(long long x) {
  long long res = IntSqrtImp(x);
  if (res * res == x)
    return res;
  else
    return -1;
}
long long Int3Sqrt(long long x) {
  long long res = Int3SqrtImp(x);
  if (res * res * res == x)
    return res;
  else
    return -1;
}
long long Int4Sqrt(long long x) {
  long long res = IntSqrt(x);
  if (res != -1) {
    res = IntSqrt(res);
    if (res != -1) return res;
  }
  return -1;
}
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);
}
long long mod(long long a, long long b) {
  assert(b != 0);
  long long r = a % b;
  return r >= 0 ? r : r + std::abs(b);
}
struct MI {
  MI() : _val(0) {}
  MI(long long val) : _val(mod(val, 998244353LL)) {}
  MI operator*(MI other) { return MI(_val * other._val); }
  MI operator*=(MI other) { return *this = *this * other; }
  MI operator+(MI other) { return MI(_val + other._val); }
  MI operator+=(MI other) { return *this = *this + other; }
  MI operator-(MI other) { return MI(_val + (998244353LL - other._val)); }
  MI operator-=(MI other) { return *this = *this - other; }
  long long Val() { return _val; }

 private:
  long long _val;
};
vector<long long> d;
map<long long, long long> known;
map<long long, int> unknowns;
void CheckPrimes(list<long long> pending) {
  while (!pending.empty()) {
    auto primeToTest = pending.front();
    pending.pop_front();
    for (auto itUnk = unknowns.begin(); itUnk != unknowns.end();) {
      if (itUnk->first % primeToTest == 0) {
        long long other = itUnk->first / primeToTest;
        known[primeToTest] += itUnk->second;
        if (known[other] == 0) pending.push_back(other);
        known[other] += itUnk->second;
        itUnk = unknowns.erase(itUnk);
      } else
        itUnk++;
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  cout << std::setprecision(15);
  cout << std::fixed;
  int n;
  cin >> n;
  for (int i = (0), _b = ((n)-1); i <= _b; i++) {
    long long num;
    cin >> num;
    long long test = Int4Sqrt(num);
    if (test != -1)
      known[test] += 4;
    else {
      test = IntSqrt(num);
      if (test != -1)
        known[test] += 2;
      else {
        test = Int3Sqrt(num);
        if (test != -1)
          known[test] += 3;
        else
          unknowns[num]++;
      }
    }
  }
  {
    list<long long> pending;
    for (auto kno : known) pending.push_back(kno.first);
    CheckPrimes(pending);
  }
  MI res(1);
  while (!unknowns.empty()) {
    auto unk = *unknowns.begin();
    bool broke = false;
    for (auto otherUnk : unknowns) {
      if (otherUnk.first != unk.first) {
        long long g = gcd(unk.first, otherUnk.first);
        if (g != 1) {
          list<long long> pending;
          pending.push_back(unk.first / g);
          pending.push_back(otherUnk.first / g);
          pending.push_back(g);
          CheckPrimes(pending);
          broke = true;
          break;
        }
      }
    }
    if (!broke) {
      unknowns.erase(unknowns.begin());
      res *= (unk.second + 1);
      res *= (unk.second + 1);
    }
  }
  for (auto kno : known) res *= (kno.second + 1);
  cout << res.Val();
  return 0;
}
