Java program:
import java . io . * ; import java . util . * ; class GFG { static int MAX = 1000 ; static void sieveOfEratosthenes ( boolean isPrime [ ] ) { isPrime [ 1 ] = false ; for ( int p = 2 ; p * p <= MAX ; p ++ ) { if ( isPrime [ p ] == true ) { for ( int i = p * 2 ; i <= MAX ; i += p ) isPrime [ i ] = false ; } } } static int getMid ( int s , int e ) { return s + ( e - s ) / 2 ; } static int queryPrimesUtil ( int [ ] st , int ss , int se , int qs , int qe , int index ) { if ( qs <= ss && qe >= se ) return st [ index ] ; if ( se < qs ss > qe ) return 0 ; int mid = getMid ( ss , se ) ; return queryPrimesUtil ( st , ss , mid , qs , qe , 2 * index + 1 ) + queryPrimesUtil ( st , mid + 1 , se , qs , qe , 2 * index + 2 ) ; } static void updateValueUtil ( int [ ] st , int ss , int se , int i , int diff , int si ) { if ( i < ss i > se ) return ; st [ si ] = st [ si ] + diff ; if ( se != ss ) { int mid = getMid ( ss , se ) ; updateValueUtil ( st , ss , mid , i , diff , 2 * si + 1 ) ; updateValueUtil ( st , mid + 1 , se , i , diff , 2 * si + 2 ) ; } } static void updateValue ( int arr [ ] , int [ ] st , int n , int i , int new_val , boolean isPrime [ ] ) { if ( i < 0 i > n - 1 ) { System . out . println ( " Invalid ▁ Input " ) ; return ; } int diff = 0 ; int oldValue ; oldValue = arr [ i ] ; arr [ i ] = new_val ; if ( isPrime [ oldValue ] && isPrime [ new_val ] ) return ; if ( ( ! isPrime [ oldValue ] ) && ( ! isPrime [ new_val ] ) ) return ; if ( isPrime [ oldValue ] && ! isPrime [ new_val ] ) { diff = - 1 ; } if ( ! isPrime [ oldValue ] && isPrime [ new_val ] ) { diff = 1 ; } updateValueUtil ( st , 0 , n - 1 , i , diff , 0 ) ; } static void queryPrimes ( int [ ] st , int n , int qs , int qe ) { int primesInRange = queryPrimesUtil ( st , 0 , n - 1 , qs , qe , 0 ) ; System . out . println ( " Number ▁ of ▁ Primes ▁ in ▁ subarray ▁ from ▁ " + qs + " ▁ to ▁ " + qe + " ▁ = ▁ " + primesInRange ) ; } static int constructSTUtil ( int arr [ ] , int ss , int se , int [ ] st , int si , boolean isPrime [ ] ) { if ( ss == se ) { if ( isPrime [ arr [ ss ] ] ) st [ si ] = 1 ; else st [ si ] = 0 ; return st [ si ] ; } int mid = getMid ( ss , se ) ; st [ si ] = constructSTUtil ( arr , ss , mid , st , si * 2 + 1 , isPrime ) + constructSTUtil ( arr , mid + 1 , se , st , si * 2 + 2 , isPrime ) ; return st [ si ] ; } static int [ ] constructST ( int arr [ ] , int n , boolean isPrime [ ] ) { int x = ( int ) ( Math . ceil ( Math . log ( n ) / Math . log ( 2 ) ) ) ; int max_size = 2 * ( int ) Math . pow ( 2 , x ) - 1 ; int [ ] st = new int [ max_size ] ; constructSTUtil ( arr , 0 , n - 1 , st , 0 , isPrime ) ; return st ; } public static void main ( String [ ] args ) { int arr [ ] = { 1 , 2 , 3 , 5 , 7 , 9 } ; int n = arr . length ; boolean [ ] isPrime = new boolean [ MAX + 1 ] ; Arrays . fill ( isPrime , Boolean . TRUE ) ; sieveOfEratosthenes ( isPrime ) ; int [ ] st = constructST ( arr , n , isPrime ) ; int start = 0 ; int end = 4 ; queryPrimes ( st , n , start , end ) ; int i = 3 ; int x = 6 ; updateValue ( arr , st , n , i , x , isPrime ) ; start = 0 ; end = 4 ; queryPrimes ( st , n , start , end ) ; } }

Index/key variables: i, index, max_size, new_val, oldValue, p, si, ss
Accumulator variables: i, p
Iterator variables: i, p
Class/struct names: GFG