#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
long long MOD = 1e9 + 7;
void dfs(int now, vector<int> &used, vector<vector<int> > &graph) {
  used[now] = 1;
  for (auto elem : graph[now]) {
    if (used[elem] == 1) continue;
    dfs(elem, used, graph);
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  long long n, m, k;
  cin >> n >> m >> k;
  vector<long long> pow(n + 1);
  pow[0] = 1;
  for (int i = 1; i <= n; i++) pow[i] = (pow[i - 1] * 2) % MOD;
  vector<long long> arr(n);
  long long c;
  for (int i = 0; i < n; i++) {
    cin >> c;
    arr[i] = c;
  }
  map<long long, set<int> > color;
  map<long long, vector<pair<int, int> > > edges;
  long long a, b;
  int u, v;
  for (int i = 0; i < m; i++) {
    cin >> u >> v;
    u--;
    v--;
    a = arr[u];
    b = arr[v];
    c = a ^ b;
    if (color.find(c) == color.end()) color[c] = set<int>();
    if (edges.find(c) == edges.end()) edges[c] = vector<pair<int, int> >();
    edges[c].push_back({u, v});
    color[c].insert(u);
    color[c].insert(v);
  }
  map<int, int> numb;
  vector<int> used;
  vector<vector<int> > graph;
  long long cnt;
  int help;
  int n1;
  long long q;
  long long ans = 0;
  for (auto elem : color) {
    numb.clear();
    used.clear();
    graph.clear();
    for (auto vert : elem.second) {
      help = numb.size();
      numb[vert] = help;
    }
    n1 = elem.second.size();
    used.resize(n1);
    for (int i = 0; i < n1; i++) used[i] = 0;
    graph.resize(n1);
    for (auto ed : edges[elem.first]) {
      graph[numb[ed.first]].push_back(numb[ed.second]);
      graph[numb[ed.second]].push_back(numb[ed.first]);
    }
    q = 0;
    for (int i = 0; i < n1; i++) {
      if (used[i] == 1) continue;
      q++;
      dfs(i, used, graph);
    }
    cnt = pow[n - n1 + q];
    cnt %= MOD;
    ans += cnt;
    ans %= MOD;
  }
  cnt = color.size();
  cnt = ((long long)1 << k) - cnt;
  cnt %= MOD;
  cnt *= pow[n];
  cnt %= MOD;
  ans = (ans + cnt) % MOD;
  cout << ans << endl;
}
