#include <bits/stdc++.h>
namespace modular {
const int MOD = 1000000007;
inline int add(int x, int y) { return (x += y) >= MOD ? x -= MOD : x; }
inline void inc(int &x, int y) { (x += y) >= MOD ? x -= MOD : 0; }
inline int mul(int x, int y) { return 1LL * x * y % MOD; }
inline int qpow(int x, int y) {
  int ans = 1;
  for (; y; y >>= 1, x = mul(x, x))
    if (y & 1) ans = mul(ans, x);
  return ans;
}
};  // namespace modular
using namespace modular;
namespace Base {
template <typename Tp>
inline Tp input() {
  Tp x = 0, y = 1;
  char c = getchar();
  while ((c < '0' || '9' < c) && c != EOF) {
    if (c == '-') y = -1;
    c = getchar();
  }
  if (c == EOF) return 0;
  while ('0' <= c && c <= '9') x = x * 10 + c - '0', c = getchar();
  return x *= y;
}
template <typename Tp>
inline void read(Tp &x) {
  x = input<Tp>();
}
template <typename Tp>
inline void chmax(Tp &x, Tp y) {
  x < y ? x = y : 0;
}
template <typename Tp>
inline void chmin(Tp &x, Tp y) {
  x > y ? x = y : 0;
}
};  // namespace Base
using namespace Base;
int N, tot;
int a[3007], b[3007];
int f[3007], g[3007], h[3007];
int C[3007][3007], fac[3007];
void init() {
  int MX = 3000;
  C[0][0] = 1;
  for (int i = 1; i <= MX; ++i) {
    C[i][0] = 1;
    for (int j = 1; j <= i; ++j) C[i][j] = add(C[i - 1][j - 1], C[i - 1][j]);
  }
  fac[0] = 1;
  for (int i = 1; i <= MX; ++i) fac[i] = mul(fac[i - 1], i);
}
void solve() {
  f[0] = 1;
  int tmp = 0;
  for (int i = 1; i <= tot; ++i) {
    for (int j = 1; j <= b[i]; ++j)
      g[j] = C[b[i] - 1][b[i] - j], (b[i] - j) & 1 ? g[j] = MOD - g[j] : 0;
    for (int j = 0; j <= tmp + b[i]; ++j) h[j] = 0;
    for (int j = b[i]; j >= 1; --j) {
      for (int k = tmp; k >= 0; --k)
        inc(h[j + k], mul(mul(g[j], f[k]), C[j + k][j]));
    }
    tmp += b[i];
    for (int j = 0; j <= tmp; ++j) f[j] = h[j];
  }
  int res = 0;
  for (int i = 1; i <= tmp; ++i) inc(res, f[i]);
  for (int i = 1; i <= tot; ++i) res = mul(res, fac[b[i]]);
  printf("%d\n", res);
}
int main() {
  init();
  read(N);
  for (int i = 1; i <= N; ++i) {
    read(a[i]);
    for (int j = 2, tmp = j * j; j * j <= a[i]; ++j, tmp = j * j)
      while (a[i] % tmp == 0) a[i] /= tmp;
  }
  std::sort(a + 1, a + N + 1);
  for (int i = 1; i <= N; ++i) {
    b[++tot] = 1;
    int tmp = a[i];
    while (i < N && a[i + 1] == tmp) b[tot]++, i++;
  }
  solve();
  return 0;
}

### Prompt

Develop a solution in cpp to the problem described below:

A year ago on the bench in public park Leha found an array of n numbers. Leha believes that permutation p is right if for all 1 ≤ i < n condition, that api·api + 1 is not perfect square, holds. Leha wants to find number of right permutations modulo 109 + 7.

Input

First line of input data contains single integer n (1 ≤ n ≤ 300) — length of the array.

Next line contains n integers a1, a2, ... , an (1 ≤ ai ≤ 109) — found array.

Output

Output single integer — number of right permutations modulo 109 + 7.

Examples

Input

