#include <bits/stdc++.h>
using namespace std;
const int inf = 1e9;
const double eps = 1e-9;
const double pi = 4 * atan(1.0);
const int N = int(2e5) + 100;
const int LOG = 30;
int maxv;
int a[N], add[4 * N];
vector<int> rmq[4 * N];
inline int bit(int mask, int pos) { return (mask >> pos) & 1; }
inline vector<int> go(vector<int> c) {
  vector<int> res;
  for (int i = 0; i < LOG; ++i) {
    bool fl = false;
    for (int j = ((int)(res).size()); j < ((int)(c).size()); ++j) {
      if (bit(c[j], i)) {
        swap(c[((int)(res).size())], c[j]);
        fl = true;
        break;
      }
    }
    if (!fl) {
      continue;
    }
    res.push_back(c[((int)(res).size())]);
    for (int j = ((int)(res).size()); j < ((int)(c).size()); ++j) {
      if (bit(c[j], i)) {
        c[j] ^= res.back();
      }
    }
  }
  return res;
}
inline vector<int> merge(const vector<int>& a, const vector<int>& b) {
  vector<int> c;
  c.insert(c.end(), (a).begin(), (a).end());
  c.insert(c.end(), (b).begin(), (b).end());
  return go(c);
}
void update(int v, int gl, int gr, int l, int r, int val) {
  if (gl > r || gr < l || l > r) {
    return;
  }
  if (gl >= l && gr <= r) {
    add[v] ^= val;
    return;
  }
  int mid = (gl + gr) / 2;
  update(v * 2, gl, mid, l, r, val);
  update(v * 2 + 1, mid + 1, gr, l, r, val);
}
inline int get_val(int pos) {
  int res = a[pos];
  pos += maxv;
  while (pos) {
    res ^= add[pos];
    pos /= 2;
  }
  return res;
}
inline void update_rmq(int pos, int val) {
  pos += maxv;
  rmq[pos].clear();
  if (val != 0) {
    rmq[pos].push_back(val);
  }
  while (pos > 1) {
    pos /= 2;
    rmq[pos] = merge(rmq[pos * 2], rmq[pos * 2 + 1]);
  }
}
vector<int> get(int v, int gl, int gr, int l, int r) {
  if (gl > r || gr < l || l > r) {
    return vector<int>();
  }
  if (gl >= l && gr <= r) {
    return rmq[v];
  }
  int mid = (gl + gr) / 2;
  return merge(get(v * 2, gl, mid, l, r), get(v * 2 + 1, mid + 1, gr, l, r));
}
inline vector<int> add_one(vector<int> a, int b) {
  vector<int> c;
  c.insert(c.end(), (a).begin(), (a).end());
  c.push_back(b);
  return go(c);
}
int main() {
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < n; ++i) {
    scanf("%d", a + i);
  }
  maxv = 1;
  while (maxv < n) {
    maxv *= 2;
  }
  for (int i = 0; i + 1 < n; ++i) {
    if ((a[i] ^ a[i + 1]) != 0) {
      rmq[i + maxv].push_back(a[i] ^ a[i + 1]);
    }
  }
  for (int i = maxv - 1; i > 0; --i) {
    rmq[i] = merge(rmq[i * 2], rmq[i * 2 + 1]);
  }
  for (int i = 0; i < m; ++i) {
    int t, l, r;
    scanf("%d %d %d", &t, &l, &r);
    --l;
    --r;
    if (t == 1) {
      int k;
      scanf("%d", &k);
      update(1, 0, maxv - 1, l, r, k);
      if (l > 0) {
        update_rmq(l - 1, get_val(l - 1) ^ get_val(l));
      }
      if (r + 1 < n) {
        update_rmq(r, get_val(r) ^ get_val(r + 1));
      }
      continue;
    }
    assert(t == 2);
    vector<int> res = get(1, 0, maxv - 1, l, r - 1);
    res = add_one(res, get_val(l));
    printf(
        "%lld"
        "\n",
        (1LL << ((int)(res).size())));
  }
  return 0;
}
