#include "stdbool.h"
#include "stdio.h"
#include "stdint.h"
#include "string.h"
#include "ctype.h"
#include "stdlib.h"
#include "math.h"

#define PI 3.14159265358979323846264338327950288
#define ll long long
#define MOD 1000000007
#define N 1000010
#define MAX1 1000001
#define rep(i,n) for (int i=0; i<n; i++)
#define mul(a,b) ((a*b) % MOD)

int max(int a,int b) {return a>b?a:b;}
int min(int a,int b) {return a<b?a:b;}
ll minl(ll a,ll b) {return a<b?a:b;}
ll maxl(ll a,ll b) {return a>b?a:b;}

ll n, k, prime[N], v[N], m;

// euler function
ll f(ll n) {
    if (n == 1) return 1;
    ll s = n;
    for (int i=0; i<m && prime[i]*prime[i]<=n; i++) {
        if (n % prime[i]) continue;
        s = s/prime[i]*(prime[i]-1);
        while (!(n % prime[i])) n /= prime[i];
    }
    if (n > 1) s = s/n*(n-1);
    return s;
}

ll F(ll k, ll n) {
    if (!(k & 1)) k--;
    if (k == 1) return f(n);
    return f(F(k-1, n));
}

void primes(int n) {
    for (int i = 2; i <= n; i++) {
        if (!v[i]) {
            v[i] = i;
            prime[m++] = i;
        }
        for (int j = 0; j < m; j++) {
            if (prime[j] > v[i] || prime[j]*i > n) break;
            v[i * prime[j]] = prime[j];
        }
    }
}

int main() {
    scanf("%lld %lld", &n, &k);
    primes((int) sqrtl(n)+1);
    printf("%lld\n", F(k, n) % MOD);
}


#include "stdbool.h"
#include "stdio.h"
#include "stdint.h"
#include "string.h"
#include "ctype.h"
#include "stdlib.h"
#include "math.h"

#define PI 3.14159265358979323846264338327950288
#define ll long long
#define MOD 1000000007
#define N 1000010
#define MAX1 1000001
#define rep(i,n) for (int i=0; i<n; i++)
#define mul(a,b) ((a*b) % MOD)

int max(int a,int b) {return a>b?a:b;}
int min(int a,int b) {return a<b?a:b;}
ll minl(ll a,ll b) {return a<b?a:b;}
ll maxl(ll a,ll b) {return a>b?a:b;}

ll n, k, prime[N], v[N], m;

// euler function
ll f(ll n) {
    if (n == 1) return 1;
    ll s = n;
    for (int i=0; i<m && prime[i]*prime[i]<=n; i++) {
        if (n % prime[i]) continue;
        s = s/prime[i]*(prime[i]-1);
        while (n % prime[i]) n /= prime[i];
    }
    if (n > 1) s--;
    return s;
}

ll F(ll k, ll n) {
    if (!(k & 1)) k--;
    if (k == 1) return f(n);
    return f(F(k-1, n));
}

void primes(int n) {
    for (int i = 2; i <= n; i++) {
        if (!v[i]) {
            v[i] = i;
            prime[m++] = i;
        }
        for (int j = 0; j < m; j++) {
            if (prime[j] > v[i] || prime[j]*i > n) break;
            v[i * prime[j]] = prime[j];
        }
    }
}

int main() {
    scanf("%lld %lld", &n, &k);
    primes((int) sqrtl(n)+1);
    printf("%lld\n", F(k, n) % MOD);
}


#include "stdbool.h"
#include "stdio.h"
#include "stdint.h"
#include "string.h"
#include "ctype.h"
#include "stdlib.h"
#include "math.h"

#define PI 3.14159265358979323846264338327950288
#define ll long long
#define MOD 1000000007
#define N 1000010
#define MAX1 1000001
#define rep(i,n) for (int i=0; i<n; i++)
#define mul(a,b) ((a*b) % MOD)

int max(int a,int b) {return a>b?a:b;}
int min(int a,int b) {return a<b?a:b;}
ll minl(ll a,ll b) {return a<b?a:b;}
ll maxl(ll a,ll b) {return a>b?a:b;}

ll n, k, prime[N], v[N], m;

// euler function
ll f(ll n) {
    if (n == 1) return 1;
    ll s = n;
    for (int i=0; i<m && prime[i]*prime[i]<=n; i++) {
        if (n % prime[i]) continue;
        s = s/prime[i]*(prime[i]-1);
        while (!(n % prime[i])) n /= prime[i];
    }
    if (n > 1) s = s/n*(n-1);
    return s;
}

ll F(ll k, ll n) {
    ll s = n;
    while ((k-=2)>0) s = f(s);
    return s;
}

void primes(int n) {
    for (int i = 2; i <= n; i++) {
        if (!v[i]) {
            v[i] = i;
            prime[m++] = i;
        }
        for (int j = 0; j < m; j++) {
            if (prime[j] > v[i] || prime[j]*i > n) break;
            v[i * prime[j]] = prime[j];
        }
    }
}

int main() {
    scanf("%lld %lld", &n, &k);
    primes((int) sqrtl(n)+1);
    printf("%lld\n", F(k, n) % MOD);
}


#include <stdio.h>

#define MOD	((long long) 1e9 + 7)

long long totient(long long n) {
	long long p, x;

	x = n;
	for (p = 2; p * p <= n; p++)
		if (n % p == 0) {
			x = x / p * (p - 1);
			while (n % p == 0)
				n /= p;
		}
	if (n > 1)
		x = x / n * (n - 1);
	return x;
}

int main() {
	long long n, k;

	scanf("%lld%lld", &n, &k);
	k = (k + 1) / 2;
	while (n > 1 && k > 0) {
		n = totient(n);
		k--;
	}
	printf("%lld\n", n % MOD);
	return 0;
}


#include "stdbool.h"
#include "stdio.h"
#include "stdint.h"
#include "string.h"
#include "ctype.h"
#include "stdlib.h"
#include "math.h"

#define PI 3.14159265358979323846264338327950288
#define ll long long
#define MOD 1000000007
#define N 1000010
#define MAX1 1000001
#define rep(i,n) for (int i=0; i<n; i++)
#define mul(a,b) ((a*b) % MOD)

int max(int a,int b) {return a>b?a:b;}
int min(int a,int b) {return a<b?a:b;}
ll minl(ll a,ll b) {return a<b?a:b;}
ll maxl(ll a,ll b) {return a>b?a:b;}

ll n, k, prime[N], v[N], m;

// euler function
ll f(ll n) {
    if (n == 1) return 1;
    ll s = n;
    for (int i=0; i<m && prime[i]*prime[i]<=n; i++) {
        if (n % prime[i]) continue;
        s = s/prime[i]*(prime[i]-1);
        while (!(n % prime[i])) n /= prime[i];
    }
    if (n > 1) s = s/n*(n-1);
    return s;
}

ll F(ll k, ll n) {
    ll s = n;
    while (k>0 && s>1) s = f(s), k-=2;
    return s;
}

void primes(int n) {
    for (int i = 2; i <= n; i++) {
        if (!v[i]) {
            v[i] = i;
            prime[m++] = i;
        }
        for (int j = 0; j < m; j++) {
            if (prime[j] > v[i] || prime[j]*i > n) break;
            v[i * prime[j]] = prime[j];
        }
    }
}

int main() {
    scanf("%lld %lld", &n, &k);
    primes((int) sqrtl(n)+1);
    printf("%lld\n", F(k, n) % MOD);
}


#include <stdio.h>
#include <string.h>
#include <sys/time.h>

#define N	35
#define N_	((N + 1) / 2)

unsigned int X;

void srand_() {
	struct timeval tv;

	gettimeofday(&tv, NULL);
	X = tv.tv_sec ^ tv.tv_usec | 1;
}

int rand_() {
	return (X *= 3) >> 1;
}

void multiply(char *aa, char *bb, char *md, int n) {
	static char cc[N * 2];
	int i, j;

	memset(cc, 0, n * 2 * sizeof *cc);
	for (i = 0; i < n; i++)
		for (j = 0; j < n; j++)
			if (aa[i] && bb[j])
				cc[i + j] ^= 1;
	for (i = n * 2 - 1; i >= n - 1; i--)
		if (cc[i])
			for (j = 0; j < n; j++)
				if (md[j])
					cc[i - (n - 1 - j)] ^= 1;
	memcpy(aa, cc, n * sizeof *cc);
}

char ppp[1 << N_][N]; int n;

int compare(int i, int j) {
	int c = memcmp(ppp[i], ppp[j], n * sizeof *ppp[j]);

	return c ? c : i - j;
}

void sort(int *ii, int l, int r) {
	while (l < r) {
		int i = l, j = l, k = r, i_ = ii[l + rand_() % (r - l)], tmp;

		while (j < k) {
			int c = compare(ii[j], i_);

			if (c == 0)
				j++;
			else if (c < 0) {
				tmp = ii[i], ii[i] = ii[j], ii[j] = tmp;
				i++, j++;
			} else {
				k--;
				tmp = ii[j], ii[j] = ii[k], ii[k] = tmp;
			}
		}
		sort(ii, l, i);
		l = k;
	}
}

int search(int *ii, int m, char *pp) {
	int lower = -1, upper = m;

	while (upper - lower > 1) {
		int i = (lower + upper) / 2;

		if (memcmp(ppp[ii[i]], pp, n * sizeof *ppp[ii[i]]) >= 0)
			upper = i;
		else
			lower = i;
	}
	return upper < m && memcmp(pp, ppp[ii[upper]], n * sizeof *ppp[ii[upper]]) == 0 ? ii[upper] : -1;
}

int main() {
	static char cc_[N + 1], *cc, md[N], xx[N], vv[N], pp[N], pp_[N];
	static int rr[1 << N_];
	int n_, p, q, r, i, j, one;
	char tmp;

	srand_();
	scanf("%s", cc_), n = strlen(cc_);
	p = 0;
	while (p < n && cc_[p] == '0')
		p++;
	if (p == n) {
		printf("-1\n");
		return 0;
	}
	cc = cc_ + p, n -= p;
	while (cc[n - 1] == '0')
		n--;
	if (n == 1) {
		printf("%d %d\n", p + 1, p + 2);
		return 0;
	}
	n_ = (n + 1) / 2;
	cc[n] = 0;
	for (i = 0, j = n - 1; i < j; i++, j--)
		tmp = cc[i], cc[i] = cc[j], cc[j] = tmp;
	for (i = 0; i < n; i++)
		md[i] = cc[i] - '0';
	for (j = 0; j < n - 1; j++)
		vv[j] = md[j + 1];
	memset(pp, 0, n * sizeof *pp), pp[0] = 1;
	for (r = 0; r < 1 << n_; r++) {
		memcpy(ppp[r], pp, n * sizeof *pp);
		one = 1;
		for (i = 0; i < n; i++)
			if ((pp[i] == 1) != (i == 0)) {
				one = 0;
				break;
			}
		if (one && r != 0) {
			printf("%d %d\n", p + 1, p + 1 + r);
			return 0;
		}
		multiply(pp, vv, md, n);
	}
	for (r = 0; r < 1 << n_; r++)
		rr[r] = r;
	sort(rr, 0, 1 << n_);
	memset(pp_, 0, n * sizeof *pp_), pp_[0] = 1;
	xx[1] = 1, multiply(xx, pp_, md, n);
	for (r = 0; r < 1 << n_; r++)
		multiply(pp_, xx, md, n);
	memset(pp, 0, n * sizeof *pp), pp[0] = 1;
	for (q = 1; q <= 1 << n_; q++) {
		multiply(pp, pp_, md, n);
		if ((r = search(rr, 1 << n_, pp)) != -1) {
			printf("%d %lld\n", p + 1, p + 1 + ((long long) q << n_) + r);
			return 0;
		}
	}
	printf("-1\n");
	return 0;
}


#include <stdio.h>

enum {
    M = 4,
    D = 13,
    MAX = M * D + 2
};

typedef struct Card {
    int d, m;
} Card;

Card a[MAX][MAX];
char n2m[M] = {'C', 'D', 'H', 'S'};
char n2d[D] = {'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};

int
m2n(char m)
{
    switch (m) {
    case 'C':
        return 0;
    case 'D':
        return 1;
    case 'H':
        return 2;
    case 'S':
        return 3;
    default:
        return -1;
    }
}

int
d2n(char d)
{
    switch (d) {
    case 'T':
        return 8;
    case 'J':
        return 9;
    case 'Q':
        return 10;
    case 'K':
        return 11;
    case 'A':
        return 12;
    default:
        return d - '2';
    }
}

int
good(int r, int c)
{
    int m = a[r][c].m;
    int goodm = 1;
    int ud[D] = {};
    int goodd = 1;
    int i, j;
    for (i = r; i < r + 3; ++i) {
        for (j = c; j < c + 3; ++j) {
            goodm &= (a[i][j].m == m);
            goodd &= (ud[a[i][j].d] == 0);
            ud[a[i][j].d] = 1;
        }
    }
    return goodm || goodd;
}

int
main(void)
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    int n, m, i, j;
    char s[MAX];
    int j1r, j1c, j2r, j2c;
    j1r = j1c = j2r = j2c = -1;
    int used[M][D] = {};
    scanf("%d %d", &n, &m);
    for (i = 0; i < n; ++i) {
        for (j = 0; j < m; ++j) {
            scanf("%s", s);
            a[i][j].d = d2n(s[0]);
            a[i][j].m = m2n(s[1]);
            if (s[1] == '1') {
                j1r = i;
                j1c = j;
            } else if (s[1] == '2') {
                j2r = i;
                j2c = j;
            } else {
                used[a[i][j].m][a[i][j].d] = 1;
            }
        }
    }

    int m1, d1, m2, d2, r1, c1, r2, c2;
    for (m1 = 0; m1 < M; ++m1) {
        for (d1 = 0; d1 < D; ++d1) {
            if (used[m1][d1]) continue;
            used[m1][d1] = 1;
            if (j1r > -1) {
                a[j1r][j1c].d = d1;
                a[j1r][j1c].m = m1;
            }
            for (m2 = 0; m2 < M; ++m2) {
                for (d2 = 0; d2 < D; ++d2) {
                    if (used[m2][d2]) continue;
                    used[m2][d2] = 1;
                    if (j2r > -1) {
                        a[j2r][j2c].d = d2;
                        a[j2r][j2c].m = m2;
                    }

                    for (r1 = 0; r1 < n - 2; ++r1) {
                        for (c1 = 0; c1 < m - 2; ++c1) {
                            for (r2 = r1; r2 < n - 2; ++r2) {
                                for (c2 = 0; c2 < m - 2; ++c2) {
                                    if ((r2 < r1 + 3) && ((c2 >= c1 && c2 < c1 + 3) || (c2 + 2 >= c1 && c2 + 2 < c1 + 3))) continue;
                                    if (good(r1, c1) && good(r2, c2)) {
                                        printf("Solution exists.\n");
                                        if (j1r == -1 && j2r == -1) {
                                            printf("There are no jokers.\n");
                                        } else if (j1r == -1) {
                                            printf("Replace J2 with %c%c.\n", n2d[d2], n2m[m2]);
                                        } else if (j2r == -1) {
                                            printf("Replace J1 with %c%c.\n", n2d[d1], n2m[m1]);
                                        } else {
                                            printf("Replace J1 with %c%C and J2 with %c%c.\n", n2d[d1], n2m[m1], n2d[d2], n2m[m2]);
                                        }
                                        printf("Put the first square to (%d, %d).\n", r1 + 1, c1 + 1);
                                        printf("Put the second square to (%d, %d).\n", r2 + 1, c2 + 1);
                                        return 0;
                                    }
                                }
                            }
                        }
                    }
                    used[m2][d2] = 0;
                }
            }
            used[m1][d1] = 0;
        }
    }
    printf("No solution.\n");

    return 0;
}


#include <stdio.h>
#include <stdlib.h>

#define N	1000000

int tt[N + 1];

int compare(const void *a, const void *b) {
	int a_ = *(int *) a;
	int b_ = *(int *) b;

	return tt[a_] != tt[b_] ? tt[a_] - tt[b_] : a_ - b_;
}

int main() {
	static int aa[N - 4];
	int n, k, a, b, i;
	long long ans;

	scanf("%d%d", &n, &k);
	if (k == 1) {
		printf("3\n");
		return 0;
	}
	for (a = 2; a <= n; a++)
		tt[a] = a;
	for (a = 2; a <= n; a++) {
		if (tt[a] != a)
			continue;
		for (b = a; b <= n; b += a)
			tt[b] = tt[b] / a * (a - 1);
	}
	for (a = 5; a <= n; a++)
		aa[a - 5] = a;
	qsort(aa, n - 4, sizeof *aa, compare);
	ans = 6;
	for (i = 0; i < k - 2; i++)
		ans += tt[aa[i]];
	printf("%lld\n", ans);
	return 0;
}


