#include <bits/stdc++.h>
#pragma GCC optimize("Ofast", "unroll-loops")
using namespace std;
const long long inf = numeric_limits<long long>::max() / 2;
const long double eps = 1e-9;
const long double pi = acos(-1);
inline void solve(), read();
int main() {
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  read();
  solve();
  return 0;
}
struct edge {
  long long v, u, w;
};
struct graph {
  long long n;
  vector<edge> es;
  map<long long, vector<long long>> x;
  graph() {}
  graph(long long n_) { n = n_; }
  void insert(long long v, long long u, long long w) {
    es.push_back({v, u, w});
    x[w].push_back((long long)((es).size()) - 1);
  }
};
struct dsu {
  long long n;
  vector<long long> t, rk;
  stack<pair<long long&, long long>> st;
  long long cnt = 0;
  dsu() {}
  dsu(long long n_) {
    n = n_;
    t.resize(n);
    iota((t).begin(), (t).end(), 0);
    rk.assign(n, 0);
    cnt = n;
  }
  long long find(long long v) {
    if (v == t[v]) {
      return v;
    }
    st.push({t[v], t[v]});
    t[v] = find(t[v]);
    return t[v];
  }
  void join(long long v, long long u) {
    v = find(v), u = find(u);
    if (v != u) {
      if (rk[v] < rk[u]) {
        swap(v, u);
      }
      st.push({t[u], t[u]});
      t[u] = v;
      if (rk[v] == rk[u]) {
        st.push({rk[v], rk[v]});
        ++rk[v];
      }
      st.push({cnt, cnt});
      --cnt;
    }
  }
  void restore() {
    while (!st.empty()) {
      st.top().first = st.top().second;
      st.pop();
    }
  }
};
const long long R = 1e9 + 7;
long long binpow(long long n, long long p) {
  if (p == 0) {
    return 1;
  }
  if (p == 1) {
    return n;
  }
  long long a = binpow(n, p / 2);
  a = a * a % R;
  if (p %= 2) {
    a = a * n % R;
  }
  return a;
}
long long n, m, k;
graph g;
dsu d;
vector<long long> c;
inline void solve() {
  d = dsu(g.n);
  long long ans = 0;
  long long c = binpow(2, k);
  for (auto& p : g.x) {
    --c;
    for (long long x : p.second) {
      edge e = g.es[x];
      d.join(e.v, e.u);
    }
    ans += binpow(2, d.cnt);
    ans %= R;
    d.restore();
  }
  ans += c * binpow(2, n) % R;
  ans %= R;
  cout << ans << "\n";
}
inline void read() {
  cin >> n >> m >> k;
  g = graph(n);
  c.resize(n);
  for (long long i = 0; i < n; i++) {
    cin >> c[i];
  }
  for (long long i = 0; i < m; i++) {
    long long v, u;
    cin >> v >> u;
    --v, --u;
    long long w = c[v] ^ c[u];
    g.insert(v, u, w);
  }
}
