#include using namespace std; struct Minmod{long long x,q,len;}; //[x,x+q,x+2*q,...,x+(len-1)*q] O(logm)の等差数列で済む. vector MinofModLinear(long long a,long long b,long long m){ //min(a*x+b modM)を更新するxを返す. assert(0 < m && m <= numeric_limits::max()); //mod*modの計算が必要. a %= m,b %= m,a += m,b += m; a = a>=m?a-m:a,b = b>=m?b-m:b; //a,bをmodMに. vector ret = {{0,1,1}}; //X=0だけ特別. if(a == 0 || b == 0) return {{0,1,1}}; //a=0orb=0は当然x=0が最善. if(a) a = m-a; // a<=-aとして考える -ax+bのminを求める. long long X = 0,Y = b; //現在のx,y; if(a <= Y){ //q=1を処理. long long len = Y/a; Y %= a; ret.at(0) = {X,1,len+1}; X += len; } long long p1 = 0,q1 = 1,p2 = 1,q2 = 0; //p1/q1<=a/m<=p2/q2. long long n = a,d = m; //n/dに近いp/qを探していく aq(modM)<=Yが欲しい. while(n){ //だいたいStern-Brocot木 aq-mp<=Yとして考える. long long move = d/n; d %= n; //p2/q2を更新. p2 += p1*move,q2 += q1*move; if(d == 0) break; move = n/d; n %= d; if(move > 0){ long long np = p1+p2*move,nq = q1+q2*move; //次のp1/q1. long long c1 = a*q1-m*p1,c2 = a*q2-m*p2,c3 = a*nq-m*np; //a/m>=p1/q1の変形 aq-mpになる. while(c3 <= Y){ //np/nqで更新の場合. long long t = max(0LL,(c1-Y+(-c2)-1)/(-c2)); //Yを超えないだけ進む. if(c1+c2*t == 0) break; //a/mと一致した場合. long long dx = q1+q2*t,dy = c1+c2*t; //dyの値が欲しいやつになる aq modm<=Y. long long len = Y/dy; Y %= dy; ret.push_back({X+dx,dx,len}); X += dx*len; } p1 = np,q1 = nq; //p1/q1を更新. } } return ret; } vector MinofModLinear(long long N,long long M,long long a,long long b){ //0<=x ret; for(auto [x,q,len] : MinofModLinear(a,b,M)){ if(N <= x) break; long long r = x+q*(len-1); ret.push_back(x); if(r < N){ret.push_back(r); continue;} long long add = (N-1-x)/q; ret.push_back(x+add*q); } return ret; } int main(){ ios_base::sync_with_stdio(false); cin.tie(nullptr); int T; cin >> T; while(T--){ long long N,M,A,B,C,D; cin >> N >> M >> A >> B >> C >> D; auto f = [&](long long x) -> long long { assert(0 <= x && x < N); return A*x+B*((C*x+D)/M); }; //long long g = gcd(M,C); //D = D/g*g; //D /= g,C /= g,M /= g; // long long best = -1; vector BestX; if(false){ for(int i=0; i best) BestX = {i},best = now; else if(now == best) BestX.push_back(i); } } if(A <= 0 && B <= 0) cout << f(0) << "\n"; else if(A >= 0 && B >= 0) cout << f(N-1) << "\n"; else if(A >= 0 && B <= 0){ if(A+B >= 0) cout << f(N-1) << "\n"; else{ long long answer = 0,type = A*M+B*C; D = M-1-D,C = (M-C)%M; if(type >= 0){ D = (C*(N-1)+D)%M,C = (M-C)%M; for(auto x : MinofModLinear(N,M,C,D)){ C = (M-C)%M,D = (D-C*(N-1)%M+M)%M; D = M-1-D,C = (M-C)%M; answer = max(answer,f(N-1-x)); D = M-1-D,C = (M-C)%M; D = (C*(N-1)+D)%M,C = (M-C)%M; } } else for(auto x : MinofModLinear(N,M,C,D)){ D = M-1-D,C = (M-C)%M; answer = max(answer,f(x)); D = M-1-D,C = (M-C)%M; } cout << answer << "\n"; } } else{ if(A+B <= 0) cout << f(0) << "\n"; else{ long long answer = 0; if(A*M+B*C >= 0){ D = (C*(N-1)+D)%M,C = (M-C)%M; for(auto x : MinofModLinear(N,M,C,D)){ C = (M-C)%M,D = (D-C*(N-1)%M+M)%M; answer = max(answer,f(N-1-x)); D = (C*(N-1)+D)%M,C = (M-C)%M; } } else for(auto x : MinofModLinear(N,M,C,D)) answer = max(answer,f(x)); cout << answer << "\n"; } } } }