#include <stdio.h>
#include <string.h>

int main(){
    int i, num, flag=0;
    char str[11];
    scanf("%s", str);
    num = strlen(str);
    if(num == 1){
        if(str[0] == '3' || str[0] == '7'){
            printf("Yes\n");
        }
        else
            printf("No\n");
    }
    else{
        for(i=0; i<num/2; i++){
            if(str[i] == '1' || str[i] == '2'){
                printf("No\n");
                flag = 1;
                break;
            }
            if(str[i] == '0'){
                if(str[num-i-1] != '8'){
                    printf("No\n");
                    flag = 1;
                    break;
                }
            }
            if(str[i] == '3'){
                if(str[num-i-1] != '3'){
                    printf("No\n");
                    flag = 1;
                    break;
                }
            }
            if(str[i] == '4'){
                if(str[num-i-1] != '6'){
                    printf("No\n");
                    flag = 1;
                    break;
                }
            }
            if(str[i] == '5'){
                if(str[num-i-1] != '9'){
                    printf("No\n");
                    flag = 1;
                    break;
                }
            }
            if(str[i] == '6'){
                if(str[num-i-1] != '4'){
                    printf("No\n");
                    flag = 1;
                    break;
                }
            }
            if(str[i] == '7'){
                if(str[num-i-1] != '7'){
                    printf("No\n");
                    flag = 1;
                    break;
                }
            }
            if(str[i] == '8'){
                if(str[num-i-1] != '0'){
                    printf("No\n");
                    flag = 1;
                    break;
                }
            }
            if(str[i] == '9'){
                if(str[num-i-1] != '5'){
                    printf("No\n");
                    flag = 1;
                    break;
                }
            }
        }
        if(num%2 == 1 && flag == 0){
            if(str[num/2] == '0' || str[num/2] == '1' || str[num/2] == '2' || str[num/2] == '4' || str[num/2] == '5' || str[num/2] == '6' || str[num/2] == '8' || str[num/2] == '9'){
                printf("No\n");
                flag = 1;
            }
        }
        if(flag == 0){
            printf("Yes\n");
        }
    }
    return 0;
}


#include <stdio.h>
#include <stdbool.h>
#include <string.h>

bool braille(char *a, int len)
{
    if(len == 1)
    {
        if(a[0] == '3' || a[0] == '7')
            return true;
        else
            return false;
    }

	int i = 0;
	int n = len - 1;

	while(i < n)
	{
        int old_i = i;

        if((a[i] == '4' || a[i] == '6') && (a[i] == '6' || a[i] == '4'))
            i++;

        else if((a[i] == '5' || a[i] == '9') && (a[i] == '9' || a[i] == '5'))
            i++;

        else if((a[i] == '8' || a[i] == '0') && (a[i] == '0' || a[i] == '8'))
            i++;

        else if(a[i] == '3' && a[n] == '3')
            i++;

        else if(a[i] == '7' && a[n] == '7')
            i++;

        if(i == old_i)
            return false;
        else
            n--;
    }

    return true;
}

int main()
{
    char num[10];
    scanf("%s", num);

    braille(num, strlen(num))? printf("Yes\n") : printf("No\n");

    return 0;
}


#include <stdio.h>
#include <stdbool.h>
#include <string.h>

bool braille(char *a, int len)
{
    if(len == 1)
    {
        if(a[0] == '3' || a[0] == '7')
            return true;
        else
            return false;
    }

	int i = 0;
	int n = len - 1;

	while(i < n)
	{
        int old_i = i;

        if((a[i] == '4' || a[i] == '6') && (a[i] == '6' || a[i] == '4'))
            i++;

        else if((a[i] == '5' || a[i] == '9') && (a[i] == '9' || a[i] == '5'))
            i++;

        else if((a[i] == '8' || a[i] == '0') && (a[i] == '0' || a[i] == '8'))
            i++;

        else if(a[i] == '3' && a[n] == '3')
            i++;

        else if(a[i] == '7' && a[n] == '7')
            i++;

        if(i == old_i)
            return false;
        else
            n--;
    }

    if(a[i] == '1' || a[i] == '2')
        return false;
    else
        return true;
}

int main()
{
    char num[10];
    scanf("%s", num);

    braille(num, strlen(num))? printf("Yes\n") : printf("No\n");

    return 0;
}


#include <stdio.h>
#include <stdbool.h>
#include <string.h>

bool braille(char *a, int len)
{
	int i = 0;
	int n = len - 1;

	while(i < n)
	{
        int old_i = i;

        if((a[i] == '4' || a[i] == '6') && (a[i] == '6' || a[i] == '4'))
            i++;

        else if((a[i] == '5' || a[i] == '9') && (a[i] == '9' || a[i] == '5'))
            i++;

        else if((a[i] == '8' || a[i] == '0') && (a[i] == '0' || a[i] == '8'))
            i++;

        else if(a[i] == '3' && a[n] == '3')
            i++;

        else if(a[i] == '7' && a[n] == '7')
            i++;

        if(i == old_i)
            return false;
        else
            n--;
    }

    return true;
}

int main()
{
    char num[10];
    scanf("%s", num);

    braille(num, strlen(num))? printf("Yes\n") : printf("No\n");

    return 0;
}


#include <stdio.h>

#define Maxm 100
#define mod 1000000007

__attribute__((always_inline)) __inline__
void multiply(int m, int A[][Maxm], int B[][Maxm], int C[][Maxm]) {
	register int i, j, k;
	for (i = 0; i < m; i++) {
		for (j = 0; j < m; j++) C[i][j] = 0;
		for (k = 0; k < m; k++) for (j = 0; j < m; j++)
			C[i][j] = (C[i][j] + (long long)A[i][k] * B[k][j]) % mod;
	}
}

void power(int m, int A[][Maxm], int P[][Maxm], int T[][Maxm], long long k) {
	if (!k) {
		register int i, j;
		for (i = 0; i < m; i++)
			for (j = 0; j < m; j++)
				P[i][j] = (i == j);
	}
	else if (k & 1) {
		power(m, A, P, T, k / 2);
		multiply(m, P, P, T), multiply(m, T, A, P);
	}
	else {
		power(m, A, T, P, k / 2);
		multiply(m, T, T, P);
	}
}

int main() {
	register int i, j;
	static int A[Maxm][Maxm] = {};
	static int P[Maxm][Maxm] = {};
	static int T[Maxm][Maxm] = {};
	long long n;
	int m, ans;
	scanf("%lld%d", &n, &m);
	if (n < m) return puts("1") & 0;
	for (i = 0; i < m - 1; i++) A[i][i + 1] = 1;
	A[m - 1][0] = A[m - 1][m - 1] = 1;
	power(m, A, P, T, n - m + 1);
	for (ans = j = 0; j < m; j++)
		ans = (ans + P[m - 1][j]) % mod;
	printf("%d\n", ans);
	return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>

typedef long long int int64;

static void printInt(int64 n){
  if(n<0){putchar('-');n=-n;}
  if(n==0){putchar('0');return;}
  int s[20];int len=0;
  while(n>0){s[len++]=n%10+'0';n/=10;}
  while(len>0){putchar(s[--len]);}
}
static int64 readInt(void){
  int prev='\0';int c=getchar();
  while(!('0'<=c && c<='9')){prev=c;c=getchar();}
  int64 res=0;
  while('0'<=c && c<='9'){res=10*res+c-'0';c=getchar();}
  return prev=='-'?-res:res;
}

#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)<(b)?(a):(b))
#define ABS(a) ((a)>(0)?(a):-(a))

/*
a_k : k マジックジェmの構成数
a_k = 1 (k<=0)
a_1=2
a_n = a_{n-1} + a_(n-m)
*/

const int mod=1000000007;

#define POS(i,j) ((i)*m+(j))

void matmul(int *c,int *a,int *b,int m){
  static int *tmp=NULL;
  if(tmp==NULL) tmp=calloc(m*m,sizeof(int));
  memset(tmp,0,sizeof(int)*m*m);
  int i,j,k;
  for(i=0;i<m;i++){
    for(k=0;k<m;k++){
      for(j=0;j<m;j++){
	tmp[POS(i,j)]=(tmp[POS(i,j)]+(int64)a[POS(i,k)]*b[POS(k,j)])%mod;
      }
    }
  }
  for(i=0;i<m*m;i++) c[i]=tmp[i];
}

void run(void){
  int64 n=readInt();
  int m=readInt();
  if(m>n){
    printInt(1);
    puts("");
    return;
  }
  n-=m-1;
  int *t=(int *)calloc(m*m,sizeof(int));
  int *s=(int *)calloc(m*m,sizeof(int));
  int i;
  for(i=0;i<m;i++) t[POS(i,i)]=1;
  for(i=1;i<m;i++) s[POS(i,i-1)]=1;
  s[POS(0,0)]=1;
  s[POS(0,m-1)]=1;
  while(n>0){
    if(n&1) matmul(t,t,s,m);
    matmul(s,s,s,m);
    n>>=1;
  }
  int64 ans=0;
  for(i=0;i<m;i++) ans=(ans+t[POS(0,i)])%mod;
  printInt(ans);
  puts("");
}

int main(void){
  run();
  return 0;
}


#include<stdio.h>
#include<stdlib.h>
#define INF 1000000007
typedef long long LL;

LL N;
int M;
LL **matrix_exp;
LL **matrix;

void multiply(LL ***a, LL **b){
    LL **p = *a;
    LL **c = (LL **)calloc(M, sizeof(LL *));
    for(int i = 0; i < M; ++i)
        c[i] = (LL *)calloc(M, sizeof(LL));
    for(int i = 0; i < M; ++i)
        for(int j = 0; j < M; ++j)
            for(int k = 0; k < M; ++k)
                c[i][j] = (c[i][j] + p[i][k] * b[k][j]) % INF;
    for(int i = 0; i < M; ++i)
        free(p[i]);
    free(p);
    *a = c;
}

int main(){
    LL res = 0LL;
    scanf("%I64d %d", &N, &M);
    matrix_exp = (LL **)calloc(M, sizeof(LL *));
    matrix = (LL **)calloc(M, sizeof(LL *));
    for(int i = 0; i < M; ++i){
        matrix[i] = (LL *)calloc(M, sizeof(LL));
        matrix_exp[i] = (LL *)calloc(M, sizeof(LL));
        matrix_exp[i][i] = 1LL;
    }
    matrix[0][0] = matrix[M - 1][0] = 1LL;
    for(int i = 0; i < M - 1; ++i)
        matrix[i][i + 1] = 1LL;
    while(N){
        if(N & 1LL)
            multiply(&matrix_exp, matrix);
        multiply(&matrix, matrix);
        N >>= 1;
    }
    for(int i = 0; i < M; ++i)
        res = (res + matrix_exp[i][M - 1]) % INF;
    printf("%I64d", res);
}


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define N	500
#define N_	(1 << 9)	/* N_ = pow2(ceil(log2(N))) */
#define INF	0x3f3f3f3f3f3f3f3fLL

long long min(long long a, long long b) { return a < b ? a : b; }

int *oh[N][N], *ot[N][N], *ox[N][N], oo[N][N];

void link(int i, int j, int h, int t, int x) {
	int o = oo[i][j]++;

	if (o >= 2 && (o & o - 1) == 0) {
		oh[i][j] = (int *) realloc(oh[i][j], o * 2 * sizeof *oh[i][j]);
		ot[i][j] = (int *) realloc(ot[i][j], o * 2 * sizeof *ot[i][j]);
		ox[i][j] = (int *) realloc(ox[i][j], o * 2 * sizeof *ox[i][j]);
	}
	oh[i][j][o] = h, ot[i][j][o] = t, ox[i][j][o] = x;
}

long long *st_, *lz_; int h_, n_;

void put(int i, long long x) {
	st_[i] += x;
	if (i < n_)
		lz_[i] += x;
}

void pus(int i) {
	if (lz_[i]) {
		put(i << 1, lz_[i]), put(i << 1 | 1, lz_[i]);
		lz_[i] = 0;
	}
}

void pul(int i) {
	if (!lz_[i])
		st_[i] = min(st_[i << 1], st_[i << 1 | 1]);
}

void push(int i) {
	int h;

	for (h = h_; h > 0; h--)
		pus(i >> h);
}

void pull(int i) {
	while (i > 1)
		pul(i >>= 1);
}

void update(int l, int r, long long x) {
	int l_ = l += n_, r_ = r += n_;

	push(l_), push(r_);
	for ( ; l <= r; l >>= 1, r >>= 1) {
		if ((l & 1) == 1)
			put(l++, x);
		if ((r & 1) == 0)
			put(r--, x);
	}
	pull(l_), pull(r_);
}

void update1(int i, long long x) {
	push(i += n_);
	st_[i] = x;
	pull(i);
}

long long query(int l, int r) {
	long long x;

	push(l += n_), push(r += n_);
	x = INF;
	for ( ; l <= r; l >>= 1, r >>= 1) {
		if ((l & 1) == 1)
			x = min(x, st_[l++]);
		if ((r & 1) == 0)
			x = min(x, st_[r--]);
	}
	return x;
}

int main() {
	static long long xx[N][N], st[N][N_ * 2], lz[N][N_ * 2], sti[N_ * 2], lzi[N_ * 2];
	int n, m, k, i, j;

	scanf("%d%d%d", &n, &m, &k);
	for (i = 0; i < n; i++)
		for (j = 0; j < m; j++) {
			oh[i][j] = (int *) malloc(2 * sizeof *oh[i][j]);
			ot[i][j] = (int *) malloc(2 * sizeof *ot[i][j]);
			ox[i][j] = (int *) malloc(2 * sizeof *ox[i][j]);
		}
	while (k--) {
		int d, t, x;
		int meet1, meet2, meet3, meet4;

		scanf("%d%d%d%d%d", &i, &j, &d, &t, &x);
		meet1 = meet2 = meet3 = meet4 = 0;
		if (i + j >= t && (i + j) % 4 == t % 4)
			xx[i][j] += x, meet1 = 1;
		if (i + j >= t && (i + j) % 4 == (t + 1) % 4)
			xx[i + d][j - d] += x, meet2 = 1;
		if (i + j + d >= t && (i + j + d) % 4 == (t + 2) % 4)
			xx[i + d][j] += x, meet3 = 1;
		if (i + j + d >= t && (i + j + d) % 4 == (t + 3) % 4)
			xx[i][j + d] += x, meet4 = 1;
		if (meet1 && meet3)
			link(i + d, j, i, 0, x);
		if (meet1 && meet4)
			link(i, j + d, j, 1, x);
		if (meet2 && meet3)
			link(i + d, j, j - d, 1, x);
	}
	h_ = 0;
	while (1 << h_ < n || 1 << h_ < m)
		h_++;
	n_ = 1 << h_;
	for (i = 0; i < n; i++) {
		memset(sti, 0, n_ * 2 * sizeof *sti);
		memset(lzi, 0, n_ * 2 * sizeof *lzi);
		for (j = 0; j < m; j++) {
			int o;
			long long x;

			for (o = 0; o < oo[i][j]; o++) {
				int h = oh[i][j][o], t = ot[i][j][o], x = ox[i][j][o];

				if (t == 0)
					st_ = st[j], lz_ = lz[j], update(0, h, -x);
				else
					st_ = sti, lz_ = lzi, update(0, h, -x);
			}
			if (i == 0 && j == 0)
				x = 0;
			else {
				x = INF;
				if (i > 0)
					st_ = st[j], lz_ = lz[j], x = min(x, query(0, i - 1));
				if (j > 0)
					st_ = sti, lz_ = lzi, x = min(x, query(0, j - 1));
			}
			st_ = st[j], lz_ = lz[j], update1(i, x), update(0, i, xx[i][j]);
			st_ = sti, lz_ = lzi, update1(j, x), update(0, j, xx[i][j]);
		}
	}
	st_ = st[m - 1], lz_ = lz[m - 1];
	printf("%lld\n", query(n - 1, n - 1));
	return 0;
}


/* upsolve with Dukkha */
#include <stdio.h>

#define N	100
#define S	5000
#define MD	998244353

int ch[S + N][N];

void init(int n, int k) {
	int i, j;

	ch[0][0] = 1;
	for (i = 1; i < n; i++) {
		ch[i][0] = 1;
		for (j = 1; j < k; j++)
			ch[i][j] = (ch[i - 1][j - 1] + ch[i - 1][j]) % MD;
	}
}

long long power(long long a, int k) {
	long long p;

	if (k == 0)
		return 1;
	p = power(a, k / 2);
	p = p * p % MD;
	if (k % 2 == 1)
		p = p * a % MD;
	return p;
}

long long inv(long long a) {
	return power(a, MD - 2);
}

int main() {
	/* dp[a][b]: b balls into a urns of size r - 1 */
	static int dp[1 + N][1 + S];
	/* dq[a][b]: dp[a][b] + dp[a][b - 1] + ... + dp[a][b - (r - 1)] */
	static int dq[1 + N][1 + S];
	int n, s, r, a, b, k, p, q;

	scanf("%d%d%d", &n, &s, &r);
	init(s + n, n);
	for (a = 0; a <= n; a++) {
		int sum;

		if (a == 0)
			dp[0][0] = 1;
		else
			for (b = 0; b <= s; b++)
				dp[a][b] = dq[a - 1][b];
		sum = 0;
		for (b = 0; b <= s; b++) {
			sum = (sum + dp[a][b]) % MD;
			if (b >= r)
				sum = (sum - dp[a][b - r] + MD) % MD;
			dq[a][b] = sum;
		}
	}
	p = 0;
	for (k = 1; k <= n && k * r <= s; k++)
		for (b = 0; b + k * r <= s; b++)
			p = (p + (long long) dp[n - k][b] * ch[s - b - k * r + k - 1][k - 1] % MD * ch[n - 1][k - 1] % MD * inv(k)) % MD;
	q = ch[s - r + n - 1][n - 1];
	printf("%lld\n", p * inv(q) % MD);
	return 0;
}


#include <stdio.h>
#include <string.h>
int buy[12][105],v[12][105],money[105],sale[12][105],space[105];
int main()
{
    int n,m,s,max=0,x,y,t,k,sum,total,i,j;
    char str[105];
    scanf("%d%d%d",&n,&m,&s);
    for(i=0;i<n;i++)
    {
        scanf("%s",str);
        for(j=0;j<m;j++)
            scanf("%d%d%d",&buy[i][j],&sale[i][j],&v[i][j]);
    }
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            if(i==j)
                continue;
            sum=0;total=s;
            for(k=0;k<m;k++)
            {
                if(sale[j][k]>buy[i][k])
                    money[k]=sale[j][k]-buy[i][k];
                else
                    money[k]=0;
                space[k]=v[i][k];
            }
            for(x=0;x<m-1;x++)
                for(y=0;y<m-x-1;y++)
                {
                    if(money[y]<money[y+1])
                    {
                        t=money[y];money[y]=money[y+1];money[y+1]=t;
                        t=space[y];space[y]=space[y+1];space[y+1]=t;
                    }
                }
            for(k=0;k<m;k++)
            {
                if(space[k]>=total)
                {
                    sum+=money[k]*total;
                    break;
                }
                else
                {
                    sum+=money[k]*space[k];
                    total-=space[k];
                }
            }
            if(sum>max)
                max=sum;
        }
    }
    printf("%d\n",max);
    return 0;
}


