#include <bits/stdc++.h>
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template <int modd>
struct modint {
  static const int mod = modd;
  int v;
  explicit operator int() const { return v; }
  modint() : v(0) {}
  modint(long long x) : v(int(x % mod)) {
    if (v < 0) v += mod;
  }
  friend bool operator==(const modint& a, const modint& b) {
    return a.v == b.v;
  }
  friend bool operator!=(const modint& a, const modint& b) {
    return a.v != b.v;
  }
  friend bool operator<(const modint& a, const modint& b) { return a.v < b.v; }
  modint& operator+=(const modint& a) {
    if ((v += a.v) >= mod) v -= mod;
    return *this;
  }
  modint& operator-=(const modint& a) {
    if ((v -= a.v) < 0) v += mod;
    return *this;
  }
  modint& operator*=(const modint& a) {
    v = int((long long)v * a.v % mod);
    return *this;
  }
  modint& operator/=(const modint& a) { return (*this) *= inv(a); }
  friend modint pow(modint a, long long p) {
    modint ret = 1;
    for (; p; p /= 2, a *= a) {
      if (p & 1) ret *= a;
    }
    return ret;
  }
  friend modint inv(const modint& a) { return pow(a, mod - 2); }
  modint operator-() const { return modint(-v); }
  modint& operator++() { return *this += 1; }
  modint& operator--() { return *this -= 1; }
  friend modint operator+(modint a, const modint& b) { return a += b; }
  friend modint operator-(modint a, const modint& b) { return a -= b; }
  friend modint operator*(modint a, const modint& b) { return a *= b; }
  friend modint operator/(modint a, const modint& b) { return a /= b; }
  friend ostream& operator<<(ostream& out, modint a) { return out << a.v; }
  friend istream& operator>>(istream& in, modint& a) {
    long long b;
    in >> b;
    a.v = b;
    return in;
  }
};
using mint = modint<1000000007>;
struct change {
  int* ptr;
  int val, t;
  change(int* p, int v, int tin) : ptr(p), val(v), t(tin) {}
  void undo() { *ptr = val; }
};
struct dsu {
  vector<int> v, len;
  stack<change> st;
  int ttime, ct;
  dsu(int n) : v(n), len(n, 1), ttime(0), ct(n) { iota(v.begin(), v.end(), 0); }
  void make_change(int* p, int val) {
    change ch(p, *p, ttime);
    st.push(ch);
    *p = val;
  }
  void batch_undo() {
    assert(!st.empty());
    int tt = st.top().t;
    while (((int)((st).size())) && st.top().t == tt) {
      st.top().undo();
      st.pop();
    }
  }
  int root(int a) { return (v[a] == a ? a : root(v[a])); }
  bool unite(int a, int b) {
    ttime++;
    int a1 = root(a), b1 = root(b);
    if (a1 == b1) {
      make_change(&v[0], v[0]);
      return false;
    }
    make_change(&ct, ct - 1);
    if (len[a1] < len[b1]) swap(a1, b1);
    make_change(&len[a1], len[a1] + len[b1]);
    make_change(&v[b1], a1);
    return true;
  }
};
const int mx = 5e5 + 5;
int n, m, k;
long long a[mx];
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cin >> n >> m >> k;
  for (int q = 1; q <= n; q++) cin >> a[q];
  vector<array<long long, 3>> v(m);
  for (int q = 0; q < m; q++) {
    cin >> v[q][1] >> v[q][2];
    v[q][0] = a[v[q][1]] ^ a[v[q][2]];
  }
  sort(v.begin(), v.end());
  int q = 0, tot = 0;
  dsu d(n + 1);
  mint ans = 0;
  while (q < m) {
    tot++;
    int w = q;
    while (w < m && v[w][0] == v[q][0]) {
      d.unite(v[w][1], v[w][2]);
      w++;
    }
    ans += pow(mint(2), d.ct - 1);
    w = q;
    while (w < m && v[w][0] == v[q][0]) {
      d.batch_undo();
      w++;
    }
    q = w;
  }
  ans += (pow(mint(2), k) - tot) * pow(mint(2), n);
  cout << ans << '\n';
  return 0;
}
