#include <bits/stdc++.h>
using namespace std;
mt19937 rnd(time(0));
bool isPrime(long long a) {
  int i;
  for (i = 2; i * i <= a; i++) {
    if (a % i == 0) {
      return 0;
    }
  }
  return (a != 1);
}
bool isPalindrom(const string& s, int l, int r) {
  for (int i = 0; i < (r - l + 1) / 2; i++) {
    if (s[l + i] != s[r - i]) {
      return 0;
    }
  }
  return 1;
}
template <class type1>
type1 gcd(type1 a, type1 b) {
  type1 t;
  while (b) {
    t = b;
    b = a % b;
    a = t;
  }
  return a;
}
long long positiveMod(long long v, long long md) {
  v = v % md;
  if (v < 0) {
    v += md;
  }
  return v;
}
struct node {
  vector<int> last, first;
  long long cnt;
  node() : cnt(0) {}
};
int x;
vector<node> segTree;
vector<int> val;
vector<node> inf;
void unit(node& parent, node& left, node& right) {
  parent.cnt = left.cnt + right.cnt;
  int vv;
  vv = 0;
  parent.last = right.last;
  for (auto it : parent.last) {
    vv |= val[it];
  }
  for (int i = 0; i < left.last.size(); i++) {
    int pp = left.last[i];
    if (i == left.last.size() - 1 || (vv | val[pp]) != vv) {
      parent.last.push_back(pp);
      vv |= val[pp];
    }
  }
  vv = 0;
  parent.first = left.first;
  for (auto it : parent.first) {
    vv |= val[it];
  }
  for (int i = 0; i < right.first.size(); i++) {
    int pp = right.first[i];
    if (i == right.first.size() - 1 || (val[pp] | vv) != vv) {
      parent.first.push_back(pp);
      vv |= val[pp];
    }
  }
  int init = 0;
  for (int i = 0; i < left.last.size(); i++) {
    init |= val[left.last[i]];
    int tv = init;
    int j = 0;
    tv |= val[right.first[0]];
    while (tv < x) {
      j++;
      if (j < right.first.size()) {
        tv |= val[right.first[j]];
      } else {
        break;
      }
    }
    long long lf;
    if (j == right.first.size()) {
      continue;
    }
    if (i == left.last.size() - 1) {
      lf = 1;
    } else {
      lf = left.last[i] - left.last[i + 1];
    }
    parent.cnt += lf * (right.first.back() - right.first[j] + 1);
  }
}
void build(int v, int l, int r) {
  if (l == r) {
    segTree[v].last.push_back(r);
    segTree[v].first.push_back(l);
    segTree[v].cnt = val[l] >= x ? 1 : 0;
  } else {
    int mid = (l + r) / 2;
    build(v * 2, l, mid);
    build(v * 2 + 1, mid + 1, r);
    unit(segTree[v], segTree[v * 2], segTree[v * 2 + 1]);
  }
}
void update(int v, int l, int r, int pos) {
  if (l == r) {
    segTree[v].cnt = val[l] >= x ? 1 : 0;
  } else {
    int mid = (l + r) / 2;
    if (pos <= mid) {
      update(v * 2, l, mid, pos);
    } else {
      update(v * 2 + 1, mid + 1, r, pos);
    }
    unit(segTree[v], segTree[v * 2], segTree[v * 2 + 1]);
  }
}
void get(int v, int l, int r, int tl, int tr) {
  if (tl == l && r == tr) {
    inf.push_back(segTree[v]);
  } else {
    int mid = (l + r) / 2;
    if (tr <= mid) {
      get(v * 2, l, mid, tl, tr);
    } else if (tl > mid) {
      get(v * 2 + 1, mid + 1, r, tl, tr);
    } else {
      get(v * 2, l, mid, tl, mid);
      get(v * 2 + 1, mid + 1, r, mid + 1, tr);
    }
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  ;
  int n, q, qq, i, j, a, b, c;
  cin >> n >> q >> x;
  for (i = 0; i < n; i++) {
    cin >> a;
    val.push_back(a);
  }
  segTree.resize(4 * n + 1);
  build(1, 0, n - 1);
  for (qq = 0; qq < q; qq++) {
    cin >> a;
    if (a == 1) {
      cin >> b >> c;
      val[b - 1] = c;
      update(1, 0, n - 1, b - 1);
    } else {
      cin >> b >> c;
      b--;
      c--;
      get(1, 0, n - 1, b, c);
      node ans = inf[0];
      for (i = 1; i < inf.size(); i++) {
        node tAns;
        unit(tAns, ans, inf[i]);
        ans = tAns;
      }
      cout << ans.cnt << "\n";
      inf.clear();
    }
  }
  return 0;
}