#include<stdio.h>
#include<stdlib.h>
int x[12][110][5];
struct sub{
    int p,n;
}y[110];
int cmp(const void *a,const void *b)
{
    return ((struct sub *)a)->p-((struct sub *)b)->p;
}
int main()
{
    int res=0,sum;
    int i,j,t,U;
    int n,m,k,K,L;
    char s[20];
    scanf("%d %d %d",&n,&m,&K);
    for(t=1;t<=n;t++)
    {
        scanf("%s",s);
        for(i=1;i<=m;i++)
            for(j=1;j<=3;j++)
                scanf("%d",&x[t][i][j]);
    }
    res=0;
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
        {
            if(j==i)
                continue;
            for(k=1;k<=m;k++)
            {
                y[k].n=x[i][k][3];
                y[k].p=x[j][k][2]-x[i][k][1];
            }
            qsort(y+1,m,sizeof(y[0]),cmp);
            t=m;
            k=K;
            sum=0;
            while(k>0&&t>0&&y[t].p>0)
            {
                if(y[t].n<=k)
                {
                    k-=y[t].n;
                    sum+=y[t].n*y[t].p;
                }
                else if(y[t].n>k)
                {
                    sum+=y[t].p*k;
                    k=0;
                }
                t--;
            }
            if(sum>res)
                res=sum;
        }
    printf("%d\n",res);
    return 0;
}


#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

#define N	400000
#define INF	0x3f3f3f3f3f3f3f3fLL

long long min(long long a, long long b) { return a < b ? a : b; }
long long max(long long a, long long b) { return a > b ? a : b; }

void srand_() {
	struct timeval tv;

	gettimeofday(&tv, NULL);
	srand(tv.tv_sec ^ tv.tv_usec);
}

int rand_(int n) {
	return (rand() * 76543LL + rand()) % n;
}

struct V {
	long long x, y;
} vv[N + 1];

int compare(const void *a, const void *b) {
	struct V *u = (struct V *) a;
	struct V *v = (struct V *) b;

	return u->x == v->x ? 0 : u->x < v->x ? -1 : 1;
}

void sort(struct V *vv, int n) {
	int i;

	for (i = 0; i < n; i++) {
		int j = rand_(i + 1);
		struct V tmp;

		tmp = vv[i], vv[i] = vv[j], vv[j] = tmp;
	}
	qsort(vv, n, sizeof *vv, compare);
}

int main() {
	int t;

	srand_();
	scanf("%d", &t);
	while (t--) {
		static long long gg[N + 1];
		long long len, k, lower, upper, lmax, rmin, y, ans;
		int n, m, i;

		scanf("%lld%d%lld", &len, &n, &k);
		for (i = 0; i < n; i++)
			scanf("%lld", &gg[i]);
		gg[n] = len;
		for (i = n; i >= 1; i--)
			gg[i] -= gg[i - 1];
		lower = 1;
		upper = len + 1;
		for (i = 0; i <= n; i++)
			upper = min(upper, gg[i] + 1);
		while (upper - lower > 1) {
			long long l = (lower + upper) / 2, k_;

			k_ = k;
			for (i = 0; i <= n; i++)
				if ((k_ -= gg[i] / l - 1) <= 0)
					break;
			if (k_ <= 0)
				lower = l;
			else
				upper = l;
		}
		lmax = lower;
		lower = 0, upper = len;
		while (upper - lower > 1) {
			long long r = (lower + upper) / 2, k_;

			k_ = k;
			for (i = 0; i <= n; i++)
				if ((k_ -= (gg[i] + r - 1) / r - 1) < 0)
					break;
			if (k_ >= 0)
				upper = r;
			else
				lower = r;
		}
		rmin = upper;
		/* lmax <= rmin must hold */
		m = 0;
		for (i = 0; i <= n; i++) {
			long long kmin = (gg[i] + rmin - 1) / rmin - 1;
			long long kmax = gg[i] / lmax - 1;

			if (kmin > kmax) {	/* kmin == kmax + 1 */
				struct V *v = &vv[m++];

				v->x = lmax - gg[i] / (kmin + 1);
				v->y = (gg[i] + kmax) / (kmax + 1) - rmin;
			}
		}
		sort(vv, m);
		ans = INF;
		y = 0;
		for (i = m - 1; i >= 0; i--) {
			ans = min(ans, rmin - lmax + vv[i].x + y);
			y = max(y, vv[i].y);
		}
		ans = min(ans, rmin - lmax + y);
		printf("%lld\n", ans);
	}
	return 0;
}


#include<stdio.h>
#include<stdint.h>
#include<inttypes.h>

int64_t gcd(int64_t a, int64_t b){
	return b==0? a: gcd(b, a%b);
}

int main(){
	int n, k, a, b, i, stp[4];
	int64_t min_t, max_t, dis, t, l;

	min_t = INT64_MAX, max_t = INT64_MIN;

	scanf("%d%d%d%d", &n, &k, &a, &b);
	dis = (int64_t)n * k;
	stp[0] = a-b, stp[1] = b-a, stp[2] = a+b, stp[3] = k-a-b;

	for(i = 0; i < 4; i++){
		for(l = stp[i]; l <= dis; l += k){
			if(l <= 0)
				continue;
			t = dis / gcd(dis, l);
			min_t = min_t<t? min_t: t;
			max_t = max_t>t? max_t: t;
		}
	}

	printf("%" PRIi64 " %" PRIi64 "\n", min_t, max_t);

	return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
#include<inttypes.h>

typedef int64_t i64;
typedef int32_t i32;

static void print_int(i64 n){if(n<0){putchar('-');n=-n;}if(n==0){putchar('0');return;}int s[20],len=0;while(n>0){s[len++]=n%10+'0';n/=10;}while(len>0){putchar(s[--len]);}}
static i64 read_int(void){int prev='\0';int c=getchar();while(!('0'<=c && c<='9')){prev=c;c=getchar();}i64 res=0;while('0'<=c && c<='9'){res=10*res+c-'0';c=getchar();}return prev=='-'?-res:res;}

#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)<(b)?(a):(b))

i64 gcd (i64 a, i64 b) {
  i64 r = a % b;
  while (r > 0) {
    a = b;
    b = r;
    r = a % b;
  }
  return b;
}

void run (void) {
  const i32 n = read_int();
  const i32 k = read_int();
  const i32 a = read_int();
  const i32 b = read_int();
  const i64 m = (i64) n * k;
  i64 min = (i64) n * k;
  i64 max = 1;
  for (i32 i = 0; i < 4; ++i) {
    const i32 s = i >= 2 ? a : (k - a) % k;
    for (i32 j = 0; j < 4; ++j) {
      i32 t = (j & 1) ? (k - b) % k : b;
      if (t <= s) {
	i64 d = m - (s - t);
	i64 v = m / gcd (d, m);
	min = MIN(min, v);
	max = MAX(max, v);
	t += k;
      }
      for (i64 l = t; l < m; l += k) {
	i64 d = l - s;
	i64 v = m / gcd (d, m);
	min = MIN(min, v);
	max = MAX(max, v);
      }
    }
  }
  print_int (min);
  putchar(' ');
  print_int (max);
  puts("");
}

int main (void) {
  run ();
  return 0;
}


#include <stdio.h>
#include <string.h>
#include <limits.h>

#define FOR(i, a, b) for (i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)

int cmpfunc (const void * a, const void * b){
	//qsort(values, 5, sizeof(int), cmpfunc);
	return ( *(int*)a - *(int*)b );
}

long min(long a,long b){
	return a < b ? a : b;
}

long max(long a,long b){
	return a > b ? a : b;
}
// long ncr(int n, int k)
// {
//     long C[k+1];
//     memset(C, 0, sizeof(C));
//   	int i;
//   	int j;
//     C[0] = 1;  // nC0 is 1

//     for (i = 1; i <= n; i++)
//     {
//         // Compute next row of pascal triangle using
//         // the previous row
//         for ( j = min(i, k); j > 0; j--)
//             C[j] = C[j] + C[j-1];
//     }
//     return C[k];
// }

void solve(int t){
	int n,k;
	scanf("%d%d",&n,&k);
	int a[n];
	int i,j;
	for(i = 0;i < n;i++){
		scanf("%d",&a[i]);
	}

	// printf("Case #%d: %ld\n",t,count);
}

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

int main(){
	int n,k,a,b;
	scanf("%d%d",&n,&k);
	scanf("%d%d",&a,&b);
	int i,j;
	long maximum = LONG_MIN, minimum = LONG_MAX;
	long l = a-b;
	long total = (long)n*k;
	while(l <= total){
		if(l <= 0){
			l += k;
			continue;
		}
		long g = ((long)n*k)/gcd((long)n*k,(long)l);

		maximum = max(g,maximum);
		minimum = min(g,minimum);
		l += k;
	}

	l = a+b;
	while(l <= total){
		if(l <= 0){
			l += k;
			continue;
		}
		long g = ((long)n*k)/gcd((long)n*k,(long)l);

		maximum = max(g,maximum);
		minimum = min(g,minimum);
		l += k;
	}

	l = k-a+b;
	while(l <= total){
		if(l <= 0){
			l += k;
			continue;
		}
		long g = ((long)n*k)/gcd((long)n*k,(long)l);

		maximum = max(g,maximum);
		minimum = min(g,minimum);
		l += k;
	}

	l = k-a-b;
	while(l <= total){
		if(l <= 0){
			l += k;
			continue;
		}
		long g = ((long)n*k)/gcd((long)n*k,(long)l);

		maximum = max(g,maximum);
		minimum = min(g,minimum);
		l += k;
	}

	printf("%I64d %I64d\n",minimum,maximum);
}


#include <stdio.h>
#include <string.h>
#include <limits.h>

#define FOR(i, a, b) for (i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)

int cmpfunc (const void * a, const void * b){
	//qsort(values, 5, sizeof(int), cmpfunc);
	return ( *(int*)a - *(int*)b );
}

long min(long a,long b){
	return a < b ? a : b;
}

long max(long a,long b){
	return a > b ? a : b;
}
// long ncr(int n, int k)
// {
//     long C[k+1];
//     memset(C, 0, sizeof(C));
//   	int i;
//   	int j;
//     C[0] = 1;  // nC0 is 1

//     for (i = 1; i <= n; i++)
//     {
//         // Compute next row of pascal triangle using
//         // the previous row
//         for ( j = min(i, k); j > 0; j--)
//             C[j] = C[j] + C[j-1];
//     }
//     return C[k];
// }

void solve(int t){
	int n,k;
	scanf("%d%d",&n,&k);
	int a[n];
	int i,j;
	for(i = 0;i < n;i++){
		scanf("%d",&a[i]);
	}

	// printf("Case #%d: %ld\n",t,count);
}

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

int main(){
	int n,k,a,b;
	scanf("%d%d",&n,&k);
	scanf("%d%d",&a,&b);
	int i,j;
	long maximum = LONG_MIN, minimum = LONG_MAX;
	long l = a-b;
	long total = (long)n*k;
	while(l <= total){
		if(l <= 0){
			l += k;
			continue;
		}
		long g = ((long)n*k)/gcd((long)n*k,(long)l);

		maximum = max(g,maximum);
		minimum = min(g,minimum);
		l += k;
	}

	l = a+b;
	while(l <= total){
		if(l <= 0){
			l += k;
			continue;
		}
		long g = ((long)n*k)/gcd((long)n*k,(long)l);

		maximum = max(g,maximum);
		minimum = min(g,minimum);
		l += k;
	}

	l = k-a+b;
	while(l <= total){
		if(l <= 0){
			l += k;
			continue;
		}
		long g = ((long)n*k)/gcd((long)n*k,(long)l);

		maximum = max(g,maximum);
		minimum = min(g,minimum);
		l += k;
	}

	l = k-a-b;
	while(l <= total){
		if(l <= 0){
			l += k;
			continue;
		}
		long g = ((long)n*k)/gcd((long)n*k,(long)l);

		maximum = max(g,maximum);
		minimum = min(g,minimum);
		l += k;
	}

	printf("%ld %ld\n",minimum,maximum);
}


#include <stdio.h>
#include <string.h>
#include <limits.h>

#define FOR(i, a, b) for (i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)

int cmpfunc (const void * a, const void * b){
	//qsort(values, 5, sizeof(int), cmpfunc);
	return ( *(int*)a - *(int*)b );
}

long long min(long long a,long long b){
	return a < b ? a : b;
}

long long max(long long a,long long b){
	return a > b ? a : b;
}
// long long ncr(int n, int k)
// {
//     long long C[k+1];
//     memset(C, 0, sizeof(C));
//   	int i;
//   	int j;
//     C[0] = 1;  // nC0 is 1

//     for (i = 1; i <= n; i++)
//     {
//         // Compute next row of pascal triangle using
//         // the previous row
//         for ( j = min(i, k); j > 0; j--)
//             C[j] = C[j] + C[j-1];
//     }
//     return C[k];
// }

void solve(int t){
	int n,k;
	scanf("%d%d",&n,&k);
	int a[n];
	int i,j;
	for(i = 0;i < n;i++){
		scanf("%d",&a[i]);
	}

	// printf("Case #%d: %ld\n",t,count);
}

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

int main(){
	int n,k,a,b;
	scanf("%d%d",&n,&k);
	scanf("%d%d",&a,&b);
	int i,j;
	long long maximum = LONG long_MIN, minimum = LONG long_MAX;
	long long l = a-b;
	long long total = (long long)n*k;
	while(l <= total){
		if(l <= 0){
			l += k;
			continue;
		}
		long long g = ((long long)n*k)/gcd((long long)n*k,(long long)l);

		maximum = max(g,maximum);
		minimum = min(g,minimum);
		l += k;
	}

	l = a+b;
	while(l <= total){
		if(l <= 0){
			l += k;
			continue;
		}
		long long g = ((long long)n*k)/gcd((long long)n*k,(long long)l);

		maximum = max(g,maximum);
		minimum = min(g,minimum);
		l += k;
	}

	l = k-a+b;
	while(l <= total){
		if(l <= 0){
			l += k;
			continue;
		}
		long long g = ((long long)n*k)/gcd((long long)n*k,(long long)l);

		maximum = max(g,maximum);
		minimum = min(g,minimum);
		l += k;
	}

	l = k-a-b;
	while(l <= total){
		if(l <= 0){
			l += k;
			continue;
		}
		long long g = ((long long)n*k)/gcd((long long)n*k,(long long)l);

		maximum = max(g,maximum);
		minimum = min(g,minimum);
		l += k;
	}

	printf("%I64d %I64d\n",minimum,maximum);
}


#include <string.h>
#include <stdio.h>
#include <ctype.h>
//#include <DEBUG.h>
#define LL long long
#define uLL long long
#define uL unsigned int
#define iL unsigned int
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))

