#include<bits/stdc++.h> using namespace std; #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> using namespace __gnu_pbds; #define ll long long #define db double #define el "\n" #define ld long double #define rep(i,n) for(int i=0;i<n;i++) #define rev(i,n) for(int i=n;i>=0;i--) #define rep_a(i,a,n) for(int i=a;i<n;i++) #define all(ds) ds.begin(), ds.end() #define ff first #define ss second #define pb push_back #define mp make_pair typedef vector< long long > vi; typedef pair<long long, long long> ii; typedef priority_queue <ll> pq; #define o_set tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update> const ll mod = 1000000007; const ll INF = (ll)1e18; const ll MAXN = 1000006; ll po(ll x, ll n){ ll ans=1; while(n>0){ if(n&1) ans=(ans*x)%mod; x=(x*x)%mod; n/=2;} return ans; } int main(){ ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); // #ifndef ONLINE_JUDGE // freopen("input.txt", "r" , stdin); // freopen("output.txt", "w" , stdout); // #endif int T=1; cin >> T; while(T--){ ll n,x; cin>>n>>x; ll a[n+1]; rep(i,n) cin>>a[i+1]; ll ans = 0; if(x==1){ int l = 0, r = 0; rep_a(i,1,n+1){ if(a[i]==1) r++; else{ ans += ((r-l)*(r-l+1))/2; l=r=i; } } ans += ((r-l)*(r-l+1))/2; cout<<ans<<el; continue; } vector<ii> pr; for(ll i=2; i*i<=x; i++){ if(x%i==0){ pr.pb(mp(i,0)); while(x%i==0){ x/=i; pr.back().ss++; } } } if(x>1) pr.pb(mp(x,1)); int k = pr.size(); map<vector<int>, int> m; vector<int> curr(k); rep(i,k) curr[i]=0; m[curr]=1; rep_a(i,1,n+1){ rep(j,k){ while(a[i]%pr[j].ff==0){ a[i]/=pr[j].ff; curr[j]++; } curr[j]-=pr[j].ss; } if(a[i]>1){ m.clear(); m[curr]=1; } else{ ans+=m[curr]; m[curr]++; } } cout<<ans<<el; } cerr << "Time : " << 1000 * ((double)clock()) / (double)CLOCKS_PER_SEC << "ms\n"; return 0; }