#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1e9 + 7;
const long long maxn = 5e5 + 5;
long long c[maxn];
map<long long, long long> mp;
vector<pair<long long, long long> > ve[maxn];
set<long long> se;
set<long long>::iterator ite, itee;
long long ans1[maxn], ans2[maxn], par[maxn];
long long qpow(long long a, long long b) {
  long long ans = 1;
  long long k = a;
  long long m = MOD;
  while (b) {
    if (b & 1) ans = ans * k % m;
    k = k * k % m;
    b >>= 1;
  }
  return ans;
}
long long find1(long long x) {
  if (par[x] == x) return x;
  return par[x] = find1(par[x]);
}
void unite(long long x, long long y) {
  long long xx = find1(x);
  long long yy = find1(y);
  if (xx == yy) return;
  par[xx] = yy;
}
int main() {
  long long n, m, k, u, v, res = 0, op = 0;
  scanf("%lld%lld%lld", &n, &m, &k);
  for (long long i = 1; i <= n; i++) scanf("%lld", &c[i]);
  for (long long i = 1; i <= m; i++) {
    scanf("%lld%lld", &u, &v);
    long long val = c[u] ^ c[v];
    se.insert(val);
    if (!mp[val]) mp[val] = ++op;
    ve[mp[val]].push_back(make_pair(u, v));
  }
  for (long long i = 1; i <= n; i++) par[i] = i;
  for (ite = se.begin(); ite != se.end(); ite++) {
    set<long long> see;
    long long cnt = 0;
    for (long long j = 0; j < ve[mp[*ite]].size(); j++) {
      see.insert(ve[mp[*ite]][j].first);
      see.insert(ve[mp[*ite]][j].second);
      unite(ve[mp[*ite]][j].first, ve[mp[*ite]][j].second);
    }
    for (itee = see.begin(); itee != see.end(); itee++) {
      if (par[*itee] == *itee) cnt++;
    }
    for (itee = see.begin(); itee != see.end(); itee++) par[*itee] = *itee;
    ans1[mp[*ite]] = see.size();
    ans2[mp[*ite]] = cnt;
  }
  for (ite = se.begin(); ite != se.end(); ite++) {
    res += (qpow(2, n - ans1[mp[*ite]]) % MOD * qpow(2, ans2[mp[*ite]]) % MOD) %
           MOD;
    res %= MOD;
  }
  long long siz = se.size();
  res += ((qpow(2, k) % MOD - siz % MOD + MOD) % MOD * qpow(2, n) % MOD) % MOD;
  printf("%lld\n", res % MOD);
  return 0;
}
