#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 7;
const int MX = 1e9 + 7;
const long long int INF = 1e18 + 9LL;
int n, m, k;
long long int value[N];
pair<long long int, pair<int, int> > edge[N];
int pt[N];
int rep[N];
int res = 0;
int Find(int a) {
  if (rep[a] == a) return a;
  return rep[a] = Find(rep[a]);
}
bool Union(int a, int b) {
  a = Find(a), b = Find(b);
  if (a == b) return false;
  rep[a] = b;
  return true;
}
void solve(int from, int to) {
  int cnt = n;
  for (int i = from; i <= to; ++i)
    if (Union(edge[i].second.first, edge[i].second.second)) --cnt;
  res = (res + pt[cnt]) % MX;
  for (int i = from; i <= to; ++i)
    rep[edge[i].second.first] = edge[i].second.first,
    rep[edge[i].second.second] = edge[i].second.second;
}
int main() {
  scanf("%d %d %d", &n, &m, &k);
  for (int i = 1; i <= n; ++i) {
    scanf("%lld", &value[i]);
    rep[i] = i;
  }
  pt[0] = 1;
  for (int i = 1; i < N; ++i) pt[i] = (pt[i - 1] + pt[i - 1]) % MX;
  for (int i = 1; i <= m; ++i) {
    int u, v;
    scanf("%d %d", &u, &v);
    edge[i] = {value[u] ^ value[v], {u, v}};
  }
  long long int ok = pt[k];
  sort(edge + 1, edge + m + 1);
  for (int i = 1; i <= m; ++i) {
    int t = i;
    while (t < m && edge[t + 1].first == edge[t].first) ++t;
    solve(i, t);
    i = t;
    --ok;
  }
  res = (res + 1LL * pt[n] * (ok % MX)) % MX;
  printf("%d\n", res);
  return 0;
}
