#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 1;
int n, Q, x, a[maxn];
struct node {
  long long ans;
  int L, R;
  vector<pair<int, int> > prefix, suffix;
};
node seg[4 * maxn];
node Merge(node a, node b) {
  int tmp;
  if (a.ans == -1) {
    return b;
  }
  if (b.ans == -1) {
    return a;
  }
  node res;
  res.ans = a.ans + b.ans;
  res.L = a.L;
  res.R = b.R;
  res.prefix = a.prefix;
  tmp = a.prefix.back().second;
  for (int i = 0; i < (int)b.prefix.size(); i++) {
    if ((tmp | b.prefix[i].second) != tmp) {
      tmp = tmp | b.prefix[i].second;
      res.prefix.push_back({b.prefix[i].first, tmp});
    }
  }
  res.suffix = b.suffix;
  tmp = b.suffix.back().second;
  for (int i = 0; i < (int)a.suffix.size(); i++) {
    if ((tmp | a.suffix[i].second) != tmp || i == (int)a.suffix.size() - 1) {
      tmp = tmp | a.suffix[i].second;
      res.suffix.push_back({a.suffix[i].first, tmp});
    }
  }
  int j = 0;
  int las = a.L - 1;
  int flag = 0;
  for (int i = (int)a.suffix.size() - 1; i >= 0; i--) {
    while ((b.prefix[j].second | a.suffix[i].second) < x) {
      j++;
      if (j >= (int)b.prefix.size()) {
        flag = 1;
        break;
      }
    }
    if (flag == 1) {
      break;
    }
    res.ans += 1ll * (a.suffix[i].first - las) * (res.R - b.prefix[j].first);
    las = a.suffix[i].first;
  }
  return res;
}
void build(int id = 1, int L = 1, int R = n + 1) {
  if (L == R - 1) {
    if (a[L] >= x) {
      seg[id].ans = 1;
    }
    seg[id].L = L;
    seg[id].R = R;
    seg[id].prefix.push_back({L, a[L]});
    seg[id].suffix.push_back({L, a[L]});
    return;
  }
  int mid = (L + R) / 2;
  build(id * 2, L, mid);
  build(id * 2 + 1, mid, R);
  seg[id] = Merge(seg[id * 2], seg[id * 2 + 1]);
  return;
}
void upd(int t1, int t2, int id = 1, int L = 1, int R = n + 1) {
  if (L == R - 1) {
    if (t2 >= x) {
      seg[id].ans = 1;
    } else {
      seg[id].ans = 0;
    }
    seg[id].L = L;
    seg[id].R = R;
    seg[id].prefix.clear();
    seg[id].suffix.clear();
    seg[id].prefix.push_back({L, t2});
    seg[id].suffix.push_back({L, t2});
    return;
  }
  int mid = (L + R) / 2;
  if (t1 < mid) {
    upd(t1, t2, id * 2, L, mid);
  } else {
    upd(t1, t2, id * 2 + 1, mid, R);
  }
  seg[id] = Merge(seg[id * 2], seg[id * 2 + 1]);
}
node query(int s, int f, int id = 1, int L = 1, int R = n + 1) {
  if (f <= L || R <= s) {
    node t;
    t.ans = -1;
    return t;
  }
  if (s <= L && R <= f) {
    return seg[id];
  }
  int mid = (L + R) / 2;
  return Merge(query(s, f, id * 2, L, mid), query(s, f, id * 2 + 1, mid, R));
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> Q >> x;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
  }
  build();
  for (int i = 1; i <= Q; i++) {
    int tmp1;
    cin >> tmp1;
    if (tmp1 == 1) {
      int tmp2, tmp3;
      cin >> tmp2 >> tmp3;
      upd(tmp2, tmp3);
    } else {
      int tmp2, tmp3;
      cin >> tmp2 >> tmp3;
      node temp = query(tmp2, tmp3 + 1);
      cout << temp.ans << endl;
    }
  }
  return 0;
}
