#include <bits/stdc++.h>
using namespace std;
const int MAXN = (int)5e5 + 5;
long long ar[MAXN];
vector<int> graph[MAXN];
unordered_map<long long, vector<int>> edges;
bool been[MAXN];
const int MOD = (int)1e9 + 7;
int add(int a, int b) {
  a += b;
  if (a >= MOD) a -= MOD;
  return a;
}
int sub(int a, int b) { return add(a, MOD - b); }
int mul(int a, int b) { return ((long long)a * b) % MOD; }
int pw(int a, long long b) {
  return b == 0 ? 1 : b % 2 ? mul(a, pw(a, b - 1)) : pw(mul(a, a), b / 2);
}
void solve() {
  int n, m, k;
  scanf("%d %d %d", &n, &m, &k);
  for (int i = 0; i < (n); ++i) scanf("%lld", &ar[i]);
  for (int i = 0; i < (m); ++i) {
    int a, b;
    scanf("%d %d", &a, &b);
    --a;
    --b;
    auto it = edges.find(ar[a] ^ ar[b]);
    if (it == edges.end()) {
      vector<int> kek{a, b};
      edges.emplace(ar[a] ^ ar[b], kek);
    } else {
      it->second.push_back(a);
      it->second.push_back(b);
    }
    graph[a].push_back(b);
    graph[b].push_back(a);
  }
  int res = mul(pw(2, n), sub(pw(2, k), (int)((edges).size())));
  for (const auto& e : edges) {
    int comp = n;
    for (auto from : e.second) {
      if (been[from]) continue;
      ++comp;
      static queue<int> q;
      q.push(from);
      been[from] = true;
      while (!q.empty()) {
        int cur = q.front();
        q.pop();
        --comp;
        long long a = ar[cur] ^ e.first;
        for (auto nxt : graph[cur])
          if (!been[nxt] && ar[nxt] == a) {
            been[nxt] = true;
            q.push(nxt);
          }
      }
    }
    for (auto v : e.second) been[v] = false;
    res = add(res, pw(2, comp));
  }
  printf("%d\n", res);
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  solve();
  return 0;
}
