/// Author : Nguyễn Thái Sơn - Ti20 - THPT chuyên Lương Thế Vinh
/// Training VOI 2023
#include<bits/stdc++.h>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/trie_policy.hpp>
//#include <ext/rope>
//#pragma GCC optimize("Ofast")
//#pragma GCC optimization("unroll-loops, no-stack-protector")
//#pragma GCC target("avx,avx2,fma")
//using namespace std;
//using namespace __gnu_pbds;
//using namespace __gnu_cxx;
#define fi first
#define se second
#define TASK "scp"
#define pb push_back
#define EL cout << endl
#define Ti20_ntson int main()
#define in(x) cout << x << endl
#define all(x) (x).begin(),(x).end()
#define getbit(x, i) (((x) >> (i)) & 1)
#define cntbit(x) __builtin_popcount(x)
#define FOR(i,l,r) for (int i = l; i <= r; i++)
#define FORD(i,l,r) for (int i = l; i >= r; i--)
#define Debug(a,n) for (int i = 1; i <= n; i++) cout << a[i] << " "; cout << endl
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> vii;
typedef unsigned long long ull;
typedef vector<vector<int>> vvi;
int fastMax(int x, int y) { return (((y-x)>>(32-1))&(x^y))^y; }
const int N = 305;
const int oo = INT_MAX;
const int mod = 1e9 + 7;
const int d4x[4] = {-1, 0, 1, 0} , d4y[4] = {0, 1, 0, -1};
const int d8x[8] = {-1, -1, 0, 1, 1, 1, 0, -1}, d8y[8] = {0, 1, 1, 1, 0, -1, -1, -1};
int n, a[N];
ll fact[N], ifact[N];
int dp[N][N];
inline void Read_Input() {
cin >> n;
FOR(i, 1, n)
cin >> a[i];
}
int Pow(int n, int k) {
if (k == 0)
return 1;
if (k == 1)
return n;
int res = Pow(n, k / 2);
res = 1ll * res * res % mod;
if (k & 1) res = 1ll * res * n % mod;
return res;
}
int C(int k, int n) {
if (k > n) return 0;
return (fact[n] * ifact[n - k] % mod) * ifact[k] % mod;
}
inline void Add(int &u, int v) {
u += v;
if (u >= mod) u -= mod;
}
inline void Solve() {
fact[0] = 1;
FOR(i, 1, n)
fact[i] = fact[i - 1] * i % mod;
ifact[n] = Pow(fact[n], mod - 2);
FORD(i, n, 1)
ifact[i - 1] = ifact[i] * i % mod;
FOR(i, 1, n)
for (int j = 2; j * j <= a[i]; j++)
while (a[i] % (j * j) == 0)
a[i] /= (j * j);
unordered_map<int, int> mp;
FOR(i, 1, n)
mp[a[i]]++;
n = 0;
for (auto[val, u] : mp)
a[++n] = u;
dp[1][a[1] - 1] = fact[a[1]];
int Sum = a[1];
FOR(i, 1, n - 1) {
FOR(j, 0, Sum)
if (dp[i][j])
FOR(k, 0, j)
FOR(t, max(1, k), a[i + 1]) {
int nj = j - k + a[i + 1] - t;
Add(dp[i + 1][nj], 1ll * (1ll * (1ll * (1ll * dp[i][j] * C(t - 1, a[i + 1] - 1) % mod) * fact[a[i + 1]] % mod) * C(t - k, Sum + 1 - j) % mod) * C(k, j) % mod);
}
Sum += a[i + 1];
}
cout << dp[n][0];
}
Ti20_ntson {
freopen(TASK".INP","r",stdin);
freopen(TASK".OUT","w",stdout);
ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int T = 1;
// cin >> T;
while (T -- ) {
Read_Input();
Solve();
}
}
Ly8vIEF1dGhvciA6IE5ndXnhu4VuIFRow6FpIFPGoW4gLSBUaTIwIC0gVEhQVCBjaHV5w6puIEzGsMahbmcgVGjhur8gVmluaAovLy8gVHJhaW5pbmcgVk9JIDIwMjMKCiNpbmNsdWRlPGJpdHMvc3RkYysrLmg+Ci8vI2luY2x1ZGUgPGV4dC9wYl9kcy9hc3NvY19jb250YWluZXIuaHBwPgovLyNpbmNsdWRlIDxleHQvcGJfZHMvdHJpZV9wb2xpY3kuaHBwPgovLyNpbmNsdWRlIDxleHQvcm9wZT4KCi8vI3ByYWdtYSBHQ0Mgb3B0aW1pemUoIk9mYXN0IikKLy8jcHJhZ21hIEdDQyBvcHRpbWl6YXRpb24oInVucm9sbC1sb29wcywgbm8tc3RhY2stcHJvdGVjdG9yIikKLy8jcHJhZ21hIEdDQyB0YXJnZXQoImF2eCxhdngyLGZtYSIpCgovL3VzaW5nIG5hbWVzcGFjZSBzdGQ7Ci8vdXNpbmcgbmFtZXNwYWNlIF9fZ251X3BiZHM7Ci8vdXNpbmcgbmFtZXNwYWNlIF9fZ251X2N4eDsKCiNkZWZpbmUgZmkgZmlyc3QKI2RlZmluZSBzZSBzZWNvbmQKI2RlZmluZSBUQVNLICJzY3AiCiNkZWZpbmUgcGIgcHVzaF9iYWNrCiNkZWZpbmUgRUwgY291dCA8PCBlbmRsCiNkZWZpbmUgVGkyMF9udHNvbiBpbnQgbWFpbigpCiNkZWZpbmUgaW4oeCkgY291dCA8PCB4IDw8IGVuZGwKI2RlZmluZSBhbGwoeCkgKHgpLmJlZ2luKCksKHgpLmVuZCgpCiNkZWZpbmUgZ2V0Yml0KHgsIGkpICgoKHgpID4+IChpKSkgJiAxKQojZGVmaW5lIGNudGJpdCh4KSBfX2J1aWx0aW5fcG9wY291bnQoeCkKI2RlZmluZSBGT1IoaSxsLHIpIGZvciAoaW50IGkgPSBsOyBpIDw9IHI7IGkrKykKI2RlZmluZSBGT1JEKGksbCxyKSBmb3IgKGludCBpID0gbDsgaSA+PSByOyBpLS0pCiNkZWZpbmUgRGVidWcoYSxuKSBmb3IgKGludCBpID0gMTsgaSA8PSBuOyBpKyspIGNvdXQgPDwgYVtpXSA8PCAiICI7IGNvdXQgPDwgZW5kbAoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnR5cGVkZWYgbG9uZyBsb25nIGxsOwp0eXBlZGVmIHZlY3RvcjxpbnQ+IHZpOwp0eXBlZGVmIHBhaXI8aW50LGludD4gdmlpOwp0eXBlZGVmIHVuc2lnbmVkIGxvbmcgbG9uZyB1bGw7CnR5cGVkZWYgdmVjdG9yPHZlY3RvcjxpbnQ+PiB2dmk7CmludCBmYXN0TWF4KGludCB4LCBpbnQgeSkgeyByZXR1cm4gKCgoeS14KT4+KDMyLTEpKSYoeF55KSleeTsgfQoKY29uc3QgaW50IE4gPSAzMDU7CmNvbnN0IGludCBvbyA9IElOVF9NQVg7CmNvbnN0IGludCBtb2QgPSAxZTkgKyA3Owpjb25zdCBpbnQgZDR4WzRdID0gey0xLCAwLCAxLCAwfSAsIGQ0eVs0XSA9IHswLCAxLCAwLCAtMX07CmNvbnN0IGludCBkOHhbOF0gPSB7LTEsIC0xLCAwLCAxLCAxLCAxLCAwLCAtMX0sIGQ4eVs4XSA9IHswLCAxLCAxLCAxLCAwLCAtMSwgLTEsIC0xfTsKCmludCBuLCBhW05dOwpsbCBmYWN0W05dLCBpZmFjdFtOXTsKaW50IGRwW05dW05dOwoKaW5saW5lIHZvaWQgUmVhZF9JbnB1dCgpIHsKICAgIGNpbiA+PiBuOwogICAgRk9SKGksIDEsIG4pCiAgICAgICAgY2luID4+IGFbaV07Cn0KCmludCBQb3coaW50IG4sIGludCBrKSB7CiAgICBpZiAoayA9PSAwKQogICAgICAgIHJldHVybiAxOwogICAgaWYgKGsgPT0gMSkKICAgICAgICByZXR1cm4gbjsKICAgIGludCByZXMgPSBQb3cobiwgayAvIDIpOwogICAgcmVzID0gMWxsICogcmVzICogcmVzICUgbW9kOwogICAgaWYgKGsgJiAxKSByZXMgPSAxbGwgKiByZXMgKiBuICUgbW9kOwogICAgcmV0dXJuIHJlczsKfQoKaW50IEMoaW50IGssIGludCBuKSB7CiAgICBpZiAoayA+IG4pIHJldHVybiAwOwogICAgcmV0dXJuIChmYWN0W25dICogaWZhY3RbbiAtIGtdICUgbW9kKSAqIGlmYWN0W2tdICUgbW9kOwp9CgppbmxpbmUgdm9pZCBBZGQoaW50ICZ1LCBpbnQgdikgewogICAgdSArPSB2OwogICAgaWYgKHUgPj0gbW9kKSB1IC09IG1vZDsKfQoKaW5saW5lIHZvaWQgU29sdmUoKSB7CiAgICBmYWN0WzBdID0gMTsKICAgIEZPUihpLCAxLCBuKQogICAgICAgIGZhY3RbaV0gPSBmYWN0W2kgLSAxXSAqIGkgJSBtb2Q7CiAgICBpZmFjdFtuXSA9IFBvdyhmYWN0W25dLCBtb2QgLSAyKTsKICAgIEZPUkQoaSwgbiwgMSkKICAgICAgICBpZmFjdFtpIC0gMV0gPSBpZmFjdFtpXSAqIGkgJSBtb2Q7CiAgICBGT1IoaSwgMSwgbikKICAgICAgICBmb3IgKGludCBqID0gMjsgaiAqIGogPD0gYVtpXTsgaisrKQogICAgICAgICAgICB3aGlsZSAoYVtpXSAlIChqICogaikgPT0gMCkKICAgICAgICAgICAgICAgIGFbaV0gLz0gKGogKiBqKTsKICAgIHVub3JkZXJlZF9tYXA8aW50LCBpbnQ+IG1wOwogICAgRk9SKGksIDEsIG4pCiAgICAgICAgbXBbYVtpXV0rKzsKICAgIG4gPSAwOwogICAgZm9yIChhdXRvW3ZhbCwgdV0gOiBtcCkKICAgICAgICBhWysrbl0gPSB1OwogICAgZHBbMV1bYVsxXSAtIDFdID0gZmFjdFthWzFdXTsKICAgIGludCBTdW0gPSBhWzFdOwogICAgRk9SKGksIDEsIG4gLSAxKSB7CiAgICAgICAgRk9SKGosIDAsIFN1bSkKICAgICAgICAgICAgaWYgKGRwW2ldW2pdKQogICAgICAgICAgICAgICAgRk9SKGssIDAsIGopCiAgICAgICAgICAgICAgICAgICAgRk9SKHQsIG1heCgxLCBrKSwgYVtpICsgMV0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IG5qID0gaiAtIGsgKyBhW2kgKyAxXSAtIHQ7CiAgICAgICAgICAgICAgICAgICAgICAgIEFkZChkcFtpICsgMV1bbmpdLCAxbGwgKiAoMWxsICogKDFsbCAqICgxbGwgKiBkcFtpXVtqXSAqIEModCAtIDEsIGFbaSArIDFdIC0gMSkgJSBtb2QpICogZmFjdFthW2kgKyAxXV0gJSBtb2QpICogIEModCAtIGssIFN1bSArIDEgLSBqKSAlIG1vZCkgKiBDKGssIGopICUgbW9kKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgU3VtICs9IGFbaSArIDFdOwogICAgfQogICAgY291dCA8PCBkcFtuXVswXTsKfQoKVGkyMF9udHNvbiB7CiAgICBmcmVvcGVuKFRBU0siLklOUCIsInIiLHN0ZGluKTsKICAgIGZyZW9wZW4oVEFTSyIuT1VUIiwidyIsc3Rkb3V0KTsKICAgIGlvc19iYXNlOjpzeW5jX3dpdGhfc3RkaW8oZmFsc2UpOyBjaW4udGllKDApOyBjb3V0LnRpZSgwKTsKICAgIGludCBUID0gMTsKLy8gICAgY2luID4+IFQ7CiAgICB3aGlsZSAoVCAtLSApIHsKICAgICAgICBSZWFkX0lucHV0KCk7CiAgICAgICAgU29sdmUoKTsKICAgIH0KfQoK