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;
}