#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:1280000000")
using namespace std;
void solve();
void precalc();
clock_t start;
int testNumber = 1;
bool todo = true;
int main() {
  start = clock();
  int t = 1;
  cout.sync_with_stdio(0);
  cin.tie(0);
  precalc();
  cout.precision(10);
  cout << fixed;
  int testNum = 1;
  while (t--) {
    solve();
    ++testNumber;
  }
  return 0;
}
int binpow(int q, int w, int mod) {
  if (!w) return 1 % mod;
  if (w & 1) return q * 1LL * binpow(q, w - 1, mod) % mod;
  return binpow(q * 1LL * q % mod, w / 2, mod);
}
void precalc() {}
int gcd(int q, int w) {
  while (w) {
    q %= w;
    swap(q, w);
  }
  return q;
}
struct Node {
  vector<int> basis;
  vector<int> min_bits;
  vector<int> adds;
  int push_xor;
  Node() { push_xor = 0; }
  Node(int cur) {
    push_xor = 0;
    basis.clear();
    adds = vector<int>(1, cur);
  }
};
const int shift = 1 << 18;
Node tree[2 * shift + 6];
void push(int v) {
  for (int h = 0; h < 2; ++h) {
    tree[2 * v + h].push_xor ^= tree[v].push_xor;
  }
  tree[v].push_xor = 0;
}
const int L = 30;
int minimal_bit[1 << 16];
int get_min_bit(int new_row) {
  if (!new_row) {
    return -1;
  }
  if (new_row & ((1 << 16) - 1)) {
    return minimal_bit[new_row & ((1 << 16) - 1)];
  }
  new_row >>= 16;
  return minimal_bit[new_row & ((1 << 16) - 1)] + 16;
}
pair<int, int> eliminate(int new_row, const vector<int>& rows,
                         const vector<int>& min_bits) {
  for (int i = 0; i < rows.size(); ++i) {
    if (new_row & (1 << min_bits[i])) {
      new_row ^= rows[i];
    }
  }
  return make_pair(new_row, get_min_bit(new_row));
}
Node merge(const Node& q, const Node& w) {
  Node res;
  vector<int> new_adds;
  int hasQ = -1;
  for (int item : q.adds) {
    item ^= q.push_xor;
    new_adds.push_back(item);
    hasQ = item;
  }
  int hasW = -1;
  for (int item : w.adds) {
    item ^= w.push_xor;
    new_adds.push_back(item);
    hasW = item;
  }
  sort(new_adds.begin(), new_adds.end());
  new_adds.erase(unique(new_adds.begin(), new_adds.end()), new_adds.end());
  if (new_adds.size() > 1) {
    new_adds.resize(1);
  }
  res.adds.swap(new_adds);
  res.basis = q.basis;
  res.min_bits = q.min_bits;
  for (int item : w.basis) {
    pair<int, int> add = eliminate(item, res.basis, res.min_bits);
    if (add.first) {
      res.basis.push_back(add.first);
      res.min_bits.push_back(add.second);
    }
  }
  if (hasQ != -1 && hasW != -1) {
    int new_row = hasQ ^ hasW;
    if (new_row) {
      pair<int, int> add = eliminate(new_row, res.basis, res.min_bits);
      if (add.first) {
        res.basis.push_back(add.first);
        res.min_bits.push_back(add.second);
      }
    }
  }
  return res;
}
void build(int v, int tl, int tr, const vector<int>& a) {
  if (tl + 1 == tr) {
    tree[v] = Node(a[tl]);
    return;
  }
  int tm = (tl + tr) / 2;
  build(2 * v, tl, tm, a);
  build(2 * v + 1, tm, tr, a);
  tree[v] = merge(tree[2 * v], tree[2 * v + 1]);
}
void make_xor(int v, int tl, int tr, int l, int r, int k) {
  if (r <= tl || tr <= l) {
    return;
  }
  if (l <= tl && tr <= r) {
    tree[v].push_xor ^= k;
    return;
  }
  int tm = (tl + tr) / 2;
  push(v);
  make_xor(2 * v, tl, tm, l, r, k);
  make_xor(2 * v + 1, tm, tr, l, r, k);
  tree[v] = merge(tree[2 * v], tree[2 * v + 1]);
}
Node get_node(int v, int tl, int tr, int l, int r) {
  if (r <= tl || tr <= l) {
    return Node();
  }
  if (l <= tl && tr <= r) {
    return tree[v];
  }
  int tm = (tl + tr) / 2;
  push(v);
  Node res =
      merge(get_node(2 * v, tl, tm, l, r), get_node(2 * v + 1, tm, tr, l, r));
  tree[v] = merge(tree[2 * v], tree[2 * v + 1]);
  return res;
}
long long get_rank(const Node& res) {
  int rk = res.basis.size();
  for (int item : res.adds) {
    item ^= res.push_xor;
    if (item && eliminate(item, res.basis, res.min_bits).first) {
      ++rk;
      break;
    }
  }
  long long ans = 1;
  for (int i = 0; i < rk; ++i) {
    ans = ans * 2;
  }
  return ans;
}
int getRandom() { return ((rand() << 15) | rand()); }
void solve() {
  for (int mask = 0; mask < (1 << 16); ++mask) {
    for (int i = 0; i < 16; ++i) {
      if (mask & (1 << i)) {
        minimal_bit[mask] = i;
        break;
      }
    }
  }
  int n, Q;
  cin >> n >> Q;
  vector<int> a(n);
  for (int i = 0; i < n; ++i) {
    cin >> a[i];
  }
  build(1, 0, n, a);
  while (Q--) {
    int type;
    cin >> type;
    int l, r;
    cin >> l >> r;
    --l;
    if (type == 1) {
      int k;
      cin >> k;
      make_xor(1, 0, n, l, r, k);
    } else {
      Node res = get_node(1, 0, n, l, r);
      cout << get_rank(res) << "\n";
    }
  }
}
