#include"iostream" #include"algorithm" #include"cstring" #include"cstdio" #include"cmath" #include"vector" #include"map" #include"set" #include"queue" usingnamespace std; #define MAXN 316 //#define int long long #define rep(i, a, b) for (int i = (a), i##end = (b); i <= i##end; ++i) #define per(i, a, b) for (int i = (a), i##end = (b); i >= i##end; --i) #define pii pair<int,int> #define fi first #define se second #define mp make_pair #define pb push_back #define eb emplace_back #define vi vector<int> #define all(x) (x).begin() , (x).end() #define mem( a ) memset( a , 0 , sizeof a ) #define P 1000000007 typedeflonglong ll; int n; int A[MAXN];
intPow( int x , int a ){ int ret = 1; while( a ) { if( a & 1 ) ret = 1ll * ret * x % P; x = 1ll * x * x % P , a >>= 1; } return ret; }
boolchk( ll x ){ ll qwq = sqrt( x ); return ( qwq * qwq == x ); }
int f[MAXN] , a[MAXN] , m; int dp[MAXN][MAXN] , td[MAXN][MAXN] , J[MAXN] , iJ[MAXN];
intC( int a , int b ){ return a < b ? 0 : J[a] * 1ll * iJ[b] % P * iJ[a - b] % P; }
voidsolve(){ cin >> n; int flg; rep( i , 1 , n ) { scanf("%d",A + i); flg = 0; rep( j , 1 , i - 1 ) if( chk( 1ll * A[i] * A[j] ) ) { ++ a[f[j]] , flg = 1; break; } if( !flg ) f[i] = ++ m , a[m] = 1; } J[0] = iJ[0] = 1; rep( i , 1 , n ) J[i] = J[i - 1] * 1ll * i % P , iJ[i] = Pow( J[i] , P - 2 ); int s = 0; dp[0][0] = 1; rep( i , 1 , m ) { rep( j , 0 , s ) { rep( t , 0 , a[i] - 1 ) { dp[i][j + a[i] - t] += 1ll * dp[i - 1][j] * ( ( t & 1 ) ? P - 1 : 1 ) % P * C( a[i] - 1 , t ) % P * iJ[a[i] - t] % P; dp[i][j + a[i] - t] %= P; } } s += a[i]; } int res = 0; rep( i , 1 , n ) res = ( res + 1ll * J[i] * dp[m][i] % P ) % P; rep( i , 1 , m ) res = 1ll * res * J[a[i]] % P; cout << res << endl; }