#include<iostream>
#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define IO ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
vector<int>v1[50][50], v2[50][50];
int x, y,m, k, t;
ll ans ;
void solve(int i, int cnt, int mx, int val, vector<int>v[][50])
{
if(i==mx)
{
v[cnt][mx-cnt].push_back(val);
return ;
}
solve(i+1,cnt+1,mx,(2*val+1)%m, v);
solve(i+1,cnt,mx,(2*val)%m, v);
}
int main()
{
IO
freopen("zeros.in", "r", stdin);
cin>>t;
while(t--)
{
ans=0;
for(int i=0; i<=45; i++)
for(int j=0; j<=45; j++)
v1[i][j].clear(), v2[i][j].clear();
cin>>x>>y>>m>>k;
int total=x+y;
int f=(total+1)/2;
solve(1,1,f,1,v1);
solve(0,0,total-f,0,v2);
ll lft=total-f;
for(int i=0; i<=x; i++)
for(int j=0; j<=y; j++)
sort(v2[i][j].begin(),v2[i][j].end());
for(int i=1; i<=x; i++)
for(int j=0; j<=y; j++)
for(auto cur : v1[i][j])
{
ll val=cur*(1LL<<lft);
val%=m;
ans+=
lower_bound(v2[x-i][y-j].begin(),v2[x-i][y-j].end(),m-val)-
lower_bound(v2[x-i][y-j].begin(),v2[x-i][y-j].end(),k-val);
ans+=v2[x-i][y-j].size()-
( lower_bound(v2[x-i][y-j].begin(),v2[x-i][y-j].end(),k+m-val)-v2[x-i][y-j].begin());
}
cout<<ans<<endl;
}
}
I2luY2x1ZGU8aW9zdHJlYW0+CiNpbmNsdWRlIDxiaXRzL3N0ZGMrKy5oPgojZGVmaW5lIGxsIGxvbmcgbG9uZwojZGVmaW5lIGxkIGxvbmcgZG91YmxlCiNkZWZpbmUgSU8gaW9zX2Jhc2U6OnN5bmNfd2l0aF9zdGRpbygwKTsgY2luLnRpZSgwKTsgY291dC50aWUoMCk7CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CnZlY3RvcjxpbnQ+djFbNTBdWzUwXSwgdjJbNTBdWzUwXTsKaW50IHgsIHksbSwgaywgdDsKbGwgYW5zIDsKdm9pZCBzb2x2ZShpbnQgaSwgaW50IGNudCwgaW50IG14LCBpbnQgdmFsLCB2ZWN0b3I8aW50PnZbXVs1MF0pCnsKICAgIGlmKGk9PW14KQogICAgewogICAgICAgIHZbY250XVtteC1jbnRdLnB1c2hfYmFjayh2YWwpOwogICAgICAgIHJldHVybiA7CiAgICB9CiAgICBzb2x2ZShpKzEsY250KzEsbXgsKDIqdmFsKzEpJW0sIHYpOwogICAgc29sdmUoaSsxLGNudCxteCwoMip2YWwpJW0sIHYpOwp9CmludCBtYWluKCkKewogICAgSU8KICAgICBmcmVvcGVuKCJ6ZXJvcy5pbiIsICJyIiwgc3RkaW4pOwogICAgY2luPj50OwogICAgd2hpbGUodC0tKQogICAgewogICAgICAgIGFucz0wOwogICAgICAgIGZvcihpbnQgaT0wOyBpPD00NTsgaSsrKQogICAgICAgICAgICBmb3IoaW50IGo9MDsgajw9NDU7IGorKykKICAgICAgICAgICAgICAgIHYxW2ldW2pdLmNsZWFyKCksIHYyW2ldW2pdLmNsZWFyKCk7CiAgICAgICAgY2luPj54Pj55Pj5tPj5rOwogICAgICAgIGludCB0b3RhbD14K3k7CiAgICAgICAgaW50IGY9KHRvdGFsKzEpLzI7CiAgICAgICAgc29sdmUoMSwxLGYsMSx2MSk7CiAgICAgICAgc29sdmUoMCwwLHRvdGFsLWYsMCx2Mik7CiAgICAgICAgbGwgbGZ0PXRvdGFsLWY7CiAgICAgICAgZm9yKGludCBpPTA7IGk8PXg7IGkrKykKICAgICAgICAgICAgZm9yKGludCBqPTA7IGo8PXk7IGorKykKICAgICAgICAgICAgICAgIHNvcnQodjJbaV1bal0uYmVnaW4oKSx2MltpXVtqXS5lbmQoKSk7CiAgICAgICAgZm9yKGludCBpPTE7IGk8PXg7IGkrKykKICAgICAgICAgICAgZm9yKGludCBqPTA7IGo8PXk7IGorKykKICAgICAgICAgICAgICAgIGZvcihhdXRvIGN1ciA6IHYxW2ldW2pdKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGxsIHZhbD1jdXIqKDFMTDw8bGZ0KTsKICAgICAgICAgICAgICAgICAgICB2YWwlPW07CgogICAgICAgICAgICAgICAgICAgIGFucys9CiAgICAgICAgICAgICAgICAgICAgICAgIGxvd2VyX2JvdW5kKHYyW3gtaV1beS1qXS5iZWdpbigpLHYyW3gtaV1beS1qXS5lbmQoKSxtLXZhbCktCiAgICAgICAgICAgICAgICAgICAgICAgIGxvd2VyX2JvdW5kKHYyW3gtaV1beS1qXS5iZWdpbigpLHYyW3gtaV1beS1qXS5lbmQoKSxrLXZhbCk7CgogICAgICAgICAgICAgICAgICAgIGFucys9djJbeC1pXVt5LWpdLnNpemUoKS0KICAgICAgICAgICAgICAgICAgICAgICAgICggbG93ZXJfYm91bmQodjJbeC1pXVt5LWpdLmJlZ2luKCksdjJbeC1pXVt5LWpdLmVuZCgpLGsrbS12YWwpLXYyW3gtaV1beS1qXS5iZWdpbigpKTsKCgogICAgICAgICAgICAgICAgfQogICAgICAgIGNvdXQ8PGFuczw8ZW5kbDsKICAgIH0KfQo=