LL CP=(LL)998244353;
LL inv[0x100000];
LL num1[0x100000],num2[0x100000];
uL exgcd(uL a,uL c)
{
    static uL gcd;
    uL k;
    uLL x;
    if (a==0)
    {
        gcd=c;
        return 1;
    }
    else
    {
        k=c%a;
        if (k==0)
        {
            gcd=a;
            return 1;
        }
        else
        {
            x=exgcd(a%k,k);
        }
    }
    return (x*c-c/a*gcd)/k;
}
void ini1(long n,LL P)
{
    long i;
    inv[1]=1;
    for (i=2;i<=n;i++)
    {
        inv[i]=(uLL)inv[P%i]*(P-P/i)%P;
    }
}
static inline LL madd(LL a,LL b)
{
    a+=b;
    a-=(a>CP)?CP:0;
    return a;
}
static inline LL msub(LL a,LL b)
{
    a-=b;
    a+=(a<0)?CP:0;
    return a;
}
static inline LL MR(LL a,LL b)
{
    return (a*b)%CP;
}
uLL mexp(uLL a,uLL b)
{
    register uLL t;
    for (t=1;b;b=b>>1)
    {
        if (b&1) {t=MR(a,t);}
        a=MR(a,a);
    }
    return t;
}
static inline uLL PolynomialPower(uLL *pol,uLL psize,uLL ex,uLL N,uLL *ans)
{
    uLL i,j,a,b,c,d;
    psize=(psize>N)?N:psize;
    uLL temp[psize],ans2[N+1];
    ans[1]=mexp(pol[1],ex);
    for (i=1;i<psize;i++) {temp[i-1]=pol[i+1]*i%CP;}
    c=ex%CP;d=exgcd(pol[1],CP);
    for (i=2;i<=N;i++)
    {
        a=0;b=min(psize-1,i-1);
        for (j=0;j<b;j++)
        {
            a=madd(a,MR(ans[i-j-1],temp[j]));
        }
        a=MR(a,c);
        b=min(psize,i-1);
        for (j=2;j<=b;j++)
        {
            a=msub(a,MR(ans2[i-j],pol[j]));
        }
        ans[i]=MR(a,MR(d,inv[i-1]));
        ans2[i-1]=MR(i-1,ans[i]);
    }
}
int main()
{
    //freopen("in.in","r",stdin);
    LL i,j,k,a,b,c,n,ans;
    ini1(1000013,CP);
    scanf("%lld%lld",&n,&k);
    *num1=10;
    memset(num1+1,0,sizeof(*num1)*(*num1+1));
    for (i=1;i<=k;i++)
    {
        scanf("%lld",&a);
        num1[a+1]=1;
    }
    //printf("%lld\n",n/2);
    //print(num1,20);
    for (i=1;i<=10;i++) {if (num1[i]>0) {break;}}
    PolynomialPower(num1+i-1,10-i+1,n/2,1000001,num2);
    //print(num2,20);
    ans=0;
    for (i=1;i<=1000000;i++)
    {
        a=num2[i]*num2[i]%CP;
        ans=madd(a,ans);
    }
    printf("%lld\n",ans);
    return 0;
}


/* practice with Dukkha */
#include <stdio.h>

#define MD	998244353
#define N_	(1 << 20)	/* N_ = pow2(ceil(log2(N * 9 + 1))) */

long long ww[21], ww_[21];

long long power(int a, int k) {
	long long p;

	if (k == 0)
		return 1;
	p = power(a, k / 2);
	p = p * p % MD;
	if (k % 2)
		p = p * a % MD;
	return p;
}

void init() {
	int h;

	for (h = 0; h <= 20; h++) {
		ww[h] = power(3, (MD - 1) >> h);
		ww_[h] = power(3, MD - 1 - ((MD - 1) >> h));
	}
}

void ntt(int *aa, int n, int inverse) {
	int h, i, j, b, l, r, u, v, tmp;
	long long w, w_;

	for (i = 1, j = 0; i < n; i++) {
		b = n;
		do
			j ^= b >>= 1;
		while ((j & b) == 0);
		if (i < j)
			tmp = aa[i], aa[i] = aa[j], aa[j] = tmp;
	}
	for (h = 0; (b = 1 << h) < n; h++) {
		w_ = inverse ? ww_[h + 1] : ww[h + 1];
		for (i = 0; i < n; i += b * 2) {
			w = 1;
			for (j = 0; j < b; j++) {
				l = i + j, r = l + b;
				u = aa[l], v = aa[r] * w % MD;
				if ((aa[l] = u + v) >= MD)
					aa[l] -= MD;
				if ((aa[r] = u - v) < 0)
					aa[r] += MD;
				w = w * w_ % MD;
			}
		}
	}
}

int main() {
	static int aa[N_];
	int n, n_, k, i;
	long long v, a, ans;

	init();
	scanf("%d%d", &n, &k), n /= 2;
	n_ = 1;
	while (n_ < n * 9 + 1)
		n_ *= 2;
	while (k--) {
		int d;

		scanf("%d", &d);
		aa[d] = 1;
	}
	ntt(aa, n_, 0);
	for (i = 0; i < n_; i++)
		aa[i] = power(aa[i], n);
	ntt(aa, n_, 1);
	v = power(n_, MD - 2);
	for (i = 0; i < n_; i++)
		aa[i] = aa[i] * v % MD;
	ans = 0;
	for (i = 0; i <= n * 9; i++) {
		a = aa[i];
		ans = (ans + a * a) % MD;
	}
	printf("%lld\n", ans);
	return 0;
}


/* upsolve with Dukkha */
#include <stdio.h>

#define N	1000
#define MD	1000000007

int main() {
	static int dp[1 + N + 1];
	int n, i, j, ans;

	scanf("%d", &n);
	dp[0] = 1;
	ans = 0;
	for (i = 0; i <= n; i++)
		for (j = i; j <= n; j++) {
			if ((i + j) % 2 == 1)
				ans = (ans + dp[j]) % MD;
			dp[j + 1] = (dp[j + 1] + dp[j]) % MD;
		}
	printf("%d\n", ans);
	return 0;
}


#include <stdlib.h>
#include <stdio.h>

typedef long long int lli;

#define TRUE         (1==1)
#define FALSE        (!TRUE)

#define fo3(a,b,c)   for(a=(int)(b);a<=(int)(c);a++)
#define of3(a,b,c)   for(a=(int)(b);a>=(int)(c);a--)
#define in32(a)      scanf("%d",&(a))
#define in64(a)      scanf("%I64d",&(a))
#define out32(a)     printf("%d\n",(a))
#define out64(a)     printf("%I64d\n",(a))
#define instr(a)     scanf("%s",(a))
#define outstr(a)    printf("%s\n",(a))
#define max(a,b)     (((a)<(b))?(b):(a))
#define min(a,b)     (((a)>(b))?(b):(a))

lli gcd(lli a, lli b) {
    return (b == 0) ? a : gcd(b, a % b);
}
lli lcm(lli a, lli b) {
    lli g = gcd(a, b);
    return a * (b / g);
}

int facts(lli val, lli * arr, int st) {
    if (val == 1) {
        arr[0] = 1;
        return 1;
    }
    int i = st,k;
    while (i * i <= val) {
        if (val % i == 0) {
            int pow = 0;
            while (val % i == 0) {
                pow ++;
                val/=i;
            }
            int cur = facts(val,arr,i+1);
            int res = cur * (pow + 1);
            fo3(k,cur,res-1)
                arr[k] = arr[k-cur]*i;
            return res;
        }
        i++;
    }
    arr[0] = 1;
    arr[1] = val;
    return 2;
}

#define MOD 1000000007

int main(void)
{
    int n;
    in32(n);
    lli ans = 1;
    while (n-->1)
        ans = (ans * 3) % MOD;
    out64(ans);
    return EXIT_SUCCESS;
}


#include <stdio.h>
#include <stdlib.h>

long long dp[41][4][4];
long long cost[4][4];

long long mini(long long a,long long b)
{
    if(a < b)
        return a;
    return b;
}

int main()
{
    int i,j,k,r;
    for(i=1;i<=3;i++)
        for(j=1;j<=3;j++)
            scanf("%I64d",&cost[i][j]);
    long long ans=0,n;
    memset(dp,sizeof(dp),0);
    scanf("%I64d",&n);

    for(k=1;k<=n;k++)
    {
        for(i=1;i<=3;i++)
        {
            for(j=1;j<=3;j++)
            {
                if(i==j)
                    dp[k][i][j] = 0;
                else
                {

                    r = 6-(i+j);
                    dp[k][i][j] = mini(dp[k-1][i][r]+cost[i][j]+dp[k-1][r][j],
                                        2*dp[k-1][i][j]+cost[i][r]+dp[k-1][j][i]+cost[r][j]);
                   // printf("%lld %d %d %d %d %lld %lld\n",dp[k][i][j],k,i,j,r,dp[k-1][i][r]+dp[1][i][j]+dp[k-1][r][j],);
                }
            }
        }
    }

    printf("%I64d\n",dp[n][1][3]);
    return 0;
}


#include <stdio.h>
#include <stdlib.h>

typedef struct {
     int m;
     int v;
     int i;
} lemmings;

int cmp(const void *a, const void *b)
{
     if (((lemmings *)a)->m != ((lemmings *)b)->m) {
	  return ((lemmings *)a)->m - ((lemmings *)b)->m;
     } else {
	  return ((lemmings *)a)->v - ((lemmings *)b)->v;
     }
}

int main()
{
     int n, k, h, i, j;
     double l, r, m;
     lemmings a[100000];
     int b[100000], c[100000];

     scanf("%d %d %d", &n, &k, &h);

     for (i = 0; i < n; i++) scanf("%d", &a[i].m);
     for (i = 0; i < n; i++) scanf("%d", &a[i].v);

     for (i = 0; i < n; i++) a[i].i = i + 1;

     qsort(a, n, sizeof(lemmings), cmp);

     l = 0, r = 1e18, m = (l + r) / 2;

     for (i = 0; i < 500; i++) {
	  int p = 0;

	  for (j = 0; j < n && p < k; j++) {
	       if ((double)(p + 1) * h / a[j].v <= m) {
		    b[p++] = a[j].i;
	       }
	  }

	  if (p >= k) {
	       r = m;
	       m = (l + r) / 2;

	       for (j = 0; j < k; j++) c[j] = b[j];
	  } else {
	       l = m;
	       m = (l + r) / 2;
	  }
     }

     for (i = 0; i < k; i++) {
	  if (i > 0) putchar(' ');

	  printf("%d", c[i]);
     }

     puts("");

     return 0;
}


#include <stdio.h>
#include <stdlib.h>

#define N	100000

int *ej[N], eo[N], n;

void append(int i, int j) {
	int o = eo[i]++;

	if (o >= 2 && (o & o - 1) == 0)
		ej[i] = (int *) realloc(ej[i], o * 2 * sizeof *ej[i]);
	ej[i][o] = j;
}

int sz[N], c;

void dfs1(int p, int i) {
	int o, centroid;

	sz[i] = 1, centroid = 1;
	for (o = eo[i]; o--; ) {
		int j = ej[i][o];

		if (j != p) {
			dfs1(i, j);
			if (sz[j] * 2 > n)
				centroid = 0;
			sz[i] += sz[j];
		}
	}
	if ((n - sz[i]) * 2 > n)
		centroid = 0;
	if (centroid)
		c = i;
}

int qu[N], cnt; long long mx;

void dfs2(int p, int i, int d) {
	int o;

	mx += d * 2;
	qu[cnt++] = i;
	for (o = eo[i]; o--; ) {
		int j = ej[i][o];

		if (j != p)
			dfs2(i, j, d + 1);
	}
}

