#include <bits/stdc++.h>
using namespace std;
const int maxN = 2 * 1000 * 100 + 100;
const int maxS = 4 * maxN;
vector<int> seg[maxS];
int f[maxS], toxor[maxS];
int n;
inline vector<int> merge(vector<int> a, vector<int> b) {
  for (auto x : b) {
    for (auto y : a)
      if (x & (y & -y)) x ^= y;
    if (x) {
      for (auto& y : a)
        if (y & (x & -x)) y ^= x;
      a.push_back(x);
    }
  }
  return a;
}
inline void handle(int ind, int qv) {
  f[ind] ^= qv;
  toxor[ind] ^= qv;
}
inline void shift(int ind) {
  handle(ind * 2, toxor[ind]);
  handle(ind * 2 + 1, toxor[ind]);
  toxor[ind] = 0;
}
inline vector<int> val(int ind) {
  vector<int> tmp;
  tmp.push_back(f[ind]);
  return merge(seg[ind], tmp);
}
void add(int ql, int qr, int qv, int xl = 0, int xr = n, int ind = 1) {
  if (xr <= ql || qr <= xl) return;
  if (ql <= xl && xr <= qr) {
    handle(ind, qv);
    return;
  }
  int xm = (xl + xr) / 2;
  shift(ind);
  add(ql, qr, qv, xl, xm, ind * 2);
  add(ql, qr, qv, xm, xr, ind * 2 + 1);
  f[ind] = f[ind * 2];
  vector<int> tmp;
  tmp.push_back(f[ind * 2 + 1] ^ f[ind * 2]);
  seg[ind] = merge(merge(seg[ind * 2], seg[ind * 2 + 1]), tmp);
}
vector<int> get(int ql, int qr, int xl = 0, int xr = n, int ind = 1) {
  if (xr <= ql || qr <= xl) return vector<int>();
  if (ql <= xl && xr <= qr) return val(ind);
  int xm = (xl + xr) / 2;
  shift(ind);
  return merge(get(ql, qr, xl, xm, ind * 2), get(ql, qr, xm, xr, ind * 2 + 1));
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int q;
  cin >> n >> q;
  for (int i = 0; i < n; i++) {
    int x;
    cin >> x;
    add(i, i + 1, x);
  }
  for (int i = 0; i < q; i++) {
    int t;
    cin >> t;
    if (t == 1) {
      int l, r, k;
      cin >> l >> r >> k;
      add(l - 1, r, k);
    } else {
      int l, r;
      cin >> l >> r;
      cout << (1 << get(l - 1, r).size()) << '\n';
    }
  }
}
