The Bouncing Flying Ball
Difficulty: Hard



Sergey and Chen are locked in a rectangular box of Dimension L\*W\*H. Evil Larry has put a machine which is located at a point inside the box (p,q,r) which starts shooting balls in every direction (dx,dy,dz) where 

-N &le; dx, dy, dz &le; N except (0, 0, 0) 

such that the ball goes through (p, q, r) -> (p + dx, q + dy, r + dz) -> (p + 2dx, q + 2dy, r + 2dz) and so on. 

so, a total of (2N + 1)<sup>3</sup> - 1 balls are fired. Sergey is standing at (a,b,c) and Chen is standing at (d,e,f). Provided all the balls follow reflection property and have constant velocity and gravity is not taken into account, can you tell how many balls are caught by Sergey and Chen? Sergey and Chen can catch the ball if it passes through the point at which they are standing. 

**Input Format**  
The first line contains the number of test cases, T lines follow, each containing a testcase.  
Each testcase contains 13 integers in the following order 

    L W H a b c d e f p q r N

**Output Format**  
For each test case please output two integers indicating the number of balls that are caught by Sergey and C, respectively.

**Constraints**  
T = 1  
1 &le; L, W, H, a, b, c, d, e, f, p, q, r, N &le; 50  

**Sample Input**

    1
    3 3 3 1 1 1 1 1 2 2 2 2 1

**Sample Output**

    8 4

**Explanation**

Here, L, W, H  = (3, 3, 3), Sergey is at (1, 1, 1) and Chen is at (1, 1, 2) and the machine Larry put is at (2, 2, 2).   
Balls are thrown at -1 &le; x, y, z &le; 1 from (2, 2, 2).  

+ (-1, -1, -1): (2, 2, 2)->(1, 1, 1) Sergey
+ (-1, -1, 0): (2, 2, 2)->(1, 1, 2) Chen
+ (-1, -1, 1): (2, 2, 2)->(1, 1, 3)->(0, 0, 2)->(1, 1, 1) Sergey
+ (-1, 0, -1): (2, 2, 2)->(1, 2, 1)->(0, 2, 0)->(1, 2, 1)->(2, 2, 2)->(3, 2, 3)->...
+ (-1, 0, 0): (2, 2, 2)->(1, 2, 2)->(0, 2, 2)->(1, 2, 2)->(2, 2, 2)->(3, 2, 2)->...
+ (-1, 0, 1): (2, 2, 2)->(1, 2, 3)->(0, 2, 2)->(1, 2, 1)->(2, 2, 0)->(3, 2, 1)->...
+ (-1, 1, -1): (2, 2, 2)->(1, 3, 1)->(0, 2, 0)->(1, 1, 1) Sergey
+ (-1, 1, 0): (2, 2, 2)->(1, 3, 2)->(0, 2, 2)->(1, 1, 2) Chen
+ (-1, 1, 1): (2, 2, 2)->(1, 3, 3)->(0, 2, 2)->(1, 1, 1) Sergey
+ (0, *, *): x-coordinate never changed
+ (1, -1, -1): (2, 2, 2)->(3, 1, 1)->(2, 0, 0)->(1, 1, 1) Sergey
+ (1, -1, 0): (2, 2, 2)->(3, 1, 2)->(2, 0, 2)->(1, 1, 2) Chen
+ (1, -1, 1): (2, 2, 2)->(3, 1, 3)->(2, 0, 2)->(1, 1, 1) Sergey
+ (1, 0, -1): (2, 2, 2)->(3, 2, 1)->(2, 2, 0)->(1, 2, 1)->(0, 2, 2)->...
+ (1, 0, 0): (2, 2, 2)->(3, 2, 2)->(2, 2, 2)->(1, 2, 2)->(0, 2, 2)->...
+ (1, 0, 1): (2, 2, 2)->(3, 2, 3)->(2, 2, 2)->(1, 2, 1)->(0, 2, 0)->...
+ (1, 1, -1): (2, 2, 2)->(3, 3, 1)->(2, 2, 0)->(1, 1, 1) Sergey
+ (1, 1, 0): (2, 2, 2)->(3, 3, 2)->(2, 2, 2)->(1, 1, 2) Chen
+ (1, 1, 1): (2, 2, 2)->(3, 3, 3)->(2, 2, 2)->(1, 1, 1) Sergey

Input Format:

Output Format:

Sample Input:

Sample Output:

Python 3 starter code:

Editorial: The bouncing flying ball - March'14 Editorial
<style id="MathJax_SVG_styles">.MathJax_SVG_Display {text-align: center; margin: 1em 0em; position: relative; display: block!important; text-indent: 0; max-width: none; max-height: none; min-width: 0; min-height: 0; width: 100%}
.MathJax_SVG .MJX-monospace {font-family: monospace}
.MathJax_SVG .MJX-sans-serif {font-family: sans-serif}
.MathJax_SVG {display: inline; font-style: normal; font-weight: normal; line-height: normal; font-size: 100%; font-size-adjust: none; text-indent: 0; text-align: left; text-transform: none; letter-spacing: normal; word-spacing: normal; word-wrap: normal; white-space: nowrap; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0; min-height: 0; border: 0; padding: 0; margin: 0}
.MathJax_SVG * {transition: none; -webkit-transition: none; -moz-transition: none; -ms-transition: none; -o-transition: none}
.mjx-svg-href {fill: blue; stroke: blue}
</style><svg style="display: none;"><defs id="MathJax_SVG_glyphs"></defs></svg><p><a href="https://www.hackerrank.com/contests/mar14/challenges/the-bouncing-flying-ball">The bouncing flying ball</a> <br>
<strong>Difficulty Level</strong> : Hard <br>
<strong>Required Knowledge</strong> : Chinese Remainder Theorem <br>
<strong>Problem Setter</strong> : <a href="https://www.hackerrank.com/tmt514">Shang-En Huang</a> <br>
<strong>Problem Tester</strong> : <a href="https://www.hackerrank.com/sdya">sdya</a>  </p>

<p><strong>Approach</strong>  </p>

<p>For each direction (dx, dy, dz), the ball is flying through (p, q, r) -&gt; (p+dx, p+dy, p+dz) -&gt; ... as a line segment.
We need to determine whether the ball touches (a, b, c) first or (d, e, f) first. This is equivalent to solve an integral equation using <a href="http://en.wikipedia.org/wiki/Chinese_remainder_theorem">Chinese Remainder Theorem</a>:</p>

<ul>
<li><strong>p</strong> + <strong>t</strong> * (dx / g) = <strong>a</strong>  or <strong>-a</strong> (mod <strong>2L</strong>)</li>
<li><strong>q</strong> + <strong>t</strong> * (dy / g) = <strong>b</strong>  or <strong>-b</strong> (mod <strong>2W</strong>)</li>
<li><strong>r</strong> + <strong>t</strong> * (dz / g) = <strong>c</strong>  or <strong>-c</strong> (mod <strong>2H</strong>)</li>
</ul>

<p>where <strong>g &gt; 0</strong> is the greatest common divisor of (dx, dy, dz). The minimum positive <strong>t &gt; 0</strong> is the variable that we want to know.</p>

<p>There are a few ways to calculate with more efficiency:</p>

<ol>
<li>Use less multiplicity &amp; division. (aka. use less "%" operations) <br>
For example, we can cache the inversion calculation (pre-caculate something like <strong>v<sup>-1</sup></strong> modulo <strong>M</strong>)</li>
<li>For same (dx/g, dy/g, dz/g) directions we can calculate the solution only once, and add the <strong>multiplicity</strong> that Sergey or Chen get.</li>
<li>Calculate the solution to (-dx, -dy, -dz) when calculating (dx, dy, dz)'s solution: when we handling (dx, dy, dz) we are finding minimum <strong>t &gt; 0</strong> that satisfying the equations; but when we handling (-dx, -dy, -dz) we are finding the maximum <strong>t &lt; LCM(2L, 2W, 2H)</strong> that satisfying the <strong>same</strong> equations.</li>
<li>To solve the system of equations above, there is no need to seperate the equation system into 8 system of equations.</li>
</ol>

<p><strong>Setter's Code</strong></p>

<pre><code>/ by tmt514
#include &lt;cstdio&gt;
#include &lt;cstdlib&gt;
#include &lt;cstring&gt;
#include &lt;cmath&gt;
#include &lt;algorithm&gt;
#include &lt;vector&gt;
using namespace std;

#define FOR(it,c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define SZ(x) ((int)(x).size())

int L, W, H, a, b, c, d, e, f, p, q, r, N;
int inv_tbl[105][105], u_inv_tbl[105][105];

int inv(int x, int y, int P, int Q, int R, int S) {
if(y==0) return P;
return inv(y, x%y, R, S, P-R*(x/y), Q-S*(x/y));
}

