/*
    Marko Bakovic
    Pijaca
*/

#include <cstdio>
#include <algorithm>
#include <vector>
#include <cmath>

using namespace std;

const int maxn = 5e4 + 5;

int n, size, queue[ maxn ], q;

vector < int > bucket[ 300 ];

int get( int idx, int low, int up )
{
    int left = 0, right = bucket[ idx ].size() - 1;
    if ( bucket[ idx ][ right ] < low ) return 0;
    if ( bucket[ idx ][ left ] > up ) return 0;
    int start, end;
    if ( low <= bucket[ idx ][ left ] ) start = left;
    else
    {
        while ( left < right )
        {
            int mid = ( left + right ) / 2;
            if ( bucket[ idx ][ mid ] < low ) left = mid + 1;
            else right = mid;
        }
        start = left;
    }
    left = 0; right = bucket[ idx ].size() - 1;
    if ( up >= bucket[ idx ][ right ] ) end = right;
    else
    {
        while ( left < right )
        {
            int mid = ( left + right + 1 ) / 2;
            if ( bucket[ idx ][ mid ] > up ) right = mid - 1;
            else left = mid;
        }
        end = left;
    }
    return ( end - start + 1 );
}

int solve( int left, int right, int low, int up )
{
    int idxLeft = left / size;
    int posLeft = left % size;
    int idxRight = right / size;
    int posRight = right % size;
    if ( idxLeft == idxRight )
    {
        int cnt = 0;
        for ( int i = left; i <= right; i++ )
            if ( queue[ i ] >= low && queue[ i ] <= up ) cnt++;
        return cnt;
    }
    int ret = 0;
    for ( int i = idxLeft * size + posLeft; i < min( n, ( idxLeft + 1 ) * size ); i++ )
        if ( queue[ i ] >= low && queue[ i ] <= up ) ret++;
    for ( int i = idxRight * size; i <= idxRight * size + posRight; i++ )
        if ( queue[ i ] >= low && queue[ i ] <= up ) ret++;
    for ( int i = idxLeft + 1; i < idxRight; i++ ) ret += get( i, low, up );
    return ret;
}

int main()
{
    freopen( "pijaca.in", "r", stdin );
    //freopen( "pijaca.out", "w", stdout );

    scanf( "%d", &n );

    size = sqrt( n );
    for ( int i = 0; i < n; i++ )
    {
        scanf( "%d", &queue[ i ] );
        bucket[ ( i / size ) ].push_back( queue[ i ] );
    }

    for ( int i = 0; i <= ( n - 1 ) / size; i++ ) sort( bucket[ i ].begin(), bucket[ i ].end() );

    scanf( "%d", &q );
    while ( q-- )
    {
        int type;
        scanf( "%d", &type );
        if ( type == 2 )
        {
            int x, y;
            scanf( "%d %d", &x, &y );
            x--;
            if ( queue[ x ] == y ) continue;
            queue[ x ] = y;
            int idx = x / size;
            int pos = x % size;
            bucket[ idx ][ pos ] = y;
            sort( bucket[ idx ].begin(), bucket[ idx ].end() );
        }
        else
        {
            int left, right, low, up;
            scanf( "%d %d %d %d", &left, &right, &low, &up );
            printf( "%d\n", solve( left - 1, right - 1, low, up ) );
        }
    }

    return 0;
}
