#include <bits/stdc++.h>
using namespace std;
long long power(long long a, long long b, long long md) {
  return (!b ? 1
             : (b & 1 ? a * power(a * a % md, b / 2, md) % md
                      : power(a * a % md, b / 2, md) % md));
}
const int xn = 1e5 + 10;
const int xm = -20 + 10;
const int sq = 320;
const int inf = 1e9 + 10;
const long long INF = 1e18 + 10;
const int mod = 1e9 + 7;
const int base = 257;
struct node {
  bool istohi = false;
  long long ans = 0;
  vector<pair<int, long long> > vec[2];
};
int n, m, val, a[xn], ptr;
long long sum;
node seg[xn << 2], tohi;
node merge(node v, node u) {
  node w;
  if (v.istohi) return u;
  if (u.istohi) return v;
  for (pair<int, long long> x : v.vec[0]) w.vec[0].push_back(x);
  for (pair<int, long long> x : u.vec[0]) {
    pair<int, long long> y = w.vec[0].back(), z = x;
    z.first |= y.first;
    if (z.first > y.first)
      w.vec[0].push_back(z);
    else
      w.vec[0].back().second += x.second;
  }
  for (pair<int, long long> x : u.vec[1]) w.vec[1].push_back(x);
  for (pair<int, long long> x : v.vec[1]) {
    pair<int, long long> y = w.vec[1].back(), z = x;
    z.first |= y.first;
    if (z.first > y.first)
      w.vec[1].push_back(z);
    else
      w.vec[1].back().second += x.second;
  }
  w.ans = v.ans + u.ans;
  ptr = int(u.vec[0].size()) - 1, sum = 0;
  for (int i = 0; i < int(v.vec[1].size()); ++i) {
    while (ptr >= 0 && (v.vec[1][i].first | u.vec[0][ptr].first) >= val)
      sum += u.vec[0][ptr].second, --ptr;
    w.ans += v.vec[1][i].second * sum;
  }
  return w;
}
void build(int id, int l, int r) {
  seg[id].istohi = false;
  if (r - l == 1) {
    seg[id].vec[0].push_back({a[l], 1});
    seg[id].vec[1].push_back({a[l], 1});
    if (a[l] >= val) seg[id].ans = 1;
    return;
  }
  int mid = l + r >> 1;
  build(id << 1, l, mid);
  build(id << 1 | 1, mid, r);
  seg[id] = merge(seg[id << 1], seg[id << 1 | 1]);
}
void modify(int id, int l, int r, int pos, int x) {
  if (r - l == 1) {
    a[pos] = x;
    seg[id].vec[0].back().first = x;
    seg[id].vec[1].back().first = x;
    if (a[l] >= val)
      seg[id].ans = 1;
    else
      seg[id].ans = 0;
    return;
  }
  int mid = l + r >> 1;
  if (pos < mid)
    modify(id << 1, l, mid, pos, x);
  else
    modify(id << 1 | 1, mid, r, pos, x);
  seg[id] = merge(seg[id << 1], seg[id << 1 | 1]);
}
node get(int id, int l, int r, int ql, int qr) {
  if (qr <= l || r <= ql) return tohi;
  if (ql <= l && r <= qr) return seg[id];
  int mid = l + r >> 1;
  return merge(get(id << 1, l, mid, ql, qr), get(id << 1 | 1, mid, r, ql, qr));
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  ;
  cin >> n >> m >> val;
  for (int i = 1; i <= n; ++i) cin >> a[i];
  tohi.istohi = true;
  build(1, 1, n + 1);
  while (m--) {
    int t, x, y;
    cin >> t >> x >> y;
    if (t == 1)
      modify(1, 1, n + 1, x, y);
    else
      cout << get(1, 1, n + 1, x, y + 1).ans << '\n';
  }
  return 0;
}
