Problem:
Problem C: Usagitobi
m
×
n
マスの盤がある.
i
行
j
列のマスを(
i
,
j
) (0 ≤
i
<
m
, 0 ≤
j
<
n
) で表す.
うさぎは(
x
,
y
) にいるとき, ((
x
+
a
) mod
m
, (
y
+
b
) mod
n
) または((
x
+
c
) mod
m
, (
y
+
d
) mod
n
) へ跳ぶことができる.
いま, うさぎが(0, 0) にいる. 一度跳び立ったマスへ再び行くことはできないとするとき, うさぎは最大何回跳ぶことができるか.
Input
入力は一行に
m
,
n
,
a
,
b
,
c
,
d
がスペース区切りで与えられる. 1 ≤
m
,
n
,
a
,
b
,
c
,
d
≤ 100 000
Output
うさぎが跳べる最大回数を一行に出力せよ.
Sample Input 1
6 6 2 2 2 4
Sample Output 1
8

Submitted solutions:

code_snippet: #include <iostream>
#include <map>
#include <vector>
using namespace std;

long long GCD(long long a, long long b) {
	if (b == 0) return a;
	return GCD(b, a % b);
}

long long GetAnswer(long long H, long long W, long long A, long long B, long long C, long long D) {
	map<pair<long long, long long>, int> Map;
	
	// Step 1
	vector<pair<long long, long long>> Trajectory;
	long long cx = 0, cy = 0, STEP1 = 0;
	while (true) {
		Trajectory.push_back(make_pair(cx, cy));
		cx = (cx + A) % H;
		cy = (cy + B) % W;
		STEP1 += 1;
		if (cx == 0) break;
	}
	long long BASE = GCD(cy, W);
	STEP1 *= (W / BASE);
	for (int i = 0; i < (int)Trajectory.size(); i++) {
		long long vx = Trajectory[i].first;
		long long vy = Trajectory[i].second;
		Map[make_pair(vx, vy % BASE)] = 1;
	}
	
	// Step 2
	long long dx = 0, dy = 0, STEP2 = 0;
	while (true) {
		dx = (dx + C) % H;
		dy = (dy + D) % W;
		STEP2 += 1;
		if (Map[make_pair(dx, dy % BASE)] == 1) {
			return STEP1 * STEP2;
		}
		if (STEP2 >= 250000LL) return (1LL << 60);
	}
}

int main() {
	// Input
	long long H, W, A, B, C, D;
	cin >> H >> W >> A >> B >> C >> D;
	
	// Get Answer
	long long Answer1 = GetAnswer(H, W, A, B, C, D);
	long long Answer2 = GetAnswer(H, W, C, D, A, B);
	cout << min(Answer1, Answer2) - 1LL << endl;
	return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 19060
final_rank: 9

code_snippet: #include<stdio.h>
#include<algorithm>
#include<set>
using namespace std;
int gcd(int a,int b){
	while(a){
		b%=a;
		int c=a;a=b;b=c;
	}
	return b;
}
set<pair<int,int> > S;
set<pair<int,int> > T;
int main(){
	int a,b,c,d,e,f;
	scanf("%d%d%d%d%d%d",&a,&b,&c,&d,&e,&f);
	int row=0;
	int col=0;
	long long cnt=1;
	S.insert(make_pair(row,col));
	while(1){
		row=(row+c)%a;
		col=(col+d)%b;
		if(col==0)break;
		cnt++;
		S.insert(make_pair(row,col));
	}
	int g=gcd(row,a);
	long long ret=a/g*cnt;
	if(ret<110000){
		S.clear();
		swap(c,e);
		swap(d,f);
		row=0;col=0;cnt=1;
		S.insert(make_pair(row,col));
		while(1){
			row=(row+c)%a;
			col=(col+d)%b;
			if(col==0)break;
			cnt++;
			S.insert(make_pair(row,col));
		}
		g=gcd(row,a);
		ret=a/g*cnt;
	}
	for(set<pair<int,int> > ::iterator it=S.begin();it!=S.end();it++){
		pair<int,int>tmp=(*it);
		T.insert(make_pair(tmp.first%g,tmp.second));
	}
	//printf("%lld\n",ret);
	row=0;col=0;cnt=1;
	  while(1){
        row=(row+e)%a;
        col=(col+f)%b;
        if(T.count(make_pair(row%g,col)))break;
        cnt++;
    }
	//printf("%lld %lld\n",ret,cnt);
	printf("%lld\n",ret*cnt-1);
}
accuracy: 1
time_ms: 20
memory_kb: 10400
final_rank: 7

code_snippet: #include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <assert.h>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <set>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

ll gcd(ll a, ll b) {
  if (b == 0) { return a; }
  return gcd(b, a % b);
}
ll lcm(ll a, ll b) {
  return a / gcd(a, b) * b;
}

//a x + b y = gcd(a, b)
long long extgcd(long long a, long long b, long long &x, long long &y) {
  long long g = a; x = 1; y = 0;
  if (b != 0) g = extgcd(b, a % b, y, x), y -= (a / b) * x;
  return g;
}


ll Mul(ll a, ll b, ll mod) {
  a %= mod;
  b %= mod;
  if (mod < 2e+9) { return a * b % mod; }
  ll ret = 0;
  while (b > 0) {
    if (b & 1) { ret = (ret + a) % mod; }
    a = (a + a) % mod;
    b >>= 1;
  }
  return ret;
}

// need extgcd
pair<ll, ll> PairChineseRemainderTherom(ll ans1, ll mod1, ll ans2, ll mod2) {
  ll g = gcd(mod1, mod2);
  ans1 %= mod1; ans1 = (ans1 + mod1) % mod1;
  ans2 %= mod2; ans2 = (ans2 + mod2) % mod2;
  if (ans1 % g != ans2 % g) { return make_pair(-1, -1); }
  const ll anss[2] = { ans1 / g, ans2 / g };
  const ll mods[2] = { mod1 / g, mod2 / g };
  ll all = mods[0] * mods[1];
  assert(all * g / g / mods[0] == mods[1]);
  ll ret = 0;
  for (int i = 0; i < 2; i++) {
    ll x, y;
    extgcd(mods[i], all / mods[i], x, y);
    y = (y + all) % all;
    ll v = Mul(y, anss[i], all);
    v = Mul(v, all / mods[i], all);
    ret = (ret + v) % all;
    assert(ret >= 0);
  }
  ret = ret * g + ans1 % g;
  return make_pair(ret, all * g);
}

// solve A x == B mod M
ll Divide(ll A, ll B, ll M) {
  A %= M; A = (A + M) % M;
  B %= M; B = (B + M) % M;
  ll g = gcd(A, M);
  if (B % g != 0) { return -1; }
  ll x, y;
  extgcd(A, M, x, y);
  ll n = x * B / g;
  ll dn = M / g;
  n -= n / dn * dn;
  if (n < 0) { n += dn; }
  return n;
}


pair<ll, ll> PairLinearCongruence(ll A1, ll B1, ll M1, ll A2, ll B2, ll M2) {
  A1 %= M1; A1 = (A1 + M1) % M1;
  B1 %= M1; B1 = (B1 + M1) % M1;
  A2 %= M2; A2 = (A2 + M2) % M2;
  B2 %= M2; B2 = (B2 + M2) % M2;
  if (A1 == 0 && B1 != 0) { return make_pair(-1, -1); }
  if (A2 == 0 && B2 != 0) { return make_pair(-1, -1); }
  if (A1 == 0 && A2 == 0) { return make_pair(0, 1); }
  if (A1 == 0) {
    swap(A1, A2);
    swap(B1, B2);
    swap(M1, M2);
  }
  ll g1 = gcd(A1, gcd(B1, M1));
  A1 /= g1; B1 /= g1; M1 /= g1;
  ll v1 = Divide(A1, B1, M1);
  if (v1 == -1) { return make_pair(-1, -1); }
  if (A2 == 0) {
    if (v1 == 0) { v1 = M1; }
    return make_pair(v1, M1);
  }
  ll g2 = gcd(A2, gcd(B2, M2));
  A2 /= g2; B2 /= g2; M2 /= g2;
  ll v2 = Divide(A2, B2, M2);
  if (v2 == -1) { return make_pair(-1, -1); }
  pair<ll, ll> ret = PairChineseRemainderTherom(v1, M1, v2, M2);
  if (ret.first == 0) { ret.first = ret.second; }
  return ret;
}


ll n, m, a, b, c, d;
int main() {
  while (scanf("%lld %lld %lld %lld %lld %lld", &m, &n, &a, &b, &c, &d) > 0) {
    a %= m; c %= m;
    b %= n; d %= n;
    ll e = 0;
    if (a == 0 && b == 0) {
      swap(a, c);
      swap(b, d);
    }
    if (a == 0 && b == 0) {
      puts("0");
      continue;
    } else if (a == 0) {
      e = n / gcd(b, n);
    } else if (b == 0) {
      e = m / gcd(a, m);
    } else {
      e = lcm(m / gcd(a, m), n / gcd(b, n));
    }
    if (c == 0 && d == 0) {
      printf("%lld\n", e - 1);
      continue;
    }

    ll sqnm = sqrt(n * m) + EPS;
    ll f = 1LL << 60;
    if (e <= sqrt(n * m)) {
      REP(g, e) {
        ll v = PairLinearCongruence(c, g * a % m, m, d, g * b % n, n).first;
        if (v == -1) { continue; }
        assert(v > 0);
        f = min(f, v);
      }
    } else {
      f = 1;
      FOREQ(i, 1, sqnm + 5) {
        ll v = PairLinearCongruence(a, i * c % m, m, b, i * d % n, n).first;
        if (v == -1) { continue; }
        f = i;
        break;
      }
    }
    printf("%lld\n", e * f - 1);
  }
}
accuracy: 1
time_ms: 20
memory_kb: 1196
final_rank: 3

code_snippet: #include <set>
#include <cstdio>
#include <numeric>
#include <algorithm>
#include <queue>

inline int getInt(){ int s; scanf("%d", &s); return s; }

typedef long long ll;

using namespace std;

int check(int a, int m){
  vector<int> visit(m);
  int now = 0;

  while(!visit[now]){
    visit[now] = 1;
    now = (now + a) % m;
  }

  return accumulate(visit.begin(), visit.end(), 0);
}

int main(){
  int m = getInt();
  int n = getInt();
  int a = getInt();
  int b = getInt();
  int c = getInt();
  int d = getInt();

  a %= m;
  b %= n;
  c %= m;
  d %= n;

  int acnt = check(a, m);
  int bcnt = check(b, n);

  ll ans1 = ((ll)acnt * bcnt) / __gcd(acnt, bcnt);
  ll ans2 = 0;

  vector<int> h(m, -1);
  int hh = 0;
  int xx = 0;
  int yy = 0;

  while(h[xx] == -1){
    h[xx] = yy;
    xx = (xx + a) % m;
    yy = (yy + b) % n;
    hh++;
  }

  int ym = ans1 / hh;
  int yd = n / ym;

  xx = c;
  yy = d;

  while(true){
    ans2++;

    if(ans2 == 30 * n){
      int ccnt = check(c, m);
      int dcnt = check(d, n);
      ans2 = ((ll)ccnt * dcnt) / __gcd(ccnt, dcnt);
      break;
    }

    if(h[xx] != -1){
      if((yy - h[xx] + n) % yd == 0)
        break;
    }

    xx = (xx + c) % m;
    yy = (yy + d) % n;
  }

  printf("%lld\n", ans1 * ans2 - 1);

  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 0
final_rank: 1

code_snippet: #include <set>
#include <cstdio>
#include <numeric>
#include <algorithm>
#include <queue>

inline int getInt(){ int s; scanf("%d", &s); return s; }

typedef long long ll;

using namespace std;

int check(int a, int m){
  vector<int> visit(m);
  int now = 0;

  while(!visit[now]){
    visit[now] = 1;
    now = (now + a) % m;
  }

  return accumulate(visit.begin(), visit.end(), 0);
}

int main(){
  int m = getInt();
  int n = getInt();
  int a = getInt();
  int b = getInt();
  int c = getInt();
  int d = getInt();

  a %= m;
  b %= n;
  c %= m;
  d %= n;

  int acnt = check(a, m);
  int bcnt = check(b, n);

  ll ans1 = ((ll)acnt * bcnt) / __gcd(acnt, bcnt);
  ll ans2 = 0;

  vector<int> h(m, -1);
  int hh = 0;
  int xx = 0;
  int yy = 0;

  while(h[xx] == -1){
    h[xx] = yy;
    xx = (xx + a) % m;
    yy = (yy + b) % n;
    hh++;
  }

  int ym = ans1 / hh;
  int yd = n / ym;

  xx = c;
  yy = d;

  while(true){
    ans2++;

    if(ans2 == 300 * n){
      int ccnt = check(c, m);
      int dcnt = check(d, n);
      ans2 = ((ll)ccnt * dcnt) / __gcd(ccnt, dcnt);
      break;
    }

    if(h[xx] != -1){
      if((yy - h[xx] + n) % yd == 0)
        break;
    }

    xx = (xx + c) % m;
    yy = (yy + d) % n;
  }

  printf("%lld\n", ans1 * ans2 - 1);

  return 0;
}
accuracy: 1
time_ms: 240
memory_kb: 1144
final_rank: 6

code_snippet: #include <set>
#include <cstdio>
#include <numeric>
#include <algorithm>
#include <queue>

inline int getInt(){ int s; scanf("%d", &s); return s; }

typedef long long ll;

using namespace std;

int check(int a, int m){
  vector<int> visit(m);
  int now = 0;

  while(!visit[now]){
    visit[now] = 1;
    now = (now + a) % m;
  }

  return accumulate(visit.begin(), visit.end(), 0);
}

int main(){
  int m = getInt();
  int n = getInt();
  int a = getInt();
  int b = getInt();
  int c = getInt();
  int d = getInt();

  a %= m;
  b %= n;
  c %= m;
  d %= n;

  int acnt = check(a, m);
  int bcnt = check(b, n);

  ll ans1 = ((ll)acnt * bcnt) / __gcd(acnt, bcnt);
  ll ans2 = 0;

  vector<int> h(m, -1);
  int hh = 0;
  int xx = 0;
  int yy = 0;

  while(h[xx] == -1){
    h[xx] = yy;
    xx = (xx + a) % m;
    yy = (yy + b) % n;
    hh++;
  }

  int ym = ans1 / hh;
  int yd = n / ym;

  xx = c;
  yy = d;

  while(true){
    ans2++;

    if(ans2 == 350 * n){
      int ccnt = check(c, m);
      int dcnt = check(d, n);
      ans2 = ((ll)ccnt * dcnt) / __gcd(ccnt, dcnt);
      break;
    }

    if(h[xx] != -1){
      if((yy - h[xx] + n) % yd == 0)
        break;
    }

    xx = (xx + c) % m;
    yy = (yy + d) % n;
  }

  printf("%lld\n", ans1 * ans2 - 1);

  return 0;
}
accuracy: 1
time_ms: 280
memory_kb: 0
final_rank: 5

code_snippet: #include <set>
#include <cstdio>
#include <numeric>
#include <algorithm>
#include <queue>

inline int getInt(){ int s; scanf("%d", &s); return s; }

typedef long long ll;

using namespace std;

int check(int a, int m){
  vector<int> visit(m);
  int now = 0;

  while(!visit[now]){
    visit[now] = 1;
    now = (now + a) % m;
  }

  return accumulate(visit.begin(), visit.end(), 0);
}

int main(){
  int m = getInt();
  int n = getInt();
  int a = getInt();
  int b = getInt();
  int c = getInt();
  int d = getInt();

  a %= m;
  b %= n;
  c %= m;
  d %= n;

  int acnt = check(a, m);
  int bcnt = check(b, n);

  ll ans1 = ((ll)acnt * bcnt) / __gcd(acnt, bcnt);
  ll ans2 = 0;

  vector<int> h(m, -1);
  int hh = 0;
  int xx = 0;
  int yy = 0;

  while(h[xx] == -1){
    h[xx] = yy;
    xx = (xx + a) % m;
    yy = (yy + b) % n;
    hh++;
  }

  int ym = ans1 / hh;
  int yd = n / ym;

  xx = c;
  yy = d;

  while(true){
    ans2++;

    if(ans2 == 1000 * n){
      int ccnt = check(c, m);
      int dcnt = check(d, n);
      ans2 = ((ll)ccnt * dcnt) / __gcd(ccnt, dcnt);
      break;
    }

    if(h[xx] != -1){
      if((yy - h[xx] + n) % yd == 0)
        break;
    }

    xx = (xx + c) % m;
    yy = (yy + d) % n;
  }

  printf("%lld\n", ans1 * ans2 - 1);

  return 0;
}
accuracy: 1
time_ms: 800
memory_kb: 0
final_rank: 8

code_snippet: #include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <assert.h>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <set>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

ll gcd(ll a, ll b) {
  if (b == 0) { return a; }
  return gcd(b, a % b);
}
ll lcm(ll a, ll b) {
  return a / gcd(a, b) * b;
}

//a x + b y = gcd(a, b)
long long extgcd(long long a, long long b, long long &x, long long &y) {
  long long g = a; x = 1; y = 0;
  if (b != 0) g = extgcd(b, a % b, y, x), y -= (a / b) * x;
  return g;
}

long long InvMod(long long a, long long mod) {
  long long x, y;
  if (extgcd(a, mod, x, y) == 1) { return (x + mod) % mod; }
  return 0;
}

pair<ll, ll> LinearCongruence(const vector<ll> &A, const vector<ll> &B, const vector<ll> &M) {
  ll x = 0;
  ll m = 1;
  for (ll i = 0; i < (ll)A.size(); i++) {
    ll a = A[i] * m;
    ll b = B[i] - A[i] * x;
    ll d = gcd(M[i], a);
    if (b % d != 0) { return make_pair(0, -1); }
    ll t = b / d * InvMod(a / d, M[i] / d) % (M[i] / d);
    x = x + m * t;
    m *= M[i] / d;
  }
  x %= m;
  if (x < 0) { x += m; }
  return make_pair(x % m, m);
}

ll solve(ll l1, ll l2, ll r1, ll r2, ll m1, ll m2) {
  vector<ll> a, b, m;
  if (l1 == 0 && r1 != 0) { return -1; }
  if (l2 == 0 && r2 != 0) { return -1; }

  if (l1 != 0) {
    a.push_back(l1);
    b.push_back(r1);
    m.push_back(m1);
  }
  if (l2 != 0) {
    a.push_back(l2);
    b.push_back(r2);
    m.push_back(m2);
  }
  if (a.size() == 0) { return 1; }
  pair<ll, ll> nret = LinearCongruence(a, b, m);
  if (nret.second > 0) {
    if (nret.first == 0) { nret.first += nret.second; }
    return nret.first;
  }
  return -1;
}

ll n, m, a, b, c, d;
int main() {
  while (scanf("%lld %lld %lld %lld %lld %lld", &m, &n, &a, &b, &c, &d) > 0) {
    a %= m; c %= m;
    b %= n; d %= n;
    ll e = 0;
    if (a == 0 && b == 0) {
      swap(a, c);
      swap(b, d);
    }
    if (a == 0 && b == 0) {
      puts("0");
      continue;
    } else if (a == 0) {
      e = n / gcd(b, n);
    } else if (b == 0) {
      e = m / gcd(a, m);
    } else {
      e = lcm(m / gcd(a, m), n / gcd(b, n));
    }
    if (c == 0 && d == 0) {
      printf("%lld\n", e - 1);
      continue;
    }
    
    ll sqnm = sqrt(n * m) + EPS;
    ll f = 1LL << 60;
    if (e <= sqrt(n * m)) {
      REP(g, e) {
        ll v = solve(c, d, g * a % m, g * b % n, m, n);
        if (v == -1) { continue; }
        assert(v > 0);
        f = min(f, v);
      }
    } else {
      f = 1;
      FOREQ(i, 1, sqnm + 5) {
        ll v = solve(a, b, i * c % m, i * d % n, m, n);
        if (v == -1) { continue; }
        f = i;
        break;
      }
    }
    printf("%lld\n", e * f - 1);
  }
}
accuracy: 1
time_ms: 70
memory_kb: 0
final_rank: 4

code_snippet: #include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <assert.h>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <set>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

ll gcd(ll a, ll b) {
  if (b == 0) { return a; }
  return gcd(b, a % b);
}
ll lcm(ll a, ll b) {
  return a / gcd(a, b) * b;
}

//a x + b y = gcd(a, b)
long long extgcd(long long a, long long b, long long &x, long long &y) {
  long long g = a; x = 1; y = 0;
  if (b != 0) g = extgcd(b, a % b, y, x), y -= (a / b) * x;
  return g;
}

ll divide(ll a, ll b, ll m) {
  ll g = gcd(a, m);
  if (b%g != 0) { return -1; }
  ll x, y;
  extgcd(a, m, x, y);
  assert(a*x+m*y == g);
  ll n = x*b/g;
  ll dn = m/g;
  n -= n/dn*dn;
  if (n < 0)
    n += dn;
  return n;
}

ll calc(const vector<ll> &anss, const vector<ll> &mods) {
  if (anss.size() == 1) { return anss[0]; }
  ll g = gcd(mods[0], mods[1]);
  if (anss[0] % g != anss[1] % g) { return -1; }
  ll t = divide(mods[0], (anss[1] - anss[0] + mods[0] * mods[1]) % mods[1], mods[1]);
  assert(t != -1);
  ll d = lcm(mods[0], mods[1]);
  ll x = (anss[0] + t * mods[0]) % d;
  assert(anss[0] == x % mods[0]);
  assert(anss[1] == x % mods[1]);
  if (x == 0) { x += d; }
  return x;
}

ll solve(ll l1, ll l2, ll r1, ll r2, ll m1, ll m2) {
  vector<ll> a, m;
  if (l1 == 0 && r1 != 0) { return -1; }
  if (l2 == 0 && r2 != 0) { return -1; }

  if (l1 != 0) {
    ll g = gcd(r1, gcd(l1, m1));
    l1 /= g; r1 /= g; m1 /= g;
    ll v = divide(l1, r1, m1);
    if (v == -1) { return -1; }
    a.push_back(v);
    m.push_back(m1);
  }
  if (l2 != 0) {
    ll g = gcd(r2, gcd(l2, m2));
    l2 /= g; r2 /= g; m2 /= g;
    ll v = divide(l2, r2, m2);
    if (v == -1) { return -1; }
    a.push_back(v);
    m.push_back(m2);
  }
  if (a.size() == 0) { return 1; }
  ll x = calc(a, m);
  if (x > 0) { return x; }
  return -1;
}

ll n, m, a, b, c, d;
int main() {
  while (scanf("%lld %lld %lld %lld %lld %lld", &m, &n, &a, &b, &c, &d) > 0) {
    a %= m; c %= m;
    b %= n; d %= n;
    ll e = 0;
    if (a == 0 && b == 0) {
      swap(a, c);
      swap(b, d);
    }
    if (a == 0 && b == 0) {
      puts("0");
      continue;
    } else if (a == 0) {
      e = n / gcd(b, n);
    } else if (b == 0) {
      e = m / gcd(a, m);
    } else {
      e = lcm(m / gcd(a, m), n / gcd(b, n));
    }
    if (c == 0 && d == 0) {
      printf("%lld\n", e - 1);
      continue;
    }

    ll sqnm = sqrt(n * m) + EPS;
    ll f = 1LL << 60;
    if (e <= sqrt(n * m)) {
      REP(g, e) {
        ll v = solve(c, d, g * a % m, g * b % n, m, n);
        if (v == -1) { continue; }
        assert(v > 0);
        f = min(f, v);
      }
    } else {
      f = 1;
      FOREQ(i, 1, sqnm + 5) {
        ll v = solve(a, b, i * c % m, i * d % n, m, n);
        if (v == -1) { continue; }
        f = i;
        break;
      }
    }
    printf("%lld\n", e * f - 1);
  }
}
accuracy: 1
time_ms: 30
memory_kb: 892
final_rank: 2