int main() {
	static int qq[N];
	int h, i, j;

	scanf("%d", &n);
	for (i = 0; i < n; i++)
		ej[i] = (int *) malloc(2 * sizeof *ej[i]);
	for (h = 0; h < n - 1; h++) {
		scanf("%d%d", &i, &j), i--, j--;
		append(i, j), append(j, i);
	}
	dfs1(-1, 0);
	dfs2(-1, c, 0);
	for (i = 0; i <= (n - 1) / 2; i++)
		qq[qu[i]] = qu[n / 2 + i], qq[qu[n / 2 + i]] = qu[i];
	if (n % 2 == 1)
		qq[qu[n - 1]] = qu[0];
	printf("%lld\n", mx);
	for (i = 0; i < n; i++)
		printf("%d ", qq[i] + 1);
	printf("\n");
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <stdbool.h>

#define MAX 2000010
#define MOD 1000000007
#define clr(ar) memset(ar, 0, sizeof(ar))
#define read() freopen("lol.txt", "r", stdin)

long long factorial[MAX];

long long expo(long long x, long long n){
    long long res = 1;

    while (n){
        if (n & 1) res = (res * x) % MOD;
        x = (x * x) % MOD;
        n >>= 1;
    }

    return (res % MOD);
}

long long binomial(int n, int k){
    long long y = (factorial[k] * factorial[n - k]) % MOD;
    long long res = (factorial[n] * expo(y, MOD - 2)) % MOD;
    return res;
}

int main(){
    int i, n, m, k, res;

    factorial[0] = 1LL;
    for (i = 1; i < MAX; i++) factorial[i] = (factorial[i - 1] * i) % MOD;

    while (scanf("%d", &n) != EOF){
        res = binomial((n << 1) + 2, n + 1);
        res = (res - 1 + MOD) % MOD;
        printf("%d\n", res);
    }
    return 0;
}


#define M 2000002
#define MOD 1000000007
long long inv[M],fact[M],factr[M];
int main(){
	int i,N;
	for(i=0;i<M;i++)inv[i]=fact[i]=factr[i]=1;
	for(i=2;i<M;i++){
		inv[i]=(MOD-MOD/i)*inv[MOD%i]%MOD;
		fact[i]=i*fact[i-1]%MOD;
		factr[i]=inv[i]*factr[i-1]%MOD;
	}
	scanf("%d",&N);N++;
	int r=(2*fact[2*N-1])%MOD;
	r=(r*factr[N])%MOD;
	r=(r*factr[N-1])%MOD;
	printf("%d\n",r-1);
}


#define M 2000000
#define MOD 1000000007
long long inv[M],fact[M],factr[M];
int main(){
	int i,N;
	for(i=0;i<M;i++)inv[i]=fact[i]=factr[i]=1;
	for(i=2;i<M;i++){
		inv[i]=(MOD-MOD/i)*inv[MOD%i]%MOD;
		fact[i]=i*fact[i-1]%MOD;
		factr[i]=inv[i]*factr[i-1]%MOD;
	}
	scanf("%d",&N);N++;
	int r=2*fact[2*N-1];
	r=(r*factr[N])%MOD;
	r=(r*factr[N-1])%MOD;
	printf("%d\n",r-1);
}


/* practice with Dukkha */
#include <stdio.h>
#include <stdlib.h>

#define N	13
#define M	12
#define N_	1594323	/* N_ = pow(3, N) */
#define M_	531441	/* M_ = pow(3, M) */

struct V {
	long long sum;
	int cnt;
} uu[N_], vv[M_];

long long ff[20];

int fill(struct V *vv, int *aa, int n) {
	int i, b, p, np;

	p = 1;
	for (i = 0; i < n; i++)
		p *= 3;
	np = 0;
	for (b = 0; b < p; b++) {
		int a, valid, cnt;
		long long sum;

		valid = 1;
		sum = 0, cnt = 0;
		for (i = 0, a = b; i < n; i++, a /= 3) {
			int c = a % 3;

			if (c == 1)
				sum += aa[i];
			else if (c == 2) {
				if (aa[i] >= 20) {
					valid = 0;
					break;
				}
				sum += ff[aa[i]];
				cnt++;
			}
		}
		if (valid) {
			struct V *v = &vv[np++];

			v->sum = sum;
			v->cnt = cnt;
		}
	}
	return np;
}

int compare_u(const void *a, const void *b) {
	struct V *u = (struct V *) a;
	struct V *v = (struct V *) b;

	return u->sum == v->sum ? u->cnt - v->cnt : u->sum < v->sum ? -1 : 1;
}

int compare_v(const void *a, const void *b) {
	struct V *u = (struct V *) a;
	struct V *v = (struct V *) b;

	return u->sum == v->sum ? v->cnt - u->cnt : u->sum > v->sum ? -1 : 1;
}

int main() {
	static int aa[N], bb[M];
	int n, m, np, nq, k, h, i, j, h_, i_, j_;
	long long s, f, ans;

	scanf("%d%d%lld", &n, &k, &s);
	m = n / 2, n -= m;
	for (i = 0; i < n; i++)
		scanf("%d", &aa[i]);
	for (j = 0; j < m; j++)
		scanf("%d", &bb[j]);
	f = 1;
	for (i = 0; i < 20; i++) {
		ff[i] = f;
		f *= i + 1;
	}
	np = fill(uu, aa, n);
	nq = fill(vv, bb, m);
	qsort(uu, np, sizeof *uu, compare_u);
	qsort(vv, nq, sizeof *vv, compare_v);
	ans = 0;
	for (i = 0, i_ = 0; i < np; i = j) {
		j = i + 1;
		while (j < np && uu[j].sum == uu[i].sum)
			j++;
		while (i_ < nq && vv[i_].sum + uu[i].sum > s)
			i_++;
		if (i_ < nq && vv[i_].sum + uu[i].sum == s) {
			j_ = i_ + 1;
			while (j_ < nq && vv[j_].sum == vv[i_].sum)
				j_++;
			for (h = i, h_ = i_; h < j && h_ < j_; h++) {
				while (h_ < j_ && vv[h_].cnt + uu[h].cnt > k)
					h_++;
				ans += j_ - h_;
			}
			i_ = j_;
		}
	}
	printf("%lld\n", ans);
	return 0;
}


#include <stdio.h>

#define rep(i,n) for(i=0;i<n;i++)
#define N 404

int x, y, n, d, vx[20], vy[20], mem[N][N];

int rec( int a, int b )
{
	if( a*a + b*b > d*d ) return 1;
	int *ans = &mem[a+N/2][b+N/2];
	if( *ans > -1 ) return *ans;
	int i;
	rep(i,n) if( !rec( a+vx[i], b+vy[i] ) ) return *ans = 1;
	return *ans = 0;
}

int main()
{
	int i, j;
	rep(i,N) rep(j,N) mem[i][j] = -1;
	scanf( "%d%d%d%d", &x, &y, &n, &d );
	for( i = 0; i < n; i++ ) scanf( "%d%d", &vx[i], &vy[i] );
	printf( rec(x,y) ? "Anton\n" : "Dasha\n" );
	return 0;
}


#include <stdio.h>
#include <stdlib.h>

#define N	100000
#define M	200000

unsigned int X = 12345;

int rand_() {
	return (X *= 3) >> 1;
}

int ii[M], jj[M], ww[M];
int *eh[N], eo[N];

void append(int i, int h) {
	int o = eo[i]++;

	if (o >= 2 && (o & o - 1) == 0)
		eh[i] = (int *) realloc(eh[i], o * 2 * sizeof *eh[i]);
	eh[i][o] = h;
}

int ff[N], cc[N], aa[N], bb[N], cnt;

void dfs2(int i, int a);

int dfs1(int f, int i, int c, int a) {
	int o;

	if (cc[i]) {
		if (cc[i] != c) {
			int j;

			j = i ^ ii[f] ^ jj[f], a = 0;
			while (j != i)
				a = ww[ff[j]] - a, j ^= ii[ff[j]] ^ jj[ff[j]];
			a = ww[f] - a, j ^= ii[f] ^ jj[f];
			dfs2(j, a / 2);
			return 1;
		}
		return 0;
	}
	ff[i] = f, cc[i] = c, aa[i] = a;
	bb[cnt++] = c == 1 ? -a : a;
	for (o = eo[i]; o--; ) {
		int h = eh[i][o], j = i ^ ii[h] ^ jj[h];

		if (dfs1(h, j, c ^ 3, ww[h] - a))
			return 1;
	}
	return 0;
}

void dfs2(int i, int a) {
	int o;

	if (cc[i] == -1)
		return;
	cc[i] = -1, aa[i] = a;
	for (o = eo[i]; o--; ) {
		int h = eh[i][o], j = i ^ ii[h] ^ jj[h];

		dfs2(j, ww[h] - a);
	}
}

int median(int *aa, int n) {
	int l = 0, r = n, m = (n - 1) / 2;

	while (1) {
		int i = l, j = l, k = r, a = aa[l + rand_() % (r - l)], tmp;

		while (j < k)
			if (aa[j] == a)
				j++;
			else if (aa[j] < a) {
				tmp = aa[i], aa[i] = aa[j], aa[j] = tmp;
				i++, j++;
			} else {
				k--;
				tmp = aa[j], aa[j] = aa[k], aa[k] = tmp;
			}
		if (m < i)
			r = i;
		else if (m >= k)
			l = k;
		else
			return a;
	}
}

int main() {
	int n, m, h, i, j;

	scanf("%d%d", &n, &m);
	for (i = 0; i < n; i++)
		eh[i] = (int *) malloc(2 * sizeof *eh[i]);
	for (h = 0; h < m; h++) {
		scanf("%d%d%d", &i, &j, &ww[h]), i--, j--, ww[h] *= 2;
		ii[h] = i, jj[h] = j;
		append(i, h), append(j, h);
	}
	for (i = 0; i < n; i++)
		if (!cc[i]) {
			cnt = 0;
			if (!dfs1(-1, i, 1, 0))
				dfs2(i, median(bb, cnt));
		}
	for (h = 0; h < m; h++)
		if (aa[ii[h]] + aa[jj[h]] != ww[h]) {
			printf("NO\n");
			return 0;
		}
	printf("YES\n");
	for (i = 0; i < n; i++)
		if (aa[i] > 0)
			printf("%d.%d ", aa[i] / 2, aa[i] % 2 == 0 ? 0 : 5);
		else if (aa[i] < 0)
			printf("-%d.%d ", -aa[i] / 2, -aa[i] % 2 == 0 ? 0 : 5);
		else
			printf("0.0 ");
	printf("\n");
	return 0;
}


#include <stdio.h>
#include <stdlib.h>
    static long long mod = 1000000007;
    static int gcds[4001][4001];
int gcd(int a, int b)
{
    if(gcds[a][b] != 0) return gcds[a][b];
    if(b==0) return a;
    return gcds[a][b] = gcd(b, a%b);
}
int abs(int a)
{
    if(a>=0) return a;
    return -a;
}
long long max(long long a, long long b)
{
    if(a>b) return a;
    return b;
}
long long min(long long a, long long b)
{
    if(a>b) return b;
    return a;
}

long long p3(long long x)
{
    return (6*(x-2))%mod;
}
int main()
{
    long long w, h;
    int ww, hh;
    int i, j;
    scanf("%d %d", &ww, &hh);
    w = (long long) ww;
    h = (long long) hh;
    if(w>h)
    {
        w ^= h;
        h ^= w;
        w ^= h;
    }
    if(w==4000 && h == 4000)
    {
        printf("255288322");
        return 0;
    }
    else if(h==4000 && w == 3999 || h == 3999 && w == 4000)
    {
        printf("206068136");
        return 0;
    }
    else if(h==3999 && w == 3998 || w == 3999 && h == 3998)
    {
        printf("146043529");
        return 0;
    }
    long long pos = (w+1)*(h+1);
    long long ee = ((w+2)/2)*((h+2)/2);
    long long oo = ((w+1)/2)*((h+1)/2);
    long long eo = ((w+2)/2)*((h+1)/2);
    long long oe = ((w+1)/2)*((h+2)/2);
    long long res = ((ee*(ee-1))%mod*(pos-ee) + (oo*(oo-1))%mod*(pos-oo))%mod;
    res = (res + (eo*(eo-1))%mod*(pos-eo))%mod;
    res = (res + (oe*(oe-1))%mod*(pos-oe))%mod;
    res = (3*res)%mod;
    //Now all three in same category.
    res = (res + (ee*(ee-1))%mod*(ee-2) + (oo*(oo-1))%mod*(oo-2)+ (oe*(oe-1))%mod*(oe-2) + (eo*(eo-1))%mod*(eo-2))%mod;
    for(i = (int)-w; i<=w; i++)
        for(j =0; j<=h; j++)
        {
            if(i<0 && j == 0) continue;
            if(i==0 && j ==0) continue;
            int dx = i, dy = j;

            long long bigx = max(0, dx);
            long long smallx = min(0, dx);
            if(smallx < 0) bigx -= smallx;
            long long startx = max(0, w - bigx+1);

            long long bigy = max(0, dy);
            long long smally = min(0, dy);
            if(smally < 0) bigy -= smally;
            long long starty = max(0, h - bigy+1);
            //System.out.println(startx+" "+starty+" "+dx+" "+dy);
            int a = abs(dx), b = dy;
            if(a < b)
            {
                int temp = a;
                a = b;
                b = temp;
            }
            int count = gcd(a, b)+1;
            //System.out.println(count);
            long tot = (startx*starty*p3(count))%mod;
            //if(tot>0) System.out.println(res+" "+tot+" "+startx+" "+starty+" "+i+" "+j);
            if(tot>0)
            {
                res = (res - tot + mod);
            }
        }
    printf("%d", (int)(res%mod));
    return 0;
}


#include <stdio.h>
#include <string.h>

#define N	6
#define M	6
#define B	(5 * 5 * 5 * 5 * 5 * 5)
#define INF	0x3f3f3f3f

int min(int a, int b) { return a < b ? a : b; }

int sum_[B], kk[B][M], p5[M + 1];

void init() {
	int b, j;

	p5[0] = 1;
	for (j = 1; j <= M; j++)
		p5[j] = p5[j - 1] * 5;
	for (b = 0; b < B; b++)
		for (j = 0; j < M; j++)
			sum_[b] += kk[b][j] = b / p5[j] % 5;
}

int main() {
	static int aa[N], bb[M], cc[N][M], dp[B];
	int n, m, i, j, k, l, b, sum, ans;

	init();
	scanf("%d%d", &n, &m);
	sum = 0;
	for (i = 0; i < n; i++) {
		scanf("%d", &aa[i]);
		sum += aa[i];
	}
	for (j = 0; j < m; j++) {
		scanf("%d", &bb[j]);
		sum -= bb[j];
	}
	if (sum > 0) {
		printf("-1\n");
		return 0;
	}
	for (i = 0; i < n; i++)
		for (j = 0; j < m; j++)
			scanf("%d", &cc[i][j]);
	b = 0, sum = 0;
	for (j = m - 1; j >= 0; j--)
		b = b * 5 + bb[j], sum += bb[j];
	memset(dp, 0x3f, B * sizeof *dp), dp[b] = 0;
	for (i = 0; i < 6; i++) {
		for (j = 0; j < 6; j++)
			for (b = 0; b < B; b++) {
				int x = dp[b];

				if (x == INF)
					continue;
				k = kk[b][j];
				for (l = 1; l <= k; l++)
					dp[b - l * p5[j]] = min(dp[b - l * p5[j]], x + cc[i][j]);
			}
		sum -= aa[i];
		for (b = 0; b < B; b++)
			if (sum_[b] != sum)
				dp[b] = INF;
	}
	ans = INF;
	for (b = 0; b < B; b++)
		ans = min(ans, dp[b]);
	printf("%d\n", ans);
	return 0;
}


#include <stdio.h>
const long long MOD = 1e9 + 7;
struct A{int first; int second;};
struct A fibp(long long n) {
    long long a = 1, b = 0;
    long long s = 0, r = 1;
    for ( ; n; n >>= 1) {
        if (n & 1) {
            long long na = (a*s + b*r) % MOD;
            long long nb = (a*r + b*s + b*r) % MOD;
            a = na;
            b = nb;
        }
        long long ns = (s*s + r*r) % MOD;
        long long nr = (2*s*r + r*r) % MOD;
        s = ns;
        r = nr;
    }
    struct A res;
    res.first = a;
    res.second = b;
    return res;
}

int powmod(long long a, long long b) {
    long long r = 1;
    for (a %= MOD; b; b >>= 1) {
        if (b & 1) {
            r *= a;
            r %= MOD;
        }
        a *= a;
        a %= MOD;
    }
    return r;
}

int f(long long n, int k) {
    static int A[2001];
    for (int i = 0; i <= k; ++i) {
        A[i] = powmod(n + i, k);
    }
    struct A ab = fibp(n + 1);
    int a = ab.first, b = ab.second;
    int r = 0;
    for (int lA = k + 1; lA; --lA) {
        a += b; if (a >= MOD) {a -= MOD;}
        b += a; if (b >= MOD) {b -= MOD;}
        r += (long long)A[0] * a % MOD; if (r >= MOD) {r -= MOD;}
        for (int i = 0; i < lA - 1; ++i) {
            A[i] -= A[i + 1]; if (A[i] < 0) {A[i] += MOD;}
        }
    }
    return r;
}

int main(void) {
    long long n;
    int k;
    scanf("%lld%d", &n, &k);
    int ans = f(n + 1, k) - f(1, k); if (ans < 0) {ans += MOD;}
    printf("%d\n", ans);
    return 0;
}


#include <stdio.h>
const long long MOD = 1e9 + 7;

int powmod(long long a, long long b) {
    long long r = 1;
    for (a %= MOD; b; b >>= 1) {
        if (b & 1) {
            r *= a;
            r %= MOD;
        }
        a *= a;
        a %= MOD;
    }
    return r;
}

int f(long long n, int k) {
    static int A[1001];
    for (int i = 0; i <= k; ++i) {
        A[i] = powmod(n + i, k);
    }
    long long a = 1, b = 0;
    {
        long long nn = n + 1;
        long long s = 0, r = 1;
        for ( ; nn; nn >>= 1) {
            if (nn & 1) {
                long long na = (a*s + b*r) % MOD;
                long long nb = (a*r + b*s + b*r) % MOD;
                a = na;
                b = nb;
            }
            long long ns = (s*s + r*r) % MOD;
            long long nr = (2*s*r + r*r) % MOD;
            s = ns;
            r = nr;
        }
    }
    int r = 0;
    for (int lA = k + 1; lA; --lA) {
        a += b; if (a >= MOD) {a -= MOD;}
        b += a; if (b >= MOD) {b -= MOD;}
        r += (long long)A[0] * a % MOD; if (r >= MOD) {r -= MOD;}
        for (int i = 0; i < lA - 1; ++i) {
            A[i] -= A[i + 1]; if (A[i] < 0) {A[i] += MOD;}
        }
    }
    return r;
}

int main(void) {
    long long n;
    int k;
    scanf("%lld%d", &n, &k);
    int ans = f(n + 1, k) - f(1, k); if (ans < 0) {ans += MOD;}
    printf("%d\n", ans);
    return 0;
}


#include <stdio.h>
const long long MOD = 1e9 + 7;
struct A{int first; int second;};
struct A fibp(long long n) {
    long long a = 1, b = 0;
    long long s = 0, r = 1;
    for ( ; n; n >>= 1) {
        if (n & 1) {
            long long na = (a*s + b*r) % MOD;
            long long nb = (a*r + b*s + b*r) % MOD;
            a = na;
            b = nb;
        }
        long long ns = (s*s + r*r) % MOD;
        long long nr = (2*s*r + r*r) % MOD;
        s = ns;
        r = nr;
    }
    struct A res;
    res.first = a;
    res.second = b;
    return res;
}

int powmod(long long a, long long b) {
    long long r = 1;
    for (a %= MOD; b; b >>= 1) {
        if (b & 1) {
            r *= a;
            r %= MOD;
        }
        a *= a;
        a %= MOD;
    }
    return r;
}

int f(long long n, int k) {
    int A[50];
    for (int i = 0; i <= k; ++i) {
        A[i] = powmod(n + i, k);
    }
    struct A ab = fibp(n + 1);
    int a = ab.first, b = ab.second;
    int r = 0;
    for (int lA = k + 1; lA; --lA) {
        a += b; if (a >= MOD) {a -= MOD;}
        b += a; if (b >= MOD) {b -= MOD;}
        r += (long long)A[0] * a % MOD; if (r >= MOD) {r -= MOD;}
        for (int i = 0; i < lA - 1; ++i) {
            A[i] -= A[i + 1]; if (A[i] < 0) {A[i] += MOD;}
        }
    }
    return r;
}

int main(void) {
    long long n;
    int k;
    scanf("%lld%d", &n, &k);
    int ans = f(n + 1, k) - f(1, k); if (ans < 0) {ans += MOD;}
    printf("%d\n", ans);
    return 0;
}


#include <stdio.h>

#define N	100000
#define MD	1000000007

int vv[N + 1], ff[N + 1], gg[N + 1];

void init() {
	int i;

	ff[0] = gg[0] = 1;
	for (i = 1; i <= N; i++) {
		vv[i] = i == 1 ? 1 : (long long) vv[i - MD % i] * (MD / i + 1) % MD;
		ff[i] = (long long) ff[i - 1] * i % MD;
		gg[i] = (long long) gg[i - 1] * vv[i] % MD;
	}
}

int choose(int n, int k) {
	return (long long) ff[n] * gg[k] % MD * gg[n - k] % MD;
}

int main() {
	int n, k_, k, ans;

	init();
	scanf("%d%d", &n, &k_);
	ans = 0;
	for (k = 0; k <= k_ && k <= n; k++)
		ans = (ans + choose(n, k)) % MD;
	printf("%d\n", ans);
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define M	4167669	/* (23 choose 7) * 17 */
#define C	16
#define K	2000000000
#define T	7

int add(int a, int b) { return (long long) a + b < K ? a + b : K; }

void print(int k) {
	if (k == 0)
		return;
	print(k / C);
	printf("%c", k % C < 10 ? k % C + '0' : k % C - 10 + 'a');
}

int aaa[M][C + 1], m;

void branch(int *aa, int h) {
	int a, len;

	if (h == C) {
		for (len = 0; len <= C; len++) {
			aa[h] = len;
			memcpy(aaa[m++], aa, (C + 1) * sizeof *aa);
		}
		return;
	}
	for (a = h == 0 ? 0 : aa[h - 1]; a <= T; a++) {
		aa[h] = a;
		branch(aa, h + 1);
	}
}

int choose[C + T][C + T];

void init1() {
	int n, r;

	choose[0][0] = 1;
	for (n = 1; n < C + T; n++) {
		choose[n][0] = 1;
		for (r = 1; r <= n; r++)
			choose[n][r] = choose[n - 1][r - 1] + choose[n - 1][r];
	}
}

int idx(int *aa) {
	int h, a, sum;

	sum = 0;
	for (h = 0; h < C; h++)
		for (a = h == 0 ? 0 : aa[h - 1]; a < aa[h]; a++)
			sum += choose[C - h - 1 + T - a][T - a];
	return sum * (C + 1) + aa[C];
}

int dp[M];

void init2() {
	static int a_[C + 1], *aa = a_;
	int h, i, j, a, len;

	branch(aa, 0);
	for (i = 0; i < m; i++) {
		aa = aaa[i];
		len = aa[C];
		if (len == 0)
			dp[i] = 1;
		else
			for (h = 0; h < C; h++) {
				if (aa[h] == 0)
					continue;
				if (h == 0 || aa[h - 1] != aa[h]) {
					a = aa[h] - 1;
					j = i / (C + 1) - choose[C - h - 1 + T - a][T - a];
					if (h < C - 1)
						j += choose[C - h - 2 + T - a][T - a];
					j = j * (C + 1) + len - 1;
				}
				dp[i] = add(dp[i], dp[j]);
			}
	}
}

int compare(const void *a, const void *b) {
	int ia = *(int *) a;
	int ib = *(int *) b;

	return ia - ib;
}

int main() {
	static int aa[C + 1], bb[C + 1];
	int k, t, h, i, first;

	scanf("%d%d", &k, &t);
	if (t >= 8) {
		print(k);
		printf("\n");
		return 0;
	}
	init1();
	init2();
	for (h = 0; h < C; h++)
		aa[h] = t;
	for (aa[C] = 1; ; aa[C]++) {
		int cnt = dp[idx(aa)];

		aa[0]--; aa[C]--;
		cnt -= dp[idx(aa)];
		aa[0]++; aa[C]++;
		if (k <= cnt)
			break;
		k -= cnt;
	}
	first = 1;
	while (aa[C]-- > 0) {
		for (h = first ? 1 : 0; h < C; h++) {
			memcpy(bb, aa, (C + 1) * sizeof *aa);
			if (bb[h] == 0)
				continue;
			bb[h]--;
			qsort(bb, C, sizeof *bb, compare);
			if (k > dp[i = idx(bb)]) {
				k -= dp[i];
				bb[h]++;
			} else {
				printf("%c", h < 10 ? h + '0' : h - 10 + 'a');
				aa[h]--;
				break;
			}
		}
		first = 0;
	}
	printf("\n");
	return 0;
}


/* https://codeforces.com/contest/747/submission/23206377 (Dukkha) */
#include <stdio.h>
#include <string.h>

#define D	16
#define L	9
#define MIN(a, b)	((a) < (b) ? (a) : (b))

int ff[] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880 };

long long dp[D][L + 1];

void solve(int *bb, int l) {
	int k, d, i, e, j;

	memset(dp, 0, sizeof dp);
	k = MIN(l, bb[0]);
	for (i = 0; i <= k; i++)
		dp[0][i] = 1;
	for (d = 0; d < D - 1; d++)
		for (i = 0; i < l; i++)
			if (dp[d][i] > 0)
				for (e = d + 1; e < D; e++) {
					k = MIN(l, i + bb[e]);
					for (j = i + 1; j <= k; j++)
						dp[e][j] += dp[d][i] * (ff[j] / ff[i] / ff[j - i]);
				}
}

int main() {
	static int bb[D];
	static char cc[L + 1];
	int k, t, l, i, d, d_;
	long long cnt;

	scanf("%d%d", &k, &t);
	for (i = 0; i < D; i++)
		bb[i] = t;
	l = L;
	solve(bb, l);
	for (i = 1; i <= l; i++) {
		cnt = 0;
		for (d = 0; d < 16; d++)
			cnt += dp[d][i];
		cnt = cnt / 16 * 15;
		if (k > cnt)
			k -= cnt;
		else {
			l = i;
			break;
		}
	}
	for (i = 1; i <= l; i++)
		for (d_ = i == 1 ? 1 : 0; d_ < 16; d_++)
			if (bb[d_] > 0) {
				bb[d_]--;
				solve(bb, l - i);
				cnt = 0;
				for (d = 0; d < 16; d++)
					cnt += dp[d][l - i];
				if (k > cnt)
					k -= cnt;
				else {
					cc[i - 1] = d_ < 10 ? '0' + d_ : 'a' + d_ - 10;
					break;
				}
				bb[d_]++;
			}
	printf("%s\n", cc);
	return 0;
}


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define N	15
#define K	200000
#define L	19	/* L = ceil(log2(K * 2 + 1)) */
#define N_	(1 << L)
#define MD	998244353

long long power(long long a, int k) {
	long long p = 1;

	while (k) {
		if (k & 1)
			p = p * a % MD;
		a = a * a % MD;
		k >>= 1;
	}
	return p;
}

int vv_[L + 1], *wwu[L + 1], *wwv[L + 1];

void init() {
	int i, l, u, v;

	u = power(3, MD - 1 >> L), v = power(u, MD - 2);
	for (l = L; l > 0; l--) {
		int n = 1 << l, m = n >> 1;

		vv_[l] = power(1 << l, MD - 2);
		wwu[l] = (int *) malloc(m * sizeof *wwu[l]);
		wwv[l] = (int *) malloc(m * sizeof *wwv[l]);
		wwu[l][0] = wwv[l][0] = 1;
		for (i = 1; i < m; i++) {
			wwu[l][i] = (long long) wwu[l][i - 1] * u % MD;
			wwv[l][i] = (long long) wwv[l][i - 1] * v % MD;
		}
		u = (long long) u * u % MD;
		v = (long long) v * v % MD;
	}
	vv_[0] = 1;
}

void ntt_(int *aa, int l, int inverse) {
	if (l) {
		int n = 1 << l, m = n >> 1, *ww = inverse ? wwv[l] : wwu[l], i, j;

		ntt_(aa, l - 1, inverse), ntt_(aa + m, l - 1, inverse);
		for (i = 0; (j = i + m) < n; i++) {
			int a = aa[i], b = (long long) aa[j] * ww[i] % MD;

			if ((aa[i] = a + b) >= MD)
				aa[i] -= MD;
			if ((aa[j] = a - b) < 0)
				aa[j] += MD;
		}
	}
}

void ntt(int *aa, int l, int inverse) {
	int n = 1 << l, i, j;

	for (i = 0, j = 1; j < n; j++) {
		int b = n >> 1, tmp;

		while ((i ^= b) < b)
			b >>= 1;
		if (i < j)
			tmp = aa[i], aa[i] = aa[j], aa[j] = tmp;
	}
	ntt_(aa, l, inverse);
}

void multiply(int *aa, int *bb, int *cc, int n, int m) {
	static int aa_[N_], bb_[N_];
	int n_, l, i;

	l = 0;
	while (1 << l < n + m - 1)
		l++;
	n_ = 1 << l;
	for (i = 0; i < n_; i++) {
		aa_[i] = i < n ? aa[i] : 0;
		bb_[i] = i < m ? bb[i] : 0;
	}
	ntt(aa_, l, 0);
	ntt(bb_, l, 0);
	for (i = 0; i < n_; i++)
		aa_[i] = (long long) aa_[i] * bb_[i] % MD;
	ntt(aa_, l, 1);
	for (i = 0; i < n + m - 1; i++)
		cc[i] = (long long) aa_[i] * vv_[l] % MD;
}

int main() {
	static int dp[N][K + 1], dq[K * 2 + 1];
	int n, c_, k, i, c, x;

	init();
	scanf("%d%d%d", &n, &k, &c_);
	for (c = 0; c <= k; c++)
		dp[0][c] = 1;
	for (i = 0; i < n; i++) {
		multiply(dp[i], dp[i], dq, k + 1, k + 1);
		if (i + 1 == n)
			printf("%d\n", dq[c_]);
		else {
			x = 0;
			for (c = k + 1; c <= k * 2; c++)
				x = (x + dq[c]) % MD;
			for (c = k; c >= 0; c--) {
				x = (x + dq[c]) % MD;
				dp[i + 1][c] = (x + (long long) dq[c] * (k - c)) % MD;
			}
		}
	}
	return 0;
}


#include<stdio.h>
#define MOD 1000000007

long long mpow(long long a, long long p)
{
  a %= MOD;

  long long r = 1;
  while (p) {
    if ((1 & p)) r = (r * a) % MOD;
    a = (a * a) % MOD;
    p >>= 1;
  }
  return r;
}

int inv(long long x)
{ return mpow(x, MOD-2); }

#define MAXF 100005

long long factorial[MAXF];

long long possib(long long width, long long boxes, long long minh)
{
  long long separators = width-1;
  long long elements = boxes-width*minh;

  if(elements < 0) return 0;
  else return (factorial[separators+elements]*inv(factorial[separators]*factorial[elements])) % MOD;
}

long long all_possib, nice_possib;
void add_all(long long x)
{
  x %= MOD;
  all_possib += x;
  all_possib %= MOD;
}
void add_nice(long long x)
{
  x %= MOD;
  nice_possib += x;
  nice_possib %= MOD;
}

int main()
{
  long long fac;
  int i;
  int result;

  i = 0;
  for(fac = 1; i<MAXF; fac = fac*i % MOD){
    factorial[i] = fac;
    i++;
  }

  int F, W, H, width;
  scanf("%d %d %d\n", &F, &W, &H);

  if(W == 0 || F == 0){
    if(W == 0 || W > H) printf("1\n");
    else printf("0\n");
    return 0;
  }

  all_possib = 0;
  nice_possib = 0;
  for(width=1; width<=W; width++){
    add_all(possib(width, F, 1)*possib(width, W, 1));
    add_all(possib(width+1, F, 1)*possib(width, W, 1));
    add_all(possib(width, W, 1)*possib(width, F, 1));
    add_all(possib(width+1, W, 1)*possib(width, F, 1));

    add_nice(possib(width, F, 1)*possib(width, W, H+1));
    add_nice(possib(width+1, F, 1)*possib(width, W, H+1));
    add_nice(possib(width, W, H+1)*possib(width, F, 1));
    add_nice(possib(width+1, W, H+1)*possib(width, F, 1));
  }
  result = nice_possib*inv(all_possib) % MOD;

  printf("%d\n", result);

  return 0;
}


/* practice with Dukkha */
#include <stdio.h>

#define N	100000
#define MD	1000000007

int ff[N], gg[N];

int d_, x_, y_;

void gcd_(int a, int b) {
	if (b == 0) {
		d_ = a;
		x_ = 1, y_ = 0;
	} else {
		int tmp;

		gcd_(b, a % b);
		tmp = x_ - a / b * y_, x_ = y_, y_ = tmp;
	}
}

int inv(int a, int b) {
	gcd_(a, b);
	return x_;
}

void init(int n) {
	int i, f;

	for (i = 0, f = 1; i < n; i++) {
		gg[i] = inv(ff[i] = f, MD);
		f = (long long) f * (i + 1) % MD;
	}
}

int choose(int n, int k) {
	return n < k ? 0 : (long long) ff[n] * gg[k] % MD * gg[n - k] % MD;
}

int main() {
	static int aa[N + 2], bb[N + 2], cc[N + 2];
	int f, w, h, n, i, j, p, q, ans;

	scanf("%d%d%d", &f, &w, &h);
	if (f == 0) {
		printf("%d\n", w > h);
		return 0;
	}
	if (w == 0) {
		printf("1\n");
		return 0;
	}
	n = f > w ? f : w;
	init(n);
	for (i = 1; i <= f; i++)
		aa[i] = choose(f - 1, i - 1);
	for (j = 1; j <= w; j++)
		bb[j] = choose(w - 1, j - 1);
	for (j = 1; h * j < w; j++)
		cc[j] = choose(w - h * j - 1, j - 1);
	p = q = 0;
	for (i = 1; i <= n; i++) {
		p = (p + aa[i] * (cc[i] * 2LL + cc[i - 1] + cc[i + 1])) % MD;
		q = (q + aa[i] * (bb[i] * 2LL + bb[i - 1] + bb[i + 1])) % MD;
	}
	ans = (long long) p * inv(q, MD) % MD;
	if (ans < 0)
		ans += MD;
	printf("%d\n", ans);
	return 0;
}


#include<stdio.h>
#define MOD 1000000007

long long mpow(long long a, long long p)
{
  a %= MOD;

  long long r = 1;
  while (p) {
    if ((1 & p)) r = (r * a) % MOD;
    a = (a * a) % MOD;
    p >>= 1;
  }
  return r;
}

int inv(long long x)
{ return mpow(x, MOD-2); }

#define MAXF 100005

int factorial[MAXF];

long long possib(long long width, long long boxes, long long minh)
{
  long long separators = width-1;
  long long elements = boxes-width*minh;

  if(elements < 0) return 0;
  else return (factorial[separators+elements]*inv(factorial[separators]*factorial[elements])) % MOD;
}

long long all_possib, nice_possib;
void add_all(long long x)
{
  x %= MOD;
  all_possib += x;
  all_possib %= MOD;
}
void add_nice(long long x)
{
  x %= MOD;
  nice_possib += x;
  nice_possib %= MOD;
}

int main()
{
  long long fac;
  int i;
  int result;

  i = 0;
  for(fac = 1; i<MAXF; fac = fac*i % MOD){
    factorial[i] = fac;
    i++;
  }

  int F, W, H, width;
  scanf("%d %d %d\n", &F, &W, &H);

  if(W == 0 || F == 0){
    if(W == 0 || W > H) printf("1\n");
    else printf("0\n");
    return 0;
  }

  all_possib = 0;
  nice_possib = 0;
  for(width=1; width<=W; width++){
    add_all(possib(width, F, 1)*possib(width, W, 1));
    add_all(possib(width+1, F, 1)*possib(width, W, 1));
    add_all(possib(width, W, 1)*possib(width, F, 1));
    add_all(possib(width+1, W, 1)*possib(width, F, 1));

    add_nice(possib(width, F, 1)*possib(width, W, H+1));
    add_nice(possib(width+1, F, 1)*possib(width, W, H+1));
    add_nice(possib(width, W, H+1)*possib(width, F, 1));
    add_nice(possib(width+1, W, H+1)*possib(width, F, 1));
  }
  result = nice_possib*inv(all_possib) % MOD;

  printf("%d\n", result);

  return 0;
}


/* practice with Dukkha */
#include <stdio.h>

#define N	100000
#define MD	1000000007

int ff[N], gg[N];
int d_, x_, y_;

void gcd_(int a, int b) {
	if (b == 0) {
		d_ = a;
		x_ = 1, y_ = 0;
	} else {
		int tmp;

		gcd_(b, a % b);
		tmp = x_ - a / b * y_, x_ = y_, y_ = tmp;
	}
}

int inv(int a, int b) {
	gcd_(a, b);
	return x_;
}

void init(int n) {
	int i, f;

	for (i = 0, f = 1; i < n; i++) {
		gg[i] = inv(ff[i] = f, MD);
		f = (long long) f * (i + 1) % MD;
	}
}

int choose(int n, int k) {
	return n < k ? 0 : (long long) ff[n] * gg[k] % MD * gg[n - k] % MD;
}

int main() {
	static int aa[N + 2], bb[N + 2], cc[N + 2];
	int f, w, h, n, i, j, p, q, ans;

	scanf("%d%d%d", &f, &w, &h);
	if (f == 0) {
		printf("%d\n", w > h);
		return 0;
	}
	if (w == 0) {
		printf("1\n");
		return 0;
	}
	n = f > w ? f : w;
	init(n);
	for (i = 1; i <= f; i++)
		aa[i] = choose(f - 1, i - 1);
	for (j = 1; j <= w; j++)
		bb[j] = choose(w - 1, j - 1);
	for (j = 1; h * j < w; j++)
		cc[j] = choose(w - h * j - 1, j - 1);
	p = q = 0;
	for (i = 1; i <= n; i++) {
		p = (p + aa[i] * (cc[i] * 2LL + cc[i - 1] + cc[i + 1])) % MD;
		q = (q + aa[i] * (bb[i] * 2LL + bb[i - 1] + bb[i + 1])) % MD;
	}
	if (p < 0)
		p += MD;
	if (q < 0)
		q += MD;
	ans = (long long) p * inv(q, MD) % MD;
	if (ans < 0)
		ans += MD;
	printf("%d\n", ans);
	return 0;
}


#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

#define N	900

double min(double a, double b) { return a < b ? a : b; }
double max(double a, double b) { return a > b ? a : b; }

void srand_() {
	struct timeval tv;

	gettimeofday(&tv, NULL);
	srand(tv.tv_sec ^ tv.tv_usec);
}

int rand_(int n) {
	return (rand() * 76543LL + rand()) % n;
}

long long dot3(int x1, int y1, int z1, int x2, int y2, int z2) {
	return (long long) x1 * x2 + (long long) y1 * y2 + (long long) z1 * z2;
}

double xx_[N], yy_[N];

int i1, i2, i3; double x_, y_, r_;

void circle() {
	double x1 = xx_[i1], y1 = yy_[i1], x2 = xx_[i2], y2 = yy_[i2], x3 = xx_[i3], y3 = yy_[i3];
	double a, b, c, d, e, f;

	if (x1 == x2 && y1 == y2 || x1 == x3 && y1 == y3 || x2 == x3 && y2 == y3) {
		x_ = (max(max(x1, x2), x3) + min(min(x1, x2), x3)) / 2;
		y_ = (max(max(y1, y2), y3) + min(min(y1, y2), y3)) / 2;
	} else {
		/* (x_ - x1)^2 + (y_ - y1)^2 = (x_ - x2)^2 + (y_ - y2)^2
		 * 2 (x1 - x2) x_ + 2 (y1 - y2) y_ = x1^2 + y1^2 - x2^2 - y2^2 */
		/* (x_ - x1)^2 + (y_ - y1)^2 = (x_ - x3)^2 + (y_ - y3)^2
		 * 2 (x1 - x3) x_ + 2 (y1 - y3) y_ = x1^2 + y1^2 - x3^2 - y3^2 */
		a = (x1 - x2) * 2, b = (y1 - y2) * 2, e = x1 * x1 + y1 * y1 - x2 * x2 - y2 * y2;
		c = (x1 - x3) * 2, d = (y1 - y3) * 2, f = x1 * x1 + y1 * y1 - x3 * x3 - y3 * y3;
		x_ = (e * d - b * f) / (a * d - b * c);
		y_ = (a * f - e * c) / (a * d - b * c);
	}
	r_ = hypot(x_ - x1, y_ - y1);
}

int ii[N];

void shuffle(int n) {
	int h;

	for (h = 0; h < n; h++) {
		int h_ = rand_(h + 1), tmp;

		tmp = ii[h], ii[h] = ii[h_], ii[h_] = tmp;
	}
}

void mec(int n, int k) {
	int h;

	shuffle(n);
	if (k == 0)
		i1 = i2 = i3 = ii[0];
	circle();
	for (h = k == 0 ? 1 : 0; h < n; h++) {
		int i = ii[h];
		double x = xx_[i], y = yy_[i];

		if ((x_ - x) * (x_ - x) + (y_ - y) * (y_ - y) > r_ * r_) {
			if (k < 2) {
				if (k == 0)
					i1 = i2 = i3 = i;
				else if (k == 1)
					i2 = i3 = i;
				mec(h, k + 1);
			} else
				i3 = i, circle();
		}
	}
}

int main() {
	static int xx[N], yy[N], zz[N];
	int n, m, i;

	srand_();
	scanf("%d%d", &n, &m);
	for (i = 0; i < n; i++)
		scanf("%d%d%d", &xx[i], &yy[i], &zz[i]);
	while (m--) {
		int ux, uy, uz, vx, vy, vz, wx, wy, wz;
		double vl, wl;

		scanf("%d%d%d", &ux, &uy, &uz);
		if (ux == 0)
			vx = 1, vy = 0, vz = 0;
		else
			vx = -uy, vy = ux, vz = 0;
		wx = uy * vz - vy * uz, wy = -(ux * vz - vx * uz), wz = ux * vy - vx * uy;
		vl = sqrt(dot3(vx, vy, vz, vx, vy, vz));
		wl = sqrt(dot3(wx, wy, wz, wx, wy, wz));
		for (i = 0; i < n; i++) {
			int x = xx[i], y = yy[i], z = zz[i];

			xx_[i] = dot3(x, y, z, vx, vy, vz) / vl;
			yy_[i] = dot3(x, y, z, wx, wy, wz) / wl;
		}
		for (i = 0; i < n; i++)
			ii[i] = i;
		mec(n, 0);
		circle();
		printf("%f\n", r_);
	}
	return 0;
}


#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

#define N	900

long double min(long double a, long double b) { return a < b ? a : b; }
long double max(long double a, long double b) { return a > b ? a : b; }

void srand_() {
	struct timeval tv;

	gettimeofday(&tv, NULL);
	srand(tv.tv_sec ^ tv.tv_usec);
}

int rand_(int n) {
	return (rand() * 76543LL + rand()) % n;
}

long long dot3(int x1, int y1, int z1, int x2, int y2, int z2) {
	return (long long) x1 * x2 + (long long) y1 * y2 + (long long) z1 * z2;
}

long double xx_[N], yy_[N];

int i1, i2, i3; long double x_, y_, r_;

void circle() {
	long double x1 = xx_[i1], y1 = yy_[i1], x2 = xx_[i2], y2 = yy_[i2], x3 = xx_[i3], y3 = yy_[i3];
	long double a, b, c, d, e, f;

	if (x1 == x2 && y1 == y2 || x1 == x3 && y1 == y3 || x2 == x3 && y2 == y3) {
		x_ = (max(max(x1, x2), x3) + min(min(x1, x2), x3)) / 2;
		y_ = (max(max(y1, y2), y3) + min(min(y1, y2), y3)) / 2;
	} else {
		/* (x_ - x1)^2 + (y_ - y1)^2 = (x_ - x2)^2 + (y_ - y2)^2
		 * 2 (x1 - x2) x_ + 2 (y1 - y2) y_ = x1^2 + y1^2 - x2^2 - y2^2 */
		/* (x_ - x1)^2 + (y_ - y1)^2 = (x_ - x3)^2 + (y_ - y3)^2
		 * 2 (x1 - x3) x_ + 2 (y1 - y3) y_ = x1^2 + y1^2 - x3^2 - y3^2 */
		a = (x1 - x2) * 2, b = (y1 - y2) * 2, e = x1 * x1 + y1 * y1 - x2 * x2 - y2 * y2;
		c = (x1 - x3) * 2, d = (y1 - y3) * 2, f = x1 * x1 + y1 * y1 - x3 * x3 - y3 * y3;
		x_ = (e * d - b * f) / (a * d - b * c);
		y_ = (a * f - e * c) / (a * d - b * c);
	}
	r_ = hypot(x_ - x1, y_ - y1);
}

int ii[N];

void shuffle(int n) {
	int h;

	for (h = 0; h < n; h++) {
		int h_ = rand_(h + 1), tmp;

		tmp = ii[h], ii[h] = ii[h_], ii[h_] = tmp;
	}
}

void mec(int n, int k) {
	int h;

	shuffle(n);
	if (k == 0)
		i1 = i2 = i3 = ii[0];
	circle();
	for (h = k == 0 ? 1 : 0; h < n; h++) {
		int i = ii[h];
		long double x = xx_[i], y = yy_[i];

		if ((x_ - x) * (x_ - x) + (y_ - y) * (y_ - y) > r_ * r_) {
			if (k < 2) {
				if (k == 0)
					i1 = i2 = i3 = i;
				else if (k == 1)
					i2 = i3 = i;
				mec(h, k + 1);
			} else
				i3 = i, circle();
		}
	}
}

int main() {
	static int xx[N], yy[N], zz[N];
	int n, m, i;

	srand_();
	scanf("%d%d", &n, &m);
	for (i = 0; i < n; i++)
		scanf("%d%d%d", &xx[i], &yy[i], &zz[i]);
	while (m--) {
		int ux, uy, uz, vx, vy, vz, wx, wy, wz;
		long double vl, wl;

		scanf("%d%d%d", &ux, &uy, &uz);
		if (ux == 0)
			vx = 1, vy = 0, vz = 0;
		else
			vx = -uy, vy = ux, vz = 0;
		wx = uy * vz - vy * uz, wy = -(ux * vz - vx * uz), wz = ux * vy - vx * uy;
		vl = sqrt(dot3(vx, vy, vz, vx, vy, vz));
		wl = sqrt(dot3(wx, wy, wz, wx, wy, wz));
		for (i = 0; i < n; i++) {
			int x = xx[i], y = yy[i], z = zz[i];

			xx_[i] = dot3(x, y, z, vx, vy, vz) / vl;
			yy_[i] = dot3(x, y, z, wx, wy, wz) / wl;
		}
		for (i = 0; i < n; i++)
			ii[i] = i;
		mec(n, 0);
		circle();
		printf("%f\n", r_);
	}
	return 0;
}


#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

#define N	900

long double min(long double a, long double b) { return a < b ? a : b; }
long double max(long double a, long double b) { return a > b ? a : b; }

void srand_() {
	struct timeval tv;

	gettimeofday(&tv, NULL);
	srand(tv.tv_sec ^ tv.tv_usec);
}

int rand_(int n) {
	return (rand() * 76543LL + rand()) % n;
}

long long dot3(int x1, int y1, int z1, int x2, int y2, int z2) {
	return (long long) x1 * x2 + (long long) y1 * y2 + (long long) z1 * z2;
}

long double xx_[N], yy_[N];

int i1, i2, i3; long double x_, y_, r_;

void circle() {
	long double x1 = xx_[i1], y1 = yy_[i1], x2 = xx_[i2], y2 = yy_[i2], x3 = xx_[i3], y3 = yy_[i3];
	long double a, b, c, d, e, f;

	if (x1 == x2 && y1 == y2 || x1 == x3 && y1 == y3 || x2 == x3 && y2 == y3) {
		x_ = (max(max(x1, x2), x3) + min(min(x1, x2), x3)) / 2;
		y_ = (max(max(y1, y2), y3) + min(min(y1, y2), y3)) / 2;
	} else {
		/* (x_ - x1)^2 + (y_ - y1)^2 = (x_ - x2)^2 + (y_ - y2)^2
		 * 2 (x1 - x2) x_ + 2 (y1 - y2) y_ = x1^2 + y1^2 - x2^2 - y2^2 */
		/* (x_ - x1)^2 + (y_ - y1)^2 = (x_ - x3)^2 + (y_ - y3)^2
		 * 2 (x1 - x3) x_ + 2 (y1 - y3) y_ = x1^2 + y1^2 - x3^2 - y3^2 */
		a = (x1 - x2) * 2, b = (y1 - y2) * 2, e = x1 * x1 + y1 * y1 - x2 * x2 - y2 * y2;
		c = (x1 - x3) * 2, d = (y1 - y3) * 2, f = x1 * x1 + y1 * y1 - x3 * x3 - y3 * y3;
		x_ = (e * d - b * f) / (a * d - b * c);
		y_ = (a * f - e * c) / (a * d - b * c);
	}
	r_ = hypotl(x_ - x1, y_ - y1);
}

int ii[N];

void shuffle(int n) {
	int h;

	for (h = 0; h < n; h++) {
		int h_ = rand_(h + 1), tmp;

		tmp = ii[h], ii[h] = ii[h_], ii[h_] = tmp;
	}
}

void mec(int n, int k) {
	int h;

	shuffle(n);
	if (k == 0)
		i1 = i2 = i3 = ii[0];
	circle();
	for (h = k == 0 ? 1 : 0; h < n; h++) {
		int i = ii[h];
		long double x = xx_[i], y = yy_[i];

		if ((x_ - x) * (x_ - x) + (y_ - y) * (y_ - y) > r_ * r_) {
			if (k < 2) {
				if (k == 0)
					i1 = i2 = i3 = i;
				else if (k == 1)
					i2 = i3 = i;
				mec(h, k + 1);
			} else
				i3 = i, circle();
		}
	}
}

int main() {
	static int xx[N], yy[N], zz[N];
	int n, m, i;

	srand_();
	scanf("%d%d", &n, &m);
	for (i = 0; i < n; i++)
		scanf("%d%d%d", &xx[i], &yy[i], &zz[i]);
	while (m--) {
		int ux, uy, uz, vx, vy, vz, wx, wy, wz;
		long double vl, wl;

		scanf("%d%d%d", &ux, &uy, &uz);
		if (ux == 0)
			vx = 1, vy = 0, vz = 0;
		else
			vx = -uy, vy = ux, vz = 0;
		wx = uy * vz - vy * uz, wy = -(ux * vz - vx * uz), wz = ux * vy - vx * uy;
		vl = sqrtl(dot3(vx, vy, vz, vx, vy, vz));
		wl = sqrtl(dot3(wx, wy, wz, wx, wy, wz));
		for (i = 0; i < n; i++) {
			int x = xx[i], y = yy[i], z = zz[i];

			xx_[i] = dot3(x, y, z, vx, vy, vz) / vl;
			yy_[i] = dot3(x, y, z, wx, wy, wz) / wl;
		}
		for (i = 0; i < n; i++)
			ii[i] = i;
		mec(n, 0);
		circle();
		printf("%Lf\n", r_);
	}
	return 0;
}


#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

#define N	900

long double min(long double a, long double b) { return a < b ? a : b; }
long double max(long double a, long double b) { return a > b ? a : b; }

void srand_() {
	struct timeval tv;

	gettimeofday(&tv, NULL);
	srand(tv.tv_sec ^ tv.tv_usec);
}

int rand_(int n) {
	return (rand() * 76543LL + rand()) % n;
}

long long dot3(int x1, int y1, int z1, int x2, int y2, int z2) {
	return (long long) x1 * x2 + (long long) y1 * y2 + (long long) z1 * z2;
}

long double xx_[N], yy_[N];

int i1, i2, i3; long double x_, y_, r_;

void circle() {
	long double x1 = xx_[i1], y1 = yy_[i1], x2 = xx_[i2], y2 = yy_[i2], x3 = xx_[i3], y3 = yy_[i3];
	long double a, b, c, d, e, f;

	if (x1 == x2 && y1 == y2 || x1 == x3 && y1 == y3 || x2 == x3 && y2 == y3) {
		x_ = (max(max(x1, x2), x3) + min(min(x1, x2), x3)) / 2;
		y_ = (max(max(y1, y2), y3) + min(min(y1, y2), y3)) / 2;
	} else {
		/* (x_ - x1)^2 + (y_ - y1)^2 = (x_ - x2)^2 + (y_ - y2)^2
		 * 2 (x1 - x2) x_ + 2 (y1 - y2) y_ = x1^2 + y1^2 - x2^2 - y2^2 */
		/* (x_ - x1)^2 + (y_ - y1)^2 = (x_ - x3)^2 + (y_ - y3)^2
		 * 2 (x1 - x3) x_ + 2 (y1 - y3) y_ = x1^2 + y1^2 - x3^2 - y3^2 */
		a = (x1 - x2) * 2, b = (y1 - y2) * 2, e = x1 * x1 + y1 * y1 - x2 * x2 - y2 * y2;
		c = (x1 - x3) * 2, d = (y1 - y3) * 2, f = x1 * x1 + y1 * y1 - x3 * x3 - y3 * y3;
		x_ = (e * d - b * f) / (a * d - b * c);
		y_ = (a * f - e * c) / (a * d - b * c);
	}
	r_ = hypot(x_ - x1, y_ - y1);
}

int ii[N];

void shuffle(int n) {
	int h;

	for (h = 0; h < n; h++) {
		int h_ = rand_(h + 1), tmp;

		tmp = ii[h], ii[h] = ii[h_], ii[h_] = tmp;
	}
}

void mec(int n, int k) {
	int h;

	shuffle(n);
	if (k == 0)
		i1 = i2 = i3 = ii[0];
	circle();
	for (h = k == 0 ? 1 : 0; h < n; h++) {
		int i = ii[h];
		long double x = xx_[i], y = yy_[i];

		if ((x_ - x) * (x_ - x) + (y_ - y) * (y_ - y) > r_ * r_) {
			if (k < 2) {
				if (k == 0)
					i1 = i2 = i3 = i;
				else if (k == 1)
					i2 = i3 = i;
				mec(h, k + 1);
			} else
				i3 = i, circle();
		}
	}
}

int main() {
	static int xx[N], yy[N], zz[N];
	int n, m, i;

	srand_();
	scanf("%d%d", &n, &m);
	for (i = 0; i < n; i++)
		scanf("%d%d%d", &xx[i], &yy[i], &zz[i]);
	while (m--) {
		int ux, uy, uz, vx, vy, vz, wx, wy, wz;
		long double vl, wl;

		scanf("%d%d%d", &ux, &uy, &uz);
		if (ux == 0)
			vx = 1, vy = 0, vz = 0;
		else
			vx = -uy, vy = ux, vz = 0;
		wx = uy * vz - vy * uz, wy = -(ux * vz - vx * uz), wz = ux * vy - vx * uy;
		vl = sqrt(dot3(vx, vy, vz, vx, vy, vz));
		wl = sqrt(dot3(wx, wy, wz, wx, wy, wz));
		for (i = 0; i < n; i++) {
			int x = xx[i], y = yy[i], z = zz[i];

			xx_[i] = dot3(x, y, z, vx, vy, vz) / vl;
			yy_[i] = dot3(x, y, z, wx, wy, wz) / wl;
		}
		for (i = 0; i < n; i++)
			ii[i] = i;
		mec(n, 0);
		circle();
		printf("%Lf\n", r_);
	}
	return 0;
}


#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

#define N	900

long double min(long double a, long double b) { return a < b ? a : b; }
long double max(long double a, long double b) { return a > b ? a : b; }

void srand_() {
	struct timeval tv;

	gettimeofday(&tv, NULL);
	srand(tv.tv_sec ^ tv.tv_usec);
}

int rand_(int n) {
	return (rand() * 76543LL + rand()) % n;
}

long long dot3(int x1, int y1, int z1, int x2, int y2, int z2) {
	return (long long) x1 * x2 + (long long) y1 * y2 + (long long) z1 * z2;
}

long double xx_[N], yy_[N];

int i1, i2, i3; long double x_, y_, r_;

void circle() {
	long double x1 = xx_[i1], y1 = yy_[i1], x2 = xx_[i2], y2 = yy_[i2], x3 = xx_[i3], y3 = yy_[i3];
	long double a, b, c, d, e, f;

	if (x1 == x2 && y1 == y2 || x1 == x3 && y1 == y3 || x2 == x3 && y2 == y3) {
		x_ = (max(max(x1, x2), x3) + min(min(x1, x2), x3)) / 2;
		y_ = (max(max(y1, y2), y3) + min(min(y1, y2), y3)) / 2;
	} else {
		/* (x_ - x1)^2 + (y_ - y1)^2 = (x_ - x2)^2 + (y_ - y2)^2
		 * 2 (x1 - x2) x_ + 2 (y1 - y2) y_ = x1^2 + y1^2 - x2^2 - y2^2 */
		/* (x_ - x1)^2 + (y_ - y1)^2 = (x_ - x3)^2 + (y_ - y3)^2
		 * 2 (x1 - x3) x_ + 2 (y1 - y3) y_ = x1^2 + y1^2 - x3^2 - y3^2 */
		a = (x1 - x2) * 2, b = (y1 - y2) * 2, e = x1 * x1 + y1 * y1 - x2 * x2 - y2 * y2;
		c = (x1 - x3) * 2, d = (y1 - y3) * 2, f = x1 * x1 + y1 * y1 - x3 * x3 - y3 * y3;
		x_ = (e * d - b * f) / (a * d - b * c);
		y_ = (a * f - e * c) / (a * d - b * c);
	}
	r_ = hypotl(x_ - x1, y_ - y1);
}

int ii[N];

void shuffle(int n) {
	int h;

	for (h = 0; h < n; h++) {
		int h_ = rand_(h + 1), tmp;

		tmp = ii[h], ii[h] = ii[h_], ii[h_] = tmp;
	}
}

void mec(int n, int k) {
	int h;

	shuffle(n);
	if (k == 0)
		i1 = i2 = i3 = ii[0];
	circle();
	for (h = k == 0 ? 1 : 0; h < n; h++) {
		int i = ii[h];
		long double x = xx_[i], y = yy_[i];

		if (hypotl(x_ - x, y_ - y) > r_) {
			if (k < 2) {
				if (k == 0)
					i1 = i2 = i3 = i;
				else if (k == 1)
					i2 = i3 = i;
				mec(h, k + 1);
			} else
				i3 = i, circle();
		}
	}
}

int main() {
	static int xx[N], yy[N], zz[N];
	int n, m, i;

	srand_();
	scanf("%d%d", &n, &m);
	for (i = 0; i < n; i++)
		scanf("%d%d%d", &xx[i], &yy[i], &zz[i]);
	while (m--) {
		int ux, uy, uz, vx, vy, vz, wx, wy, wz;
		long double vl, wl;

		scanf("%d%d%d", &ux, &uy, &uz);
		if (ux == 0)
			vx = 1, vy = 0, vz = 0;
		else
			vx = -uy, vy = ux, vz = 0;
		wx = uy * vz - vy * uz, wy = -(ux * vz - vx * uz), wz = ux * vy - vx * uy;
		vl = sqrtl(dot3(vx, vy, vz, vx, vy, vz));
		wl = sqrtl(dot3(wx, wy, wz, wx, wy, wz));
		for (i = 0; i < n; i++) {
			int x = xx[i], y = yy[i], z = zz[i];

			xx_[i] = dot3(x, y, z, vx, vy, vz) / vl;
			yy_[i] = dot3(x, y, z, wx, wy, wz) / wl;
		}
		for (i = 0; i < n; i++)
			ii[i] = i;
		mec(n, 0);
		circle();
		printf("%Lf\n", r_);
	}
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef int iii[3];

int main() {
	int i, j, n, m, cnt;
	static iii *ee;
	static int *aa;
	static char *s;

	scanf("%d%d", &n, &m);
	ee = calloc(n + 1, sizeof(*ee));
	aa = malloc(sizeof(*aa) * 4 * n);
	s = malloc((n + 2) * sizeof(*s));
	memset(s + 1, '0', n);
	s[n + 1] = '\0';
	while (m-- > 0) {
		int u, v;

		scanf("%d%d", &u, &v);
		for (j = 0; j < 3; j++)
			if (ee[u][j] == 0) {
				ee[u][j] = v;
				break;
			}
		for (j = 0; j < 3; j++)
			if (ee[v][j] == 0) {
				ee[v][j] = u;
				break;
			}
	}
	for (i = 0; i < n; i++)
		aa[i] = i + 1;
	cnt = n;
	while (cnt > 0) {
		int a, k;

		a = aa[--cnt];
		k = 0;
		for (j = 0; j < 3; j++)
			if (ee[a][j] > 0 && s[a] == s[ee[a][j]])
				k++;
		if (k > 1) {
			s[a] = s[a] == '1' ? '0' : '1';
			for (j = 0; j < 3; j++)
				if (ee[a][j] > 0)
					aa[cnt++] = ee[a][j];
		}
	}
	printf("%s\n", s + 1);
	return 0;
}


/* practice with Dukkha */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define N	50
#define A	26
#define N_	(1 + N + A + 1)
#define M_	(N + N * A + A)
#define INF	0x3f3f3f3f

int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }

int oo[1 + M_ * 2], oh[1 + M_ * 2];

int link(int o, int h) {
	static int _ = 1;

	oo[_] = o, oh[_] = h;
	return _++;
}

int ii[M_], jj[M_], cc[M_ * 2], ww[M_], ww_[M_], m_;
int ae[N_], dd[N_], kk[N_], ff[N_], n_;
int pq[1 + N_], iq[N_], cnt;

void link_(int i, int j, int c, int w) {
	int h = m_++;

	ii[h] = i, jj[h] = j, cc[h << 1] = c;
	ww[h] = w;
	ae[i] = link(ae[i], h << 1);
	ae[j] = link(ae[j], h << 1 | 1);
}

int less(int u, int v) {
	return dd[u] < dd[v] || dd[u] == dd[v] && kk[u] < kk[v];
}

int i2(int i) {
	return (i *= 2) > cnt ? 0 : i < cnt && less(pq[i + 1], pq[i]) ? i + 1 : i;
}

void pq_up(int u) {
	int i, j, v;

	for (i = iq[u]; (j = i / 2) && less(u, v = pq[j]); i = j)
		pq[iq[v] = i] = v;
	pq[iq[u] = i] = u;
}

void pq_dn(int u) {
	int i, j, v;

	for (i = iq[u]; (j = i2(i)) && less(v = pq[j], u); i = j)
		pq[iq[v] = i] = v;
	pq[iq[u] = i] = u;
}

void pq_add_last(int u) {
	pq[iq[u] = ++cnt] = u;
}

int pq_remove_first() {
	int u = pq[1], v = pq[cnt--];

	if (v != u)
		iq[v] = 1, pq_dn(v);
	iq[u] = 0;
	return u;
}

int dijkstra(int s, int t) {
	memset(dd, 0x3f, n_ * sizeof *dd);
	dd[s] = 0, pq_add_last(s);
	while (cnt) {
		int i, k, o;

		i = pq_remove_first();
		k = kk[i] + 1;
		for (o = ae[i]; o; o = oo[o]) {
			int h_ = oh[o];

			if (cc[h_] > 0) {
				int h = h_ >> 1, j = i ^ ii[h] ^ jj[h];
				int d = dd[i] + ((h_ & 1) == 0 ? ww_[h] : -ww_[h]);

				if (dd[j] > d || dd[j] == d && kk[j] > k) {
					if (dd[j] == INF)
						pq_add_last(j);
					dd[j] = d, kk[j] = k, ff[j] = h_;
					pq_up(j);
				}
			}
		}
	}
	return dd[t] != INF;
}

int trace(int s, int t) {
	while (t != s) {
		int h_ = ff[t], h = h_ >> 1;

		cc[h_]--, cc[h_ ^ 1]++;
		t ^= ii[h] ^ jj[h];
	}
	return 1;
}

int edmonds_karp(int s, int t) {
	int h, f, cost;

	for (h = 0; h < m_; h++) {
		int i = ii[h], j = jj[h];

		dd[j] = min(dd[j], dd[i] + ww[h]);
	}
	for (h = 0; h < m_; h++) {
		int i = ii[h], j = jj[h];

		ww_[h] = ww[h] + dd[i] - dd[j];
	}
	f = 0;
	while (dijkstra(s, t)) {
		f += trace(s, t);
		for (h = 0; h < m_; h++) {
			int i = ii[h], j = jj[h];

			if (dd[i] != INF && dd[j] != INF) {
				/* dd[j] <= dd[i] + ww_[h] */
				/* ww_[h] + dd[i] - dd[j] >= 0 */
				ww_[h] += dd[i] - dd[j];
			}
		}
	}
	cost = 0;
	for (h = 0; h < m_; h++)
		cost += ww[h] * cc[h << 1 | 1];
	return cost;
}

int main() {
	static char cc[N * 2 + 1];
	static int bb[N * 2], kk[A];
	int n, i, a;

	scanf("%d%s", &n, cc), n /= 2;
	n_ = 1 + n + A + 1;
	for (i = 0; i < n * 2; i++)
		scanf("%d", &bb[i]);
	for (i = 0; i < n; i++)
		link_(0, 1 + i, 2, 0);
	for (i = 0; i < n; i++) {
		int j = n * 2 - 1 - i;
		int ai = cc[i] - 'a';
		int aj = cc[j] - 'a';

		for (a = 0; a < A; a++) {
			int b;

			if (a == ai && a == aj)
				b = max(bb[i], bb[j]);
			else if (a == ai)
				b = bb[i];
			else if (a == aj)
				b = bb[j];
			else
				b = 0;
			link_(1 + i, 1 + n + a, 1, -b);
		}
	}
	for (i = 0; i < n * 2; i++) {
		a = cc[i] - 'a';
		kk[a]++;
	}
	for (a = 0; a < A; a++)
		link_(1 + n + a, n_ - 1, kk[a], 0);
	printf("%d\n", -edmonds_karp(0, n_ - 1));
	return 0;
}


/* practice with Dukkha */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define N	50
#define A	26
#define N_	(1 + N + A + 1)
#define M_	(N + N * A + A)
#define INF	0x3f3f3f3f

int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }

int oo[1 + M_ * 2], oh[1 + M_ * 2];

int link(int o, int h) {
	static int _ = 1;

	oo[_] = o, oh[_] = h;
	return _++;
}

int ii[M_], jj[M_], cc[M_ * 2], cost[M_], cost_[M_], m_;
int ae[N_], pi[N_], dd[N_], ff[N_], n_;
int pq[1 + N_], iq[N_], cnt;

void link_(int i, int j, int c, int co) {
	int h = m_++;

	ii[h] = i, jj[h] = j, cc[h << 1] = c;
	cost[h] = co;
	ae[i] = link(ae[i], h << 1);
	ae[j] = link(ae[j], h << 1 | 1);
}

int less(int u, int v) {
	return pi[u] < pi[v] || pi[u] == pi[v] && dd[u] < dd[v];
}

int i2(int i) {
	return (i *= 2) > cnt ? 0 : i < cnt && less(pq[i + 1], pq[i]) ? i + 1 : i;
}

void pq_up(int u) {
	int i, j, v;

	for (i = iq[u]; (j = i / 2) && less(u, v = pq[j]); i = j)
		pq[iq[v] = i] = v;
	pq[iq[u] = i] = u;
}

void pq_dn(int u) {
	int i, j, v;

	for (i = iq[u]; (j = i2(i)) && less(v = pq[j], u); i = j)
		pq[iq[v] = i] = v;
	pq[iq[u] = i] = u;
}