//cache the inversion results (note that 1 &lt;= M &lt;= 200)
int inv(int x, int M) {
if(!u_inv_tbl[x][M]) {
u_inv_tbl[x][M] = 1;
inv_tbl[x][M] = (inv(x, M, 1, 0, 0, 1)%M+M)%M;
}
return inv_tbl[x][M];
}

int sol[105], qb, qe;
void getsol(int ql, int qr, int &amp;modulo, int u, int x, int p, int M) {
// u + ?x = p or -p (mod) M
// ? = sol (mod) modulo

if (x &lt; 0) { u = -u; x = -x; }
int p1 = ((p-u)%M+M)%M;
int p2 = ((-p-u)%M+M)%M;

int G = __gcd(M, x);
M/=G; x/=G;
int g = __gcd(modulo, M), MM = M / g;
int ret_modulo = modulo * MM;
modulo /= g;
int MMInv = inv(modulo%MM, MM);

if (p1 % G == 0) {
p1 = p1/G * inv(x, M);
for(int it=ql;it&lt;qr;it++) {
int t = sol[it];
// ? = p1 (mod) MM
// ? = t (mod) modulo
if ((p1 - t) % g) continue;
int tmp = ((p1 - t) * MMInv * modulo + t) % ret_modulo;
tmp = (tmp+ret_modulo)%ret_modulo;
sol[qe++] = tmp;
}
}
if (p2 % G == 0) {
p2 = p2/G * inv(x, M);
for(int it=ql;it&lt;qr;it++) {
int t = sol[it];
// ? = p2 (mod) M
// ? = t (mod) modulo
if ((p2 - t) % g) continue;
int tmp = ((p2 - t) * MMInv * modulo + t) % ret_modulo;
tmp = (tmp+ret_modulo)%ret_modulo;
sol[qe++] = tmp;
}
}
qb = qr;
modulo = ret_modulo;
}

void ask(int &amp;min_pos, int &amp;min_neg, int u, int v, int w, int x, int y, int z) {
int modulo = 1;
// initialize the solution queue
sol[0] = 0;
qb = 0, qe = 1;

// p + ?x = u or -u (mod) 2L
// q + ?y = v or -v (mod) 2W
// r + ?z = w or -w (mod) 2H
getsol(qb, qe, modulo, p, x, u, 2*L);
getsol(qb, qe, modulo, q, y, v, 2*W);
getsol(qb, qe, modulo, r, z, w, 2*H);

if (qb == qe) { min_pos = min_neg = -1; return; }
min_pos = *min_element(sol + qb, sol + qe);
min_neg = modulo - *max_element(sol + qb, sol + qe);
}

int muls[105][105][105];
int main(void) {
int T;
scanf("%d", &amp;T);
while(T--) {
scanf("%d%d%d", &amp;L, &amp;W, &amp;H);
scanf("%d%d%d", &amp;a, &amp;b, &amp;c);
scanf("%d%d%d", &amp;d, &amp;e, &amp;f);
scanf("%d%d%d", &amp;p, &amp;q, &amp;r);
scanf("%d", &amp;N);
memset(muls, 0, sizeof(muls));

const int offset = 50;
int cSergey = 0, cChen = 0;
// caculate multiplicity
for(int x=-N;x&lt;=N;x++) for(int y=-N;y&lt;=N;y++) for(int z=-N;z&lt;=N;z++) {
int g = __gcd(abs(x), __gcd(abs(y), abs(z)));
if(g) muls[x/g+offset][y/g+offset][z/g+offset]++;
}
// caculate positive (x, y, z) and negative (-x, -y, -z) at same time
for(int x=0;x&lt;=N;x++) for(int y=-N;y&lt;=N;y++) for(int z=-N;z&lt;=N;z++) {
if((x==0&amp;&amp;y&lt;0) || (x==0 &amp;&amp; y==0 &amp;&amp; z&lt;0)) continue;
int g = __gcd(abs(x), __gcd(abs(y), abs(z)));
if(!g) continue;
if(g == 1) {
int S_pos, S_neg, C_pos, C_neg;
ask(S_pos, S_neg, a, b, c, x, y, z);
ask(C_pos, C_neg, d, e, f, x, y, z);

int m_pos = muls[x+offset][y+offset][z+offset];
int m_neg = muls[-x+offset][-y+offset][-z+offset];
if(S_pos != -1 &amp;&amp; C_pos != -1) (S_pos &lt; C_pos? cSergey+=m_pos: cChen+=m_pos);
else if(S_pos != -1) cSergey+=m_pos;
else if(C_pos != -1) cChen+=m_pos;

if(S_neg != -1 &amp;&amp; C_neg != -1) (S_neg &lt; C_neg? cSergey+=m_neg: cChen+=m_neg);
else if(S_neg != -1) cSergey+=m_neg;
else if(C_neg != -1) cChen+=m_neg;
}
}
printf("%d %d\n", cSergey, cChen);
}
return 0;
}
</code></pre>

