using System;
class GFG
{
// Function to compute GCD of two numbers
static int gcd(int a, int b)
{
if (b == 0) return a;
return gcd(b, a % b);
}
// Function to count distinct prime factors of a number
static int countPrimeFactors(int x)
{
if (x <= 1) return 0;
int count = 0;
for (int i = 2; i * i <= x; i++)
{
if (x % i == 0)
{
count++;
while (x % i == 0)
{
x /= i;
}
}
}
if (x > 1) count++;
return count;
}
// Build segment tree storing GCD for each segment
static void buildGCDTree(int[] A, int[] seg, int node, int start, int end)
{
if (start == end)
{
seg[node] = A[start];
}
else
{
int mid = (start + end) / 2;
buildGCDTree(A, seg, 2 * node + 1, start, mid);
buildGCDTree(A, seg, 2 * node + 2, mid + 1, end);
seg[node] = gcd(seg[2 * node + 1], seg[2 * node + 2]);
}
}
// Query GCD for range [L, R] in segment tree
static int queryGCD(int[] seg, int node, int start, int end, int L, int R)
{
// No overlap
if (R < start || end < L) return 0;
// Complete overlap
if (L <= start && end <= R) return seg[node];
// Partial overlap
int mid = (start + end) / 2;
int leftGCD = queryGCD(seg, 2 * node + 1, start, mid, L, R);
int rightGCD = queryGCD(seg, 2 * node + 2, mid + 1, end, L, R);
return gcd(leftGCD, rightGCD);
}
static int[] solve(int[] A, int[,] Q)
{
int n = A.Length;
int q = Q.GetLength(0);
int[] ans = new int[q];
// Segment Tree
int[] seg = new int[4 * n];
// Build the segment tree
buildGCDTree(A, seg, 0, 0, n - 1);
// Process each query
for (int k = 0; k < q; k++)
{
// Convert to 0-based index
int L = Q[k, 0] - 1;
int R = Q[k, 1] - 1;
// Get GCD of range
int rangeGCD = queryGCD(seg, 0, 0, n - 1, L, R);
// Count prime factors of GCD
ans[k] = countPrimeFactors(rangeGCD);
}
return ans;
}
static void Main()
{
int[] A = { 2, 4, 6, 1, 9 };
int[,] Q =
{
{ 1, 5 },
{ 3, 3 },
{ 2, 3 }
};
int[] result = solve(A, Q);
foreach (int x in result)
{
Console.Write(x + " ");
}
}
}