#include <bits/stdc++.h>
using namespace std;
struct UnionFind {
  vector<int> v;
  UnionFind(int n) : v(n, -1) {}
  void init() {
    for (int i = 0; i < (int)v.size(); i++) v[i] = -1;
  }
  int find(int x) { return v[x] < 0 ? x : v[x] = find(v[x]); }
  bool unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return false;
    if (-v[x] < -v[y]) swap(x, y);
    v[x] += v[y];
    v[y] = x;
    return true;
  }
  bool root(int x) { return v[x] < 0; }
  bool same(int x, int y) { return find(x) == find(y); }
  int size(int x) { return -v[find(x)]; }
};
long long mod_pow(long long a, long long n) {
  long long res = 1;
  while (n > 0) {
    if (n & 1) res = res * a % 1000000007;
    a = a * a % 1000000007;
    n >>= 1;
  }
  return res;
}
struct edge {
  int u, v;
  long long key;
};
long long N, M, K;
vector<edge> es;
long long c[500010];
long long p2[500010];
int main() {
  scanf("%lld%lld%lld", &N, &M, &K);
  p2[0] = 1;
  for (int i = (int)(0); i < (int)(N); i++) {
    scanf("%lld", c + i);
    p2[i + 1] = p2[i] * 2LL % 1000000007;
  }
  for (int i = (int)(0); i < (int)(M); i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    a--;
    b--;
    es.push_back((edge){a, b, c[a] ^ c[b]});
  }
  sort((es).begin(), (es).end(),
       [](const edge& a, const edge& b) { return a.key < b.key; });
  UnionFind uf(N);
  long long rest = (1LL << K);
  long long res = 0;
  for (int i = 0; i < (int)es.size();) {
    int j = i;
    while (j < (int)es.size() && es[j].key == es[i].key) j++;
    rest--;
    int cmp = N;
    for (int k = (int)(i); k < (int)(j); k++) {
      if (uf.unite(es[k].u, es[k].v)) cmp--;
    }
    (res += p2[cmp]) %= 1000000007;
    for (int k = (int)(i); k < (int)(j); k++) {
      uf.v[es[k].u] = -1;
      uf.v[es[k].v] = -1;
    }
    i = j;
  }
  rest %= 1000000007;
  (res += rest * p2[N] % 1000000007) %= 1000000007;
  cout << res << endl;
  return 0;
}