3
1 2 4


Output

2


Input

7
5 2 4 2 4 1 1


Output

144

Note

For first example:

[1, 2, 4] — right permutation, because 2 and 8 are not perfect squares.

[1, 4, 2] — wrong permutation, because 4 is square of 2.

[2, 1, 4] — wrong permutation, because 4 is square of 2.

[2, 4, 1] — wrong permutation, because 4 is square of 2.

[4, 1, 2] — wrong permutation, because 4 is square of 2.

[4, 2, 1] — right permutation, because 8 and 2 are not perfect squares.

### Response

```cpp
#include <bits/stdc++.h>
namespace modular {
const int MOD = 1000000007;
inline int add(int x, int y) { return (x += y) >= MOD ? x -= MOD : x; }
inline void inc(int &x, int y) { (x += y) >= MOD ? x -= MOD : 0; }
inline int mul(int x, int y) { return 1LL * x * y % MOD; }
inline int qpow(int x, int y) {
  int ans = 1;
  for (; y; y >>= 1, x = mul(x, x))
    if (y & 1) ans = mul(ans, x);
  return ans;
}
};  // namespace modular
using namespace modular;
namespace Base {
template <typename Tp>
inline Tp input() {
  Tp x = 0, y = 1;
  char c = getchar();
  while ((c < '0' || '9' < c) && c != EOF) {
    if (c == '-') y = -1;
    c = getchar();
  }
  if (c == EOF) return 0;
  while ('0' <= c && c <= '9') x = x * 10 + c - '0', c = getchar();
  return x *= y;
}
template <typename Tp>
inline void read(Tp &x) {
  x = input<Tp>();
}
template <typename Tp>
inline void chmax(Tp &x, Tp y) {
  x < y ? x = y : 0;
}
template <typename Tp>
inline void chmin(Tp &x, Tp y) {
  x > y ? x = y : 0;
}
};  // namespace Base
using namespace Base;
int N, tot;
int a[3007], b[3007];
int f[3007], g[3007], h[3007];
int C[3007][3007], fac[3007];
void init() {
  int MX = 3000;
  C[0][0] = 1;
  for (int i = 1; i <= MX; ++i) {
    C[i][0] = 1;
    for (int j = 1; j <= i; ++j) C[i][j] = add(C[i - 1][j - 1], C[i - 1][j]);
  }
  fac[0] = 1;
  for (int i = 1; i <= MX; ++i) fac[i] = mul(fac[i - 1], i);
}
void solve() {
  f[0] = 1;
  int tmp = 0;
  for (int i = 1; i <= tot; ++i) {
    for (int j = 1; j <= b[i]; ++j)
      g[j] = C[b[i] - 1][b[i] - j], (b[i] - j) & 1 ? g[j] = MOD - g[j] : 0;
    for (int j = 0; j <= tmp + b[i]; ++j) h[j] = 0;
    for (int j = b[i]; j >= 1; --j) {
      for (int k = tmp; k >= 0; --k)
        inc(h[j + k], mul(mul(g[j], f[k]), C[j + k][j]));
    }
    tmp += b[i];
    for (int j = 0; j <= tmp; ++j) f[j] = h[j];
  }
  int res = 0;
  for (int i = 1; i <= tmp; ++i) inc(res, f[i]);
  for (int i = 1; i <= tot; ++i) res = mul(res, fac[b[i]]);
  printf("%d\n", res);
}
int main() {
  init();
  read(N);
  for (int i = 1; i <= N; ++i) {
    read(a[i]);
    for (int j = 2, tmp = j * j; j * j <= a[i]; ++j, tmp = j * j)
      while (a[i] % tmp == 0) a[i] /= tmp;
  }
  std::sort(a + 1, a + N + 1);
  for (int i = 1; i <= N; ++i) {
    b[++tot] = 1;
    int tmp = a[i];
    while (i < N && a[i + 1] == tmp) b[tot]++, i++;
  }
  solve();
  return 0;
}

```