<p><strong>Tester's Code</strong></p>

<pre><code>#include &lt;cstdio&gt;
#include &lt;cstring&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;
#include &lt;cmath&gt;
#include &lt;iostream&gt;
using namespace std;

#define FOR(it, c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define SZ(c) ((long long)(c).size())
typedef long long LL;

long long L, W, H, x, y, z, a, b, c, p, q, r, N;
const long long INF = 1000000000000000000LL;

long long gcdtbl[105][10005];
long long gcd3[105][105][105];
long long inv[105][10005];
long long cache[105][105][105];
long long fac[105][105][105][7];

long long gcd(long long a, long long b) {
    if (a == 0 || b == 0) {
        return a + b;
    }
    if (a &gt; b) {
        return gcd(a % b, b);
    } else {
        return gcd(b % a, a);
    }
}

long long pre() {
for(long long i=0;i&lt;=100;i++) for(long long j=0;j&lt;=10000;j++) gcdtbl[i][j] = gcd(i, j);
for(long long i=0;i&lt;=100;i++) for(long long j=0;j&lt;=100;j++) for(long long k=0;k&lt;=100;k++) gcd3[i][j][k] = gcd(gcd(i, j), k);
for(long long i=2;i&lt;=100;i++) for(long long j=0;j&lt;=10000;j++) if(gcd(i, j) &gt; 1) inv[i][j] = 0;
else for(long long k=0;k&lt;=100;k++) if(j*k%i==1) { inv[i][j] = k; break; }
for(long long i=1;i&lt;=100;i++) for(long long j=1;j&lt;=100;j++) for(long long k=1;k&lt;=100;k++) {
static long long p[15]={64,9,25,49,11,13,17,19,23,29,31,37,41,43,47};
static long long q[15]={2, 3, 5, 7,11,13,17,19,23,29,31,37,41,43,47};
long long t=0;
for(long long l=0;l&lt;15;l++) if(i%q[l]==0 || j%q[l]==0 || k%q[l]==0) fac[i][j][k][t++] = p[l];
}
return 0;
}

long long solve(long long gx, long long gy, long long gz, long long u, long long v, int w) {
//gx * t = u   2L
//gy * t = v   2W
//gz * t = w   2H

long long A = 2*L, B = 2*W, C = 2*H;
long long gA = gcdtbl[A][gx], gB = gcdtbl[B][gy], gC = gcdtbl[C][gz];
if (u % gA || v % gB || w % gC) return INF;
u /= gA; A /= gA; gx /= gA; u = u * inv[A][gx];
v /= gB; B /= gB; gy /= gB; v = v * inv[B][gy];
w /= gC; C /= gC; gz /= gC; w = w * inv[C][gz];

// t = u (mod A)
// t = v (mod B)
// t = w (mod C)

for(long long *it = &amp;fac[A][B][C][0]; *it; it++) {
long long p = *it;
long long pa = gcdtbl[A][p], pb = gcdtbl[B][p], pc = gcdtbl[C][p];
if(pa&gt;=pb&amp;&amp;pa&gt;=pc) { if((u-v)%pb||(u-w)%pc) return INF; else { B/=pb; C/=pc; }}
else if(pb&gt;=pa&amp;&amp;pb&gt;=pc) { if((v-u)%pa||(v-w)%pc) return INF; else { A/=pa; C/=pc; }}
else if(pc&gt;=pa&amp;&amp;pc&gt;=pb) { if((w-u)%pa||(w-v)%pb) return INF; else { A/=pa; B/=pb; }}
}

long long ABC = A*B*C, t = ((v-u)*inv[B][A]*A+u);
t = ((w-t)*inv[C][A*B]*A*B+t);
t = (t%ABC+ABC)%ABC;
return t;
}

