#include <bits/stdc++.h>
using namespace std;
const int MOD = (int)1e9 + 7;
int n, m, k;
vector<long long> c;
vector<pair<int, int> > e;
map<long long, vector<int> > xe;
map<long long, set<int> > xv;
vector<int> pow2;
int add(int a, int b) { return (int)(((long long)a + (long long)b) % MOD); }
int sub(int a, int b) {
  return (int)(((long long)a + MOD - (long long)b) % MOD);
}
int mul(int a, int b) { return (int)(((long long)a * (long long)b) % MOD); }
struct UnionFind {
  vector<int> data;
  UnionFind(int size) : data(size, -1) {}
  bool unionSet(int x, int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (data[y] < data[x]) swap(x, y);
      data[x] += data[y];
      data[y] = x;
    }
    return x != y;
  }
  bool findSet(int x, int y) { return root(x) == root(y); }
  int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  int size(int x) { return -data[root(x)]; }
};
int main() {
  ios::sync_with_stdio(false);
  scanf("%d %d %d", &n, &m, &k);
  c.resize(n);
  for (int i = 0; i < n; ++i) scanf("%I64d", &c[i]);
  e.resize(m);
  for (int i = 0; i < m; ++i) {
    scanf("%d %d", &e[i].first, &e[i].second);
    --e[i].first;
    --e[i].second;
    long long x = c[e[i].first] ^ c[e[i].second];
    xe[x].push_back(i);
    xv[x].insert(e[i].first);
    xv[x].insert(e[i].second);
  }
  pow2.push_back(1);
  for (int i = 0, prev = 1; i <= max(n, k); ++i) {
    int curr = mul(prev, 2);
    pow2.push_back(curr);
    prev = curr;
  }
  int res = mul(pow2[n], pow2[k]);
  UnionFind uf(n);
  for (map<long long, vector<int> >::iterator it = xe.begin(), end = xe.end();
       it != end; ++it) {
    const vector<int>& xe = it->second;
    for (int i = 0; i < xe.size(); ++i) {
      uf.data[e[xe[i]].first] = -1;
      uf.data[e[xe[i]].second] = -1;
    }
    int nsets = 0;
    for (int i = 0; i < xe.size(); ++i) {
      if (uf.size(e[xe[i]].first) == 1 && uf.size(e[xe[i]].second) == 1) {
        ++nsets;
      } else if (uf.size(e[xe[i]].first) != 1 &&
                 uf.size(e[xe[i]].second) != 1 &&
                 !uf.findSet(e[xe[i]].first, e[xe[i]].second)) {
        --nsets;
      }
      uf.unionSet(e[xe[i]].first, e[xe[i]].second);
    }
    res = sub(res, pow2[n]);
    res = add(res, pow2[n - xv[it->first].size() + nsets]);
  }
  printf("%d\n", res);
  return 0;
}
