#include <bits/stdc++.h>
using namespace std;
const long long NR = 5e5 + 100, oo = 1e9 + 10, MOD = 1e9 + 7;
const long double pi = 2 * acos(0.0);
struct edge {
  long long x, y, cost;
} temp;
vector<edge> all;
vector<long long> nodes;
bool cmp(edge a, edge b) { return a.cost < b.cost; }
long long n, m, k, cnt, connected, viz[NR], a[NR], Ans;
vector<long long> v[NR];
void dfs(int nod) {
  viz[nod] = cnt;
  connected--;
  vector<long long>::iterator it;
  for (it = v[nod].begin(); it != v[nod].end(); ++it)
    if (viz[*it] != cnt) dfs(*it);
}
long long lg_pow(long long x, long long y) {
  if (!y) return 1LL;
  if (y == 1LL) return x;
  if (y % 2) return x * lg_pow(x * x % MOD, y >> 1) % MOD;
  return lg_pow(x * x % MOD, y >> 1);
}
int main() {
  int i;
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m >> k;
  for (i = 1; i <= n; ++i) {
    cin >> a[i];
  }
  for (i = 1; i <= m; ++i) {
    cin >> temp.x >> temp.y;
    temp.cost = a[temp.x] ^ a[temp.y];
    all.push_back(temp);
  }
  sort(all.begin(), all.end(), cmp);
  if (m) {
    v[all[0].x].push_back(all[0].y);
    v[all[0].y].push_back(all[0].x);
    nodes.push_back(all[0].x);
    nodes.push_back(all[0].y);
  }
  temp.cost = -1;
  cnt = 1;
  all.push_back(temp);
  for (i = 1; i < all.size(); ++i) {
    if (all[i].cost != all[i - 1].cost) {
      connected = n;
      ++cnt;
      while (!nodes.empty()) {
        if (viz[nodes.back()] != cnt) {
          dfs(nodes.back());
          connected++;
        }
        v[nodes.back()].clear();
        nodes.pop_back();
      }
      Ans += lg_pow(2, connected);
      if (Ans >= MOD) Ans -= MOD;
    }
    if (i != all.size() - 1) {
      v[all[i].x].push_back(all[i].y);
      v[all[i].y].push_back(all[i].x);
      nodes.push_back(all[i].x);
      nodes.push_back(all[i].y);
    }
  }
  Ans = (Ans +
         ((((1LL << k) % MOD) + MOD - cnt + 1) % MOD) * lg_pow(2, n) % MOD) %
        MOD;
  cout << Ans << '\n';
  return 0;
}
