#include <bits/stdc++.h>
using namespace std;
const long long mo = 1e9 + 7;
const long long INF = 0x7f7f7f7f;
template <typename _T>
_T Fabs(_T x) {
  return x < 0 ? -x : x;
}
int n, m, k, fa[500005], tt;
long long c[500005], b[500005], tot, ans;
struct ming {
  int u, v;
  long long w;
} e[500005];
vector<ming> G[500005];
void makeSet(int x) {
  for (int i = 1; i <= x; i++) fa[i] = i;
}
int findSet(int x) { return fa[x] == x ? fa[x] : fa[x] = findSet(fa[x]); }
void unionSet(int a, int b) {
  int u = findSet(a), v = findSet(b);
  if (u == v) return;
  fa[u] = v;
  tt--;
}
long long qkpow(long long a, int s) {
  long long t = 1;
  while (s) {
    if (s & 1) t = t * a % mo;
    a = a * a % mo;
    s >>= 1;
  }
  return t;
}
signed main() {
  scanf("%d %d %d", &n, &m, &k);
  for (int i = 1; i <= n; i++) scanf("%lld", &c[i]);
  for (int i = 1; i <= m; i++)
    scanf("%d %d", &e[i].u, &e[i].v), e[i].w = c[e[i].u] ^ c[e[i].v],
                                      b[++tot] = e[i].w;
  sort(b + 1, b + tot + 1);
  tot = unique(b + 1, b + tot + 1) - b - 1;
  for (int i = 1; i <= m; i++) {
    e[i].w = lower_bound(b + 1, b + tot + 1, e[i].w) - b;
    G[e[i].w].push_back(e[i]);
  }
  makeSet(n);
  for (int i = 1; i <= tot; i++) {
    int siz = G[i].size(), sum = 0;
    tt = n;
    for (int j = 0; j < siz; j++) unionSet(G[i][j].u, G[i][j].v);
    (ans += qkpow(2, tt)) %= mo;
    for (int j = 0; j < siz; j++)
      fa[G[i][j].u] = G[i][j].u, fa[G[i][j].v] = G[i][j].v;
  }
  (ans += (qkpow(2, k) - tot + mo) % mo * qkpow(2, n) % mo) %= mo;
  printf("%lld\n", ans);
  return 0;
}