long long hit(long long vx, long long vy, long long vz, long long u, long long v, long long w) {
long long tx = gcdtbl[2*L][abs(vx)], ty = gcdtbl[2*W][abs(vy)], tz = gcdtbl[2*H][abs(vz)];
if(((u-p)%tx &amp;&amp; (u+p)%tx) || ((v-q)%ty &amp;&amp; (v+q)%ty) || ((w-r)%tz &amp;&amp; (w+r)%tz)) return INF;
vx = (vx % (2*L) + 2*L) % (2*L);
vy = (vy % (2*W) + 2*W) % (2*W);
vz = (vz % (2*H) + 2*H) % (2*H);
long long t = INF;
for(long long i=0;i&lt;8;i++) t = min(t, solve(vx, vy, vz, (i&amp;1? 4*L-u-p: 2*L+u-p), (i&amp;2? 4*W-v-q: 2*W+v-q), (i&amp;4? 4*H-w-r: 2*H+w-r)));
return t;
}

void solve() {
    cin &gt;&gt; L &gt;&gt; W &gt;&gt; H &gt;&gt; x &gt;&gt; y &gt;&gt; z &gt;&gt; a &gt;&gt; b &gt;&gt; c &gt;&gt; p &gt;&gt; q &gt;&gt; r &gt;&gt; N;
//scanf("%d%d%d%d%d%d%d%d%d%d%d%d%d", &amp;L, &amp;W, &amp;H, &amp;x, &amp;y, &amp;z, &amp;a, &amp;b, &amp;c, &amp;p, &amp;q, &amp;r, &amp;N);
long long pi = 0, kel = 0;
memset(cache, 0, sizeof(cache));
for (long long vx = -N; vx &lt;= N; vx++)
for(long long vy = -N; vy &lt;= N; vy++)
for(long long vz = -N; vz &lt;= N; vz++) {
if(vx==0 &amp;&amp; vy==0 &amp;&amp; vz==0) continue;

long long cx = vx, cy = vy, cz = vz;
long long g = gcd3[abs(cx)][abs(cy)][abs(cz)];
cx /= g; cy /= g; cz /= g;
long long &amp;tmp = cache[cx+50][cy+50][cz+50];
if (tmp) {
if (tmp == 1) ++pi;
if (tmp == 2) ++kel;
continue;
}

long long tp = hit(cx, cy, cz, x, y, z);
long long th = hit(cx, cy, cz, a, b, c);

if (tp &lt; th) ++pi, tmp = 1;
if (tp &gt; th) ++kel, tmp = 2;
if (tp == th) tmp = 3;
}
cout &lt;&lt; pi &lt;&lt; " " &lt;&lt; kel &lt;&lt; endl;
//printf("%d %d\n", pi, kel);
static long long cs=0;
//cerr &lt;&lt; ++cs &lt;&lt; endl;
//fprintf(stderr, "Case #%d: %d %d\n", ++cs, pi, kel);
}

int main(void) {
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
long long T;
pre();
cin &gt;&gt; T;
while(T--) solve();
return 0;
}
</code></pre>

