#include <bits/stdc++.h>
using namespace std;
const long long p = 1e9 + 7;
const int MAXN = 2e5 + 5;
vector<int> tree[4 * MAXN];
int f[4 * MAXN], lazy[4 * MAXN];
int n, q, nums[MAXN];
vector<int> extra;
vector<int> addin(vector<int> a, vector<int> b) {
  for (int i = 0; i < b.size(); ++i) {
    int x = b[i];
    for (int j = 0; j < a.size(); ++j) {
      if (x == 0) break;
      if (__builtin_ctz(x) < __builtin_ctz(a[j])) {
        a.insert(a.begin() + j, x);
        x = 0;
        break;
      }
      if (__builtin_ctz(x) == __builtin_ctz(a[j])) x ^= a[j];
    }
    if (x != 0) a.push_back(x);
  }
  return a;
}
void init(int l = 0, int r = n - 1, int node = 1) {
  f[node] = nums[l];
  if (l == r) return;
  lazy[node] = 0;
  int mid = (l + r) / 2;
  init(l, mid, 2 * node);
  init(mid + 1, r, 2 * node + 1);
  tree[node] = addin(tree[2 * node], tree[2 * node + 1]);
  extra.clear();
  extra.push_back(nums[l] ^ nums[mid + 1]);
  tree[node] = addin(tree[node], extra);
}
void mark(int node, int x) {
  lazy[node] ^= x;
  f[node] ^= x;
}
void prop(int l, int r, int node) {
  if (l == r) return;
  mark(2 * node, lazy[node]);
  mark(2 * node + 1, lazy[node]);
  lazy[node] = 0;
}
vector<int> query2(int a, int b, int l = 0, int r = n - 1, int node = 1) {
  if (a == l && b == r) {
    extra.clear();
    extra.push_back(f[node]);
    return addin(tree[node], extra);
  }
  prop(l, r, node);
  int mid = (l + r) / 2;
  if (b <= mid) return query2(a, b, l, mid, 2 * node);
  if (a >= mid + 1) return query2(a, b, mid + 1, r, 2 * node + 1);
  return addin(query2(a, mid, l, mid, 2 * node),
               query2(mid + 1, b, mid + 1, r, 2 * node + 1));
}
void query1(int a, int b, int x, int l = 0, int r = n - 1, int node = 1) {
  if (a == l && b == r) {
    mark(node, x);
    return;
  }
  prop(l, r, node);
  int mid = (l + r) / 2;
  if (b <= mid)
    query1(a, b, x, l, mid, 2 * node);
  else if (a >= mid + 1)
    query1(a, b, x, mid + 1, r, 2 * node + 1);
  else
    query1(a, mid, x, l, mid, 2 * node),
        query1(mid + 1, b, x, mid + 1, r, 2 * node + 1);
  f[node] = f[2 * node];
  tree[node] = addin(tree[2 * node], tree[2 * node + 1]);
  extra.clear();
  extra.push_back(f[node] ^ f[2 * node + 1]);
  tree[node] = addin(tree[node], extra);
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> q;
  for (int i = 0; i < n; ++i) cin >> nums[i];
  init();
  for (int i = 0; i < q; ++i) {
    int x;
    cin >> x;
    if (x == 1) {
      int a, b, k;
      cin >> a >> b >> k;
      a--;
      b--;
      query1(a, b, k);
    } else {
      int a, b;
      cin >> a >> b;
      a--;
      b--;
      cout << (1 << query2(a, b).size()) << "\n";
    }
  }
}
