#include <bits/stdc++.h>
using namespace std;

const int MX = 30005;
int Arr[MX];
multiset <int> tree[4 * MX];

void build(int node, int st, int en){
	if(st == en){
		tree[node].clear();
		tree[node].insert(Arr[st]);
		return;
	}
	
	int left = 2*node, right = left + 1, mid = (en + st)/2;
	build(left, st, mid);
	build(right, mid + 1, en);
	
	tree[node].clear();
	tree[node].insert(tree[left].begin(), tree[left].end());
	tree[node].insert(tree[right].begin(), tree[right].end());
}

void update(int node, int st, int en, int l, int r, int newV, int oldV){
	if(st > r || en < l) return;
	if(st >= l && en <= r){
		Arr[st] = newV;
		tree[node].clear();
		tree[node].insert(newV);
		return;
	}
	
	int left = 2*node, right = left + 1, mid = (en + st)/2;
	update(left, st, mid, l, r, newV, oldV);
	update(right, mid + 1, en, l, r, newV, oldV);
	multiset<int>:: iterator it;
	it = tree[node].lower_bound(oldV);
	tree[node].erase(it);
	tree[node].insert(newV);
}

int query(int node, int st, int en, int l, int r, int num){
	if(st > r || en < l) return 0;
	if(st >= l && en <= r){
		int sz = en - st + 1;
		multiset<int>:: iterator it;
	    it = tree[node].upper_bound(num);
	    int id = distance(tree[node].begin(), it);
	    return (sz - id);
	}
	int left = 2*node, right = left + 1, mid = (en + st)/2;
	int p = query(left, st, mid, l, r, num);
	int q = query(right, mid + 1, en, l, r, num);
	return p + q;
}

int main() {
	int n, q, flag, l, r, num;
	for(; scanf("%d", &n) == 1 ;){
		for(int i = 1; i <= n; i++) scanf("%d", &Arr[i]);
		build(1,1,n);
		
		scanf("%d", &q);
		for(int i = 0; i<q; i++){
			scanf("%d", &flag);
			if(flag){
			    scanf("%d %d %d", &l, &r, &num);
			    printf("%d\n", query(1,1,n,l,r,num));
			}else{
				scanf("%d %d", &l, &num);
				update(1,1,n,l,l,num,Arr[l]);
			}
		}
	}
	return 0;
}