#include <bits/stdc++.h>
using namespace std;
int x;
struct node {
  vector<int> lst;
  vector<int> f;
  long long cnt;
  node() : cnt(0) {}
};
vector<node> t;
vector<int> a;
void merge(node& ans, node& l, node& r) {
  ans.cnt = l.cnt + r.cnt;
  int val = 0;
  ans.lst = r.lst;
  for (int pos : ans.lst) {
    val |= a[pos];
  }
  for (int j = 0; j < (int)(l.lst).size(); ++j) {
    int pos = l.lst[j];
    if ((val | a[pos]) != val || j == (int)(l.lst).size() - 1) {
      ans.lst.push_back(pos);
      val |= a[pos];
    }
  }
  ans.f = l.f;
  val = 0;
  for (int pos : ans.f) {
    val |= a[pos];
  }
  for (int j = 0; j < (int)(r.f).size(); ++j) {
    int pos = r.f[j];
    if ((val | a[pos]) != val || j == (int)(r.f).size() - 1) {
      ans.f.push_back(pos);
      val |= a[pos];
    }
  }
  int init = 0;
  for (int i = 0; i < (int)(l.lst).size(); ++i) {
    init |= a[l.lst[i]];
    val = init;
    int j = 0;
    val |= a[r.f[0]];
    while (val < x) {
      ++j;
      if (j < (int)(r.f).size()) {
        val |= a[r.f[j]];
      } else {
        break;
      }
    }
    if (j == (int)(r.f).size()) {
      continue;
    }
    long long lf;
    if (i == (int)(l.lst).size() - 1) {
      lf = 1;
    } else {
      lf = l.lst[i] - l.lst[i + 1];
    }
    ans.cnt += lf * (r.f.back() - r.f[j] + 1);
  }
}
void build(int v, int tl, int tr) {
  if (tl == tr) {
    t[v].lst = {tl};
    t[v].f = {tl};
    if (a[tl] >= x) {
      t[v].cnt = 1;
    } else {
      t[v].cnt = 0;
    }
    return;
  }
  int tm = (tl + tr) >> 1;
  build(v * 2, tl, tm);
  build(v * 2 + 1, tm + 1, tr);
  merge(t[v], t[v * 2], t[v * 2 + 1]);
}
void update(int v, int tl, int tr, int pos) {
  if (tl == tr) {
    t[v].lst = {tl};
    t[v].f = {tl};
    if (a[tl] >= x) {
      t[v].cnt = 1;
    } else {
      t[v].cnt = 0;
    }
    return;
  }
  int tm = (tl + tr) >> 1;
  if (pos <= tm) {
    update(v * 2, tl, tm, pos);
  } else {
    update(v * 2 + 1, tm + 1, tr, pos);
  }
  merge(t[v], t[v * 2], t[v * 2 + 1]);
}
void sep(int v, int tl, int tr, int l, int r, vector<node>& ans) {
  if (tl == l && tr == r) {
    ans.push_back(t[v]);
    return;
  }
  int tm = (tl + tr) >> 1;
  if (l <= tm) {
    sep(v * 2, tl, tm, l, min(r, tm), ans);
  }
  if (r > tm) {
    sep(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r, ans);
  }
}
int main() {
  int n;
  cin >> n;
  int q;
  cin >> q;
  cin >> x;
  a.resize(n);
  for (int i = 0; i < n; ++i) {
    cin >> a[i];
  }
  t.resize(4 * n);
  build(1, 0, n - 1);
  while (q--) {
    int type;
    cin >> type;
    if (type == 1) {
      int pos, val;
      cin >> pos >> val;
      --pos;
      a[pos] = val;
      update(1, 0, n - 1, pos);
    } else {
      int l, r;
      cin >> l >> r;
      --l, --r;
      vector<node> vct;
      sep(1, 0, n - 1, l, r, vct);
      node ans = vct[0];
      for (int i = 1; i < (int)(vct).size(); ++i) {
        node tmp;
        merge(tmp, ans, vct[i]);
        ans = tmp;
      }
      cout << ans.cnt << "\n";
    }
  }
}
