#include <bits/stdc++.h>
using namespace std;
constexpr long long TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n - 1); }
template <class T, class U>
void chmin(T& t, const U& u) {
  if (t > u) t = u;
}
template <class T, class U>
void chmax(T& t, const U& u) {
  if (t < u) t = u;
}
template <class T, class U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
  os << "(" << p.first << "," << p.second << ")";
  return os;
}
template <class T>
ostream& operator<<(ostream& os, const vector<T>& v) {
  os << "{";
  for (int i = 0; i < (v.size()); i++) {
    if (i) os << ",";
    os << v[i];
  }
  os << "}";
  return os;
}
class unionfind {
 public:
  vector<int> par, rank;
  void init(int n) {
    par.resize(n);
    rank.resize(n);
    for (int i = 0; i < n; i++) {
      par[i] = i;
      rank[i] = 0;
    }
  }
  int find(int x) {
    if (par[x] == x)
      return x;
    else
      return par[x] = find(par[x]);
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return;
    if (rank[x] < rank[y])
      par[x] = y;
    else {
      par[y] = x;
      if (rank[x] == rank[y]) ++rank[x];
    }
  }
  bool same(int x, int y) { return (find(x) == find(y)); }
} uf;
const long long MOD = TEN(9) + 7;
const int maxn = 500010;
long long p2[maxn];
long long c[maxn];
bool dfs(int v, int a, const vector<vector<int>>& g, vector<int>& col) {
  col[v] = a;
  for (int to : g[v]) {
    if (col[to] == -1) {
      if (!dfs(to, a ^ 1, g, col)) {
        return false;
      }
    } else {
      if (col[to] != (a ^ 1)) {
        return false;
      }
    }
  }
  return true;
}
int main() {
  p2[0] = 1;
  for (int i = 1; i < maxn; ++i) {
    p2[i] = p2[i - 1] * 2 % MOD;
  }
  int n, m, k;
  cin >> n >> m >> k;
  for (int i = 0; i < (n); i++) cin >> c[i];
  vector<pair<long long, pair<int, int>>> edges(m);
  for (int i = 0; i < (m); i++) {
    int a, b;
    cin >> a >> b;
    --a;
    --b;
    edges[i] = make_pair(c[a] ^ c[b], make_pair(a, b));
  }
  sort((edges).begin(), (edges).end());
  uf.init(n);
  long long ng = 0;
  int cmp = n;
  int i = 0;
  for (; i < edges.size();) {
    int j = i;
    while (j < edges.size() && edges[j].first == edges[i].first) ++j;
    vector<int> em;
    for (int k = i; k < j; ++k) {
      int a, b;
      tie(a, b) = edges[k].second;
      em.push_back(a);
      em.push_back(b);
      if (!uf.same(a, b)) {
        uf.unite(a, b);
        --cmp;
      }
    }
    long long x = edges[i].first;
    long long dec = 0;
    dec = p2[n] - p2[cmp];
    if (dec < 0) dec += MOD;
    for (int v : em) {
      uf.par[v] = v;
      uf.rank[v] = 0;
    }
    cmp = n;
    ng += dec;
    if (ng >= MOD) ng -= MOD;
    i = j;
  }
  long long ans = (1ll << k) % MOD * p2[n] % MOD;
  ans -= ng;
  if (ans < 0) ans += MOD;
  cout << ans << endl;
  return 0;
}