Reference solution (C++):
###C++  
```cpp  

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iostream>
using namespace std;
    
#define FOR(it, c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define SZ(c) ((long long)(c).size())
typedef long long LL;
    
long long L, W, H, x, y, z, a, b, c, p, q, r, N;
const long long INF = 1000000000000000000LL;
    
long long gcdtbl[105][10005];
long long gcd3[105][105][105];
long long inv[105][10005];
long long cache[105][105][105];
long long fac[105][105][105][7];
    
long long gcd(long long a, long long b) {
    if (a == 0 || b == 0) {
        return a + b;
    }
    if (a > b) {
        return gcd(a % b, b);
    } else {
        return gcd(b % a, a);
    }
}
    
long long pre() {
for(long long i=0;i<=100;i++) for(long long j=0;j<=10000;j++) gcdtbl[i][j] = gcd(i, j);
for(long long i=0;i<=100;i++) for(long long j=0;j<=100;j++) for(long long k=0;k<=100;k++) gcd3[i][j][k] = gcd(gcd(i, j), k);
for(long long i=2;i<=100;i++) for(long long j=0;j<=10000;j++) if(gcd(i, j) > 1) inv[i][j] = 0;
else for(long long k=0;k<=100;k++) if(j*k%i==1) { inv[i][j] = k; break; }
for(long long i=1;i<=100;i++) for(long long j=1;j<=100;j++) for(long long k=1;k<=100;k++) {
static long long p[15]={64,9,25,49,11,13,17,19,23,29,31,37,41,43,47};
static long long q[15]={2, 3, 5, 7,11,13,17,19,23,29,31,37,41,43,47};
long long t=0;
for(long long l=0;l<15;l++) if(i%q[l]==0 || j%q[l]==0 || k%q[l]==0) fac[i][j][k][t++] = p[l];
}
return 0;
}
    
long long solve(long long gx, long long gy, long long gz, long long u, long long v, int w) {
//gx * t = u   2L
//gy * t = v   2W
//gz * t = w   2H
    
long long A = 2*L, B = 2*W, C = 2*H;
long long gA = gcdtbl[A][gx], gB = gcdtbl[B][gy], gC = gcdtbl[C][gz];
if (u % gA || v % gB || w % gC) return INF;
u /= gA; A /= gA; gx /= gA; u = u * inv[A][gx];
v /= gB; B /= gB; gy /= gB; v = v * inv[B][gy];
w /= gC; C /= gC; gz /= gC; w = w * inv[C][gz];
    
// t = u (mod A)
// t = v (mod B)
// t = w (mod C)
    
for(long long *it = &fac[A][B][C][0]; *it; it++) {
long long p = *it;
long long pa = gcdtbl[A][p], pb = gcdtbl[B][p], pc = gcdtbl[C][p];
if(pa>=pb&&pa>=pc) { if((u-v)%pb||(u-w)%pc) return INF; else { B/=pb; C/=pc; }}
else if(pb>=pa&&pb>=pc) { if((v-u)%pa||(v-w)%pc) return INF; else { A/=pa; C/=pc; }}
else if(pc>=pa&&pc>=pb) { if((w-u)%pa||(w-v)%pb) return INF; else { A/=pa; B/=pb; }}
}
    
long long ABC = A*B*C, t = ((v-u)*inv[B][A]*A+u);
t = ((w-t)*inv[C][A*B]*A*B+t);
t = (t%ABC+ABC)%ABC;
return t;
}
    
long long hit(long long vx, long long vy, long long vz, long long u, long long v, long long w) {
long long tx = gcdtbl[2*L][abs(vx)], ty = gcdtbl[2*W][abs(vy)], tz = gcdtbl[2*H][abs(vz)];
if(((u-p)%tx && (u+p)%tx) || ((v-q)%ty && (v+q)%ty) || ((w-r)%tz && (w+r)%tz)) return INF;
vx = (vx % (2*L) + 2*L) % (2*L);
vy = (vy % (2*W) + 2*W) % (2*W);
vz = (vz % (2*H) + 2*H) % (2*H);
long long t = INF;
for(long long i=0;i<8;i++) t = min(t, solve(vx, vy, vz, (i&1? 4*L-u-p: 2*L+u-p), (i&2? 4*W-v-q: 2*W+v-q), (i&4? 4*H-w-r: 2*H+w-r)));
return t;
}
    
void solve() {
    cin >> L >> W >> H >> x >> y >> z >> a >> b >> c >> p >> q >> r >> N;
//scanf("%d%d%d%d%d%d%d%d%d%d%d%d%d", &L, &W, &H, &x, &y, &z, &a, &b, &c, &p, &q, &r, &N);
long long pi = 0, kel = 0;
memset(cache, 0, sizeof(cache));
for (long long vx = -N; vx <= N; vx++)
for(long long vy = -N; vy <= N; vy++)
for(long long vz = -N; vz <= N; vz++) {
if(vx==0 && vy==0 && vz==0) continue;
    
long long cx = vx, cy = vy, cz = vz;
long long g = gcd3[abs(cx)][abs(cy)][abs(cz)];
cx /= g; cy /= g; cz /= g;
long long &tmp = cache[cx+50][cy+50][cz+50];
if (tmp) {
if (tmp == 1) ++pi;
if (tmp == 2) ++kel;
continue;
}
    
long long tp = hit(cx, cy, cz, x, y, z);
long long th = hit(cx, cy, cz, a, b, c);
    
if (tp < th) ++pi, tmp = 1;
if (tp > th) ++kel, tmp = 2;
if (tp == th) tmp = 3;
}
cout << pi << " " << kel << endl;
//printf("%d %d\n", pi, kel);
static long long cs=0;
//cerr << ++cs << endl;
//fprintf(stderr, "Case #%d: %d %d\n", ++cs, pi, kel);
}
    
int main(void) {
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
long long T;
pre();
cin >> T;
while(T--) solve();
return 0;
}
    
```