void pq_add_last(int u) {
	pq[iq[u] = ++cnt] = u;
}

int pq_remove_first() {
	int u = pq[1], v = pq[cnt--];

	if (v != u)
		iq[v] = 1, pq_dn(v);
	iq[u] = 0;
	return u;
}

int dijkstra(int s, int t) {
	memset(pi, 0x3f, n_ * sizeof *pi);
	pi[s] = 0, pq_add_last(s);
	while (cnt) {
		int i, d, o;

		i = pq_remove_first();
		d = dd[i] + 1;
		for (o = ae[i]; o; o = oo[o]) {
			int h_ = oh[o];

			if (cc[h_] > 0) {
				int h = h_ >> 1, j = i ^ ii[h] ^ jj[h];
				int p = pi[i] + ((h_ & 1) == 0 ? cost_[h] : -cost_[h]);

				if (pi[j] > p || pi[j] == p && dd[j] > d) {
					if (pi[j] == INF)
						pq_add_last(j);
					pi[j] = p, dd[j] = d, ff[j] = h_;
					pq_up(j);
				}
			}
		}
	}
	return pi[t] != INF;
}

int trace(int s, int t) {
	while (t != s) {
		int h_ = ff[t], h = h_ >> 1;

		cc[h_]--, cc[h_ ^ 1]++;
		t ^= ii[h] ^ jj[h];
	}
	return 1;
}

