#include<iostream> 
#include<algorithm>
#include<vector>
#include<cmath>
#include<ctime>
#include<cstring>
#include<limits>
#include<complex>
using namespace std;
const long long m = 1000000007;
const int c = 200000;
long long factorial[c+1];
long long inv(long long a) {
  return a <= 1 ? a : m - (long long)(m/a) * inv(m % a) % m;
}
long long bin(int n, int k) {
    return factorial[n] * inv(factorial[k] * factorial[n - k] % m) % m;
}
long long pot(int n) {
	long long ans = 1;
	for(int i=0; i<n; ++i) ans = (ans * 2) % m;
	return ans;
}
struct FAU {
	int *p, *w;
	FAU(int n) : p(new int[n]), w(new int[n]) {
		for(int x=0; x<n; ++x) p[x] = w[x] = -1;
	}
	~FAU() {
		delete[]p;
		delete[]w;
	}
	int Find(int x) {
		return (p[x] < 0) ? x : p[x] = Find(p[x]);
	}
	void Union(int x, int y) {
		if((x = Find(x)) == (y = Find(y))) return;
		if(w[x] > w[y]) p[y] = x;
		else p[x] = y;
		if(w[x] == w[y]) w[y]++;
	}
};
int main() {
	ios::sync_with_stdio(0);
	factorial[0] = 1;
	for (int i = 1; i <= c; i++) {
		factorial[i] = factorial[i - 1] * i % m;
	}
	int N,M;
	cin>>N>>M;
	int Z[c+1],a[c*2],b[c*2];
	for(int i=1; i<=N; ++i) cin>>Z[i];
	vector<int> L[c+1];
	for(int i=0; i<M; ++i) {
		cin>>a[i]>>b[i];
		L[a[i]].push_back(b[i]);
		L[b[i]].push_back(a[i]);
	}
	FAU fau(N+1);
	for(int i=1; i<=N; ++i) {
		int r = L[i].size();
		for(int j=1; j<r; ++j) fau.Union(L[i][0], L[i][j]);
	}
	int nr[c+1];
	int il[c+1];
	int jed[c+1];
	for(int i=0; i<=N; ++i) nr[i] = il[i] = jed[i] = 0;
	for(int i=1; i<=N; ++i) {
		int pom = fau.Find(i);
		nr[pom] = 1;
		il[pom]++;
		if(Z[i] == 1) jed[pom]++;
	}
	for(int i=0; i<M; ++i) {
		if(fau.Find(a[i]) == fau.Find(b[i])) {
			nr[fau.Find(a[i])] = 2;
		}
	}
	long long ans = 1;
	for(int i=0; i<M; ++i) {
		int e,f;
		e = fau.Find(a[i]);
		f = fau.Find(b[i]);
		if(e != f && nr[e]*nr[f] != 0) {
			if(nr[e] == 2 || nr[f] == 2) {
				ans = (ans * pot(il[e]+il[f]-1)) % m;
			}
			else {
				if(jed[e] > jed[f]) {
					int h = jed[e] - jed[f];
					long long H = 0;
					for(int i=0; i<=min(il[f], il[e] - h); ++i) {
						H += (bin(il[f], i) * bin(il[e], i + h)) % m;
					}
					H %= m;
					ans = (ans * H) % m;
				}
				else {
					int h = jed[f] - jed[e];
					long long H = 0;
					for(int i=0; i<=min(il[e], il[f] - h); ++i) {
						H += (bin(il[e], i) * bin(il[f], i + h)) % m;
					}
					H %= m;
					ans = (ans * H) % m;
				}
			}
			nr[e] = nr[f] = 0;
		}
	}
	for(int i=1; i<=N; ++i) {
		if(nr[i] == 1) ans = (ans * bin(il[i], jed[i])) % m;
		else if(nr[i] == 2) ans = (ans * pot(il[i] - 1)) % m;
	}
	cout<<ans<<endl;
	
	
	return 0;
}
        1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125  | #include<iostream> #include<algorithm> #include<vector> #include<cmath> #include<ctime> #include<cstring> #include<limits> #include<complex> using namespace std; const long long m = 1000000007; const int c = 200000; long long factorial[c+1]; long long inv(long long a) { return a <= 1 ? a : m - (long long)(m/a) * inv(m % a) % m; } long long bin(int n, int k) { return factorial[n] * inv(factorial[k] * factorial[n - k] % m) % m; } long long pot(int n) { long long ans = 1; for(int i=0; i<n; ++i) ans = (ans * 2) % m; return ans; } struct FAU { int *p, *w; FAU(int n) : p(new int[n]), w(new int[n]) { for(int x=0; x<n; ++x) p[x] = w[x] = -1; } ~FAU() { delete[]p; delete[]w; } int Find(int x) { return (p[x] < 0) ? x : p[x] = Find(p[x]); } void Union(int x, int y) { if((x = Find(x)) == (y = Find(y))) return; if(w[x] > w[y]) p[y] = x; else p[x] = y; if(w[x] == w[y]) w[y]++; } }; int main() { ios::sync_with_stdio(0); factorial[0] = 1; for (int i = 1; i <= c; i++) { factorial[i] = factorial[i - 1] * i % m; } int N,M; cin>>N>>M; int Z[c+1],a[c*2],b[c*2]; for(int i=1; i<=N; ++i) cin>>Z[i]; vector<int> L[c+1]; for(int i=0; i<M; ++i) { cin>>a[i]>>b[i]; L[a[i]].push_back(b[i]); L[b[i]].push_back(a[i]); } FAU fau(N+1); for(int i=1; i<=N; ++i) { int r = L[i].size(); for(int j=1; j<r; ++j) fau.Union(L[i][0], L[i][j]); } int nr[c+1]; int il[c+1]; int jed[c+1]; for(int i=0; i<=N; ++i) nr[i] = il[i] = jed[i] = 0; for(int i=1; i<=N; ++i) { int pom = fau.Find(i); nr[pom] = 1; il[pom]++; if(Z[i] == 1) jed[pom]++; } for(int i=0; i<M; ++i) { if(fau.Find(a[i]) == fau.Find(b[i])) { nr[fau.Find(a[i])] = 2; } } long long ans = 1; for(int i=0; i<M; ++i) { int e,f; e = fau.Find(a[i]); f = fau.Find(b[i]); if(e != f && nr[e]*nr[f] != 0) { if(nr[e] == 2 || nr[f] == 2) { ans = (ans * pot(il[e]+il[f]-1)) % m; } else { if(jed[e] > jed[f]) { int h = jed[e] - jed[f]; long long H = 0; for(int i=0; i<=min(il[f], il[e] - h); ++i) { H += (bin(il[f], i) * bin(il[e], i + h)) % m; } H %= m; ans = (ans * H) % m; } else { int h = jed[f] - jed[e]; long long H = 0; for(int i=0; i<=min(il[e], il[f] - h); ++i) { H += (bin(il[e], i) * bin(il[f], i + h)) % m; } H %= m; ans = (ans * H) % m; } } nr[e] = nr[f] = 0; } } for(int i=1; i<=N; ++i) { if(nr[i] == 1) ans = (ans * bin(il[i], jed[i])) % m; else if(nr[i] == 2) ans = (ans * pot(il[i] - 1)) % m; } cout<<ans<<endl; return 0; }  | 
            
        
                    English