#include <bits/stdc++.h>
using namespace std;
long long pw(long long x, long long p) {
  if (p == 0) return 1;
  long long t = pw(x, p / 2);
  if (p % 2 == 0)
    return (t * t) % 1000000007;
  else
    return (((t * t) % 1000000007) * x) % 1000000007;
}
const long long NN = 500007;
long long parent[NN], sizee[NN];
void make_set(long long v) {
  parent[v] = v;
  sizee[v] = 1;
}
long long find_set(long long v) {
  if (v == parent[v]) return v;
  return parent[v] = find_set(parent[v]);
}
void union_sets(long long a, long long b) {
  a = find_set(a);
  b = find_set(b);
  if (a != b) {
    if (sizee[a] < sizee[b]) swap(a, b);
    parent[b] = a;
    sizee[a] += sizee[b];
  }
}
int32_t main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  map<long long, long long> m;
  long long i, n, M;
  long long k;
  cin >> n >> M >> k;
  long long a[n + 1];
  for (i = 1; i <= n; i++) cin >> a[i];
  long long x, y, cur = 0, virus, pos;
  vector<pair<long long, long long> > edges[M + 1];
  while (M--) {
    cin >> x >> y;
    virus = a[x] ^ a[y];
    if (m.find(virus) == m.end()) {
      m.insert({virus, cur});
      cur++;
    }
    pos = m.find(virus)->second;
    edges[pos].push_back({x, y});
  }
  long long siz, comp;
  long long unsafe = 0, temp;
  for (i = 0; i < cur; i++) {
    set<long long> SS;
    for (auto &x : edges[i]) {
      make_set(x.first), make_set(x.second);
      SS.insert(x.first), SS.insert(x.second);
    }
    siz = SS.size();
    comp = siz;
    for (auto &x : edges[i]) {
      if (find_set(x.first) != find_set(x.second))
        comp--, union_sets(x.first, x.second);
    }
    temp = (pw(2, siz) - pw(2, comp) + 1000000007) % 1000000007;
    unsafe = (unsafe + (temp * pw(2, n - siz)) % 1000000007) % 1000000007;
  }
  cout << ((pw(2, k) * pw(2, n)) % 1000000007 - unsafe + 1000000007) %
              1000000007
       << endl;
  return 0;
}
