#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const int N = (int)1e5 + 9;
const int LOG = 20;
int a[N];
struct Node {
  long long ans;
  int li;
  int ri;
  vector<pair<int, int> > lef;
  vector<pair<int, int> > rig;
};
Node T[N * 4 + 512];
int k;
int re = 0;
Node unite(Node A, Node B) {
  if (A.ans == -1) return B;
  if (B.ans == -1) return A;
  Node R;
  R.ans = A.ans + B.ans;
  R.li = A.li;
  R.ri = B.ri;
  R.rig = A.rig;
  for (int i = 0; i < B.rig.size(); i++) {
    if (((R.rig.back().first) | B.rig[i].first) > R.rig.back().first) {
      R.rig.push_back(
          make_pair((R.rig.back().first | B.rig[i].first), B.rig[i].second));
    }
  }
  R.lef = B.lef;
  for (int i = 0; i < A.lef.size(); i++) {
    if (((R.lef.back().first) | A.lef[i].first) > R.lef.back().first) {
      R.lef.push_back(
          make_pair((R.lef.back().first | A.lef[i].first), A.lef[i].second));
    }
  }
  for (int i = 0; i < A.lef.size(); i++) {
    A.lef[i].second = (A.lef[i].second - A.li + 1);
  }
  for (int i = 0; i + 1 < A.lef.size(); i++) {
    A.lef[i].second -= A.lef[i + 1].second;
  }
  for (int i = 0; i < B.rig.size(); i++) {
    B.rig[i].second = (B.ri - B.rig[i].second + 1);
  }
  for (int i = 0; i + 1 < B.rig.size(); i++) {
    B.rig[i].second -= B.rig[i + 1].second;
  }
  for (int i = 0; i < A.lef.size(); i++) {
    for (int j = 0; j < B.rig.size(); j++) {
      if ((A.lef[i].first | B.rig[j].first) >= k) {
        R.ans += A.lef[i].second * 1ll * B.rig[j].second;
      }
    }
  }
  return R;
}
void build(int node, int cl, int cr) {
  if (cl == cr) {
    T[node].ans = (a[cl] >= k);
    T[node].li = cl;
    T[node].ri = cl;
    T[node].lef = {make_pair(a[cl], cl)};
    T[node].rig = {make_pair(a[cl], cl)};
    return;
  }
  int mid = (cl + cr) / 2;
  build(node * 2, cl, mid);
  build(node * 2 + 1, mid + 1, cr);
  T[node] = unite(T[node * 2], T[node * 2 + 1]);
}
void upd(int node, int cl, int cr, int pos, int x) {
  if (cl == cr) {
    T[node].ans = (x >= k);
    T[node].li = cl;
    T[node].ri = cl;
    T[node].lef = {make_pair(x, cl)};
    T[node].rig = {make_pair(x, cl)};
    return;
  }
  int mid = (cl + cr) / 2;
  if (mid >= pos)
    upd(node * 2, cl, mid, pos, x);
  else
    upd(node * 2 + 1, mid + 1, cr, pos, x);
  T[node] = unite(T[node * 2], T[node * 2 + 1]);
}
Node cur;
void ask(int node, int cl, int cr, int tl, int tr) {
  if (cr < tl) return;
  if (cl > tr) return;
  if (cl >= tl && cr <= tr) {
    cur = unite(cur, T[node]);
    return;
  }
  int mid = (cl + cr) / 2;
  ask(node * 2, cl, mid, tl, tr);
  ask(node * 2 + 1, mid + 1, cr, tl, tr);
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  ;
  int n, q;
  cin >> n >> q >> k;
  for (int i = 1; i <= n; i++) cin >> a[i];
  build(1, 1, n);
  int id, l, r;
  for (int i = 1; i <= q; i++) {
    cin >> id >> l >> r;
    if (id == 2) {
      cur.ans = -1;
      ask(1, 1, n, l, r);
      cout << cur.ans << "\n";
    } else {
      upd(1, 1, n, l, r);
    }
  }
  return 0;
}