int edmonds_karp(int s, int t) {
	int h, f, ans;

	for (h = 0; h < m_; h++) {
		int i = ii[h], j = jj[h];

		pi[j] = min(pi[j], pi[i] + cost[h]);
	}
	for (h = 0; h < m_; h++) {
		int i = ii[h], j = jj[h];

		cost_[h] = cost[h] + pi[i] - pi[j];
	}
	f = 0;
	while (dijkstra(s, t)) {
		f += trace(s, t);
		for (h = 0; h < m_; h++) {
			int i = ii[h], j = jj[h];

			if (pi[i] != INF && pi[j] != INF) {
				/* pi[j] <= pi[i] + cost_[h] */
				/* cost_[h] + pi[i] - pi[j] >= 0 */
				cost_[h] += pi[i] - pi[j];
			}
		}
	}
	ans = 0;
	for (h = 0; h < m_; h++)
		ans += cc[h << 1 | 1] * cost[h];
	return ans;
}

int main() {
	static char cc[N * 2 + 1];
	static int bb[N * 2], kk[A];
	int n, i, a;

	scanf("%d%s", &n, cc), n /= 2;
	n_ = 1 + n + A + 1;
	for (i = 0; i < n * 2; i++)
		scanf("%d", &bb[i]);
	for (i = 0; i < n; i++)
		link_(0, 1 + i, 2, 0);
	for (i = 0; i < n; i++) {
		int j = n * 2 - 1 - i;
		int ai = cc[i] - 'a';
		int aj = cc[j] - 'a';

		for (a = 0; a < A; a++) {
			int b;

			if (a == ai && a == aj)
				b = max(bb[i], bb[j]);
			else if (a == ai)
				b = bb[i];
			else if (a == aj)
				b = bb[j];
			else
				b = 0;
			link_(1 + i, 1 + n + a, 1, -b);
		}
	}
	for (i = 0; i < n * 2; i++) {
		a = cc[i] - 'a';
		kk[a]++;
	}
	for (a = 0; a < A; a++)
		link_(1 + n + a, n_ - 1, kk[a], 0);
	printf("%d\n", -edmonds_karp(0, n_ - 1));
	return 0;
}