import java.io.*;
import java.util.*;

public class B {

    long n, c0, c1;

    public void solve() {
        n = in.nextInt() - 1;
        c0 = in.nextInt();
        c1 = in.nextInt();
        if (c0 > c1) {
            long tmp = c0;
            c0 = c1;
            c1 = tmp;
        }

        if (c0 == 0) {
            out.println(1L * n * (c0 + c1));
            return;
        }

        long left = 0, right = (long) 5e17;

        while (left < right - 1) {
            long mid = (left + right) >>> 1;

            long[] calc = calc(mid);
            if (calc[0] < n) {
                left = mid;
            } else {
                right = mid;
            }
        }
        System.err.println(left);
        long[] calc2 = calc(left);

        long result = calc2[1] + (n - calc2[0]) * (left + 1);
        result += 1L * n * (c0 + c1);
        out.println(result);
    }

    long[] calc(long x) {
        long count = 0, sum = 0;
        for (long j = 0; c1 * j <= x; j++) {
            long maxI = (x - c1 * j) / c0;
            if (j == 0) {
                count += (maxI + 1);
                sum += c0 * maxI * (maxI + 1) / 2;
            } else {
                long curChoose = 1;
                for (long i = 0; i * c0 + j * c1 <= x; i++) {
                    if (i > 0) {
                        curChoose *= (i + j);
                        curChoose /= i;
                    }
                    count += curChoose;
                    sum += curChoose * (i * c0 + j * c1);
                    if (count >= n) {
                        return new long[]{count, sum};
                    }
                }
            }
        }
        return new long[]{count, sum};
    }

    public void run() {
        in = new FastScanner();
        out = new PrintWriter(System.out);
        solve();
        out.close();
    }

    FastScanner in;
    PrintWriter out;

    class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner(String fileName) {
            try {
                br = new BufferedReader(new FileReader(fileName));
            } catch (FileNotFoundException e) {
            }
        }

        public FastScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String nextToken() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(nextToken());
        }

        long nextLong() {
            return Long.parseLong(nextToken());
        }

        double nextDouble() {
            return Double.parseDouble(nextToken());
        }
    }

    public static void main(String[] args) {
        new B().run();
    }
}


import java.io.*;
import java.util.*;

public class Codeforces
{
    public static void main(String args[])throws Exception
    {
        BufferedReader bu=new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb=new StringBuilder();
        String s[]=bu.readLine().split(" ");
        int n=Integer.parseInt(s[0]);
        int i; double p=Double.parseDouble(s[1]);

        for(i=0;i<=n;i++)
        if(probab(n,i)>=p) break;
        System.out.println(i);
    }

    static int ncr(int n,int r)
    {
        if(r>n) return 0;
        int ans=1,i;
        for(i=n;i>n-r;i--) ans*=i;
        for(i=2;i<=r;i++) ans/=i;
        return ans;
    }

    static double probab(int n,int x)
    {
        int a=ncr(x,3)*ncr(n-x,0);
        int b=ncr(x,2)*ncr(n-x,1);
        int c=ncr(x,1)*ncr(n-x,2);
        return 1.0*((3.0/6)*c+a+b)/ncr(n,3);
    }
}


import java.io.*;
import java.util.Locale;
import java.util.Scanner;

/**
 * Author: Sergey Paramonov
 * Date: 27.07.14
 * Time: 19:47
 */
public class MemSQL_20140727_C {

    Scanner scanner = new Scanner(System.in);
    BufferedReader buffered = new BufferedReader(new InputStreamReader(System.in));
    StreamTokenizer input = new StreamTokenizer(buffered);

    static PrintWriter output = new PrintWriter(new BufferedOutputStream(System.out));

    int nextInt() throws Exception {
        input.nextToken();
        return (int) input.nval;
    }

    static void flushAndClose() {
        output.flush();
        System.out.flush();
        output.close();
    }

    void main() throws Exception {
        double n = nextInt();
        double m = nextInt();
        double ans = 1.0/n;
        if (m > 1) {
            ans += (1.0 - 1.0/n) * (m-1.0)/(n*m - 1.0);
        }
        System.out.printf(Locale.ENGLISH, "%.10f", ans);
    }

    public static void main(String[] args) throws Exception {
        new MemSQL_20140727_C().main();
        flushAndClose();
    }

}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author dmytro.prytula
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        DTriFiguri solver = new DTriFiguri();
        solver.solve(1, in, out);
        out.close();
    }

    static class DTriFiguri {
        static int N;
        int M = 305;
        int INF = (int) 1e9;
        DTriFiguri.Point[] possibleKnight = new DTriFiguri.Point[]{
                DTriFiguri.Point.of(2, 1),
                DTriFiguri.Point.of(-2, 1),
                DTriFiguri.Point.of(2, -1),
                DTriFiguri.Point.of(-2, -1),
                DTriFiguri.Point.of(1, 2),
                DTriFiguri.Point.of(-1, 2),
                DTriFiguri.Point.of(1, -2),
                DTriFiguri.Point.of(-1, -2)
        };
        DTriFiguri.Point[][] dist = new DTriFiguri.Point[M][M];

        {

        }

        private boolean in(DTriFiguri.Point p) {
            return 0 <= p.x && p.x < N && 0 <= p.y && p.y < N;
        }

        public void solve(int testNumber, InputReader in, PrintWriter out) {

            N = in.nextInt();
            DTriFiguri.Point[] pos = new DTriFiguri.Point[N * N];
            int[][] A = new int[N][N];
            for (int x = 0; x < N; x++) {
                for (int y = 0; y < N; y++) {
                    A[x][y] = in.nextInt() - 1;
                    pos[A[x][y]] = DTriFiguri.Point.of(x, y);

                }
            }

            for (int i = 0; i < M; i++) {
                for (int j = 0; j < M; j++) {
//                Arrays.fill(dist[i], Point.of(INF, INF));
                    dist[i][j] = DTriFiguri.Point.of(INF, INF);
                }
            }
            for (int i = 0; i < M; i++)
//            for (int j = 0; j < M; j++)
//                if (i == j)
                dist[i][i] = DTriFiguri.Point.of(0, 0);

            for (int x = 0; x < N; x++) {
                for (int y = 0; y < N; y++) {
                    //knight
                    for (int i = 0; i < possibleKnight.length; i++) {
                        int nx = x + possibleKnight[i].x;
                        int ny = y + possibleKnight[i].y;
                        if (in(DTriFiguri.Point.of(nx, ny))) {
                            dist[DTriFiguri.Point.hash(x, y, 0)][DTriFiguri.Point.hash(nx, ny, 0)] = DTriFiguri.Point.of(1, 0);
                        }
                    }
                    //bishop
                    for (int i = -N + 1; i <= N - 1; i++) {
                        int nx = x + i;
                        int ny = y + i;
                        if (in(DTriFiguri.Point.of(nx, ny)))
                            dist[DTriFiguri.Point.hash(x, y, 1)][DTriFiguri.Point.hash(nx, ny, 1)] = DTriFiguri.Point.of(1, 0);

                        ny = y - i;
                        if (in(DTriFiguri.Point.of(nx, ny)))
                            dist[DTriFiguri.Point.hash(x, y, 1)][DTriFiguri.Point.hash(nx, ny, 1)] = DTriFiguri.Point.of(1, 0);
                    }

                    //rook
                    for (int i = 0; i < N; i++) {
                        int nx = i;
                        int ny = y;
//                    if (in(Point.of(nx, ny)))
                        dist[DTriFiguri.Point.hash(x, y, 2)][DTriFiguri.Point.hash(nx, ny, 2)] = DTriFiguri.Point.of(1, 0);
                        nx = x;
                        ny = i;
//                    if (in(Point.of(nx, ny)))
                        dist[DTriFiguri.Point.hash(x, y, 2)][DTriFiguri.Point.hash(nx, ny, 2)] = DTriFiguri.Point.of(1, 0);

                    }

                    for (int i = 0; i < 3; i++) {
                        for (int j = 0; j < 3; j++) {
                            if (i != j) {
                                dist[DTriFiguri.Point.hash(x, y, i)][DTriFiguri.Point.hash(x, y, j)] = DTriFiguri.Point.of(1, 1);
                            }
                        }
                    }

                }
            }

            for (int k = 0; k < M; k++) {
                for (int i = 0; i < M; i++) {
                    for (int j = 0; j < M; j++) {
                        dist[i][j] = DTriFiguri.Point.min(dist[i][j], DTriFiguri.Point.sum(dist[i][k], dist[k][j]));
                    }
                }
            }

            DTriFiguri.Point[][] dp = new DTriFiguri.Point[N * N][3];
            for (int i = 0; i < N * N; i++) {
                for (int j = 0; j < 3; j++) {
                    dp[i][j] = DTriFiguri.Point.of(INF, INF);
                }
            }

            dp[0][0] = dp[0][1] = dp[0][2] = DTriFiguri.Point.of(0, 0);

            for (int i = 0; i < N * N - 1; i++)
                for (int j = 0; j < 3; j++)
                    for (int k = 0; k < 3; k++)
                        dp[i + 1][k] = DTriFiguri.Point.min(
                                dp[i + 1][k],
                                DTriFiguri.Point.sum(dp[i][j], dist[DTriFiguri.Point.hash(pos[i].x, pos[i].y, j)][DTriFiguri.Point.hash(pos[i + 1].x, pos[i + 1].y, k)])
                        );

            DTriFiguri.Point ans = DTriFiguri.Point.of(INF, INF);
            ans = DTriFiguri.Point.min(ans, dp[N * N - 1][0]);
            ans = DTriFiguri.Point.min(ans, dp[N * N - 1][1]);
            ans = DTriFiguri.Point.min(ans, dp[N * N - 1][2]);

            out.print(ans.toString());
        }

        private static class Point {
            int x;
            int y;

            private Point(int x, int y) {
                this.x = x;
                this.y = y;
            }

            public static DTriFiguri.Point of(int x, int y) {
                return new DTriFiguri.Point(x, y);
            }

            public static int hash(int x, int y, int p) {
                return x * N * 3 + y * 3 + p;
            }

            public static DTriFiguri.Point min(DTriFiguri.Point a, DTriFiguri.Point b) {
                if (a.x == b.x) {
                    return a.y < b.y ? a : b;
                }
                return a.x < b.x ? a : b;
            }

            public static DTriFiguri.Point sum(DTriFiguri.Point point1, DTriFiguri.Point point) {
                return DTriFiguri.Point.of(point1.x + point.x, point1.y + point.y);
            }

            public String toString() {
                return x + " " + y;
            }

        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String nextToken() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(nextToken());
        }

    }
}


// practice with rainboy
import java.io.*;
import java.util.*;

public class CF513C extends PrintWriter {
	CF513C() { super(System.out, true); }
	Scanner sc = new Scanner(System.in);
	public static void main(String[] $) {
		CF513C o = new CF513C(); o.main(); o.flush();
	}

	double prob(int l, int r, int a) {
		return Math.max(r - Math.max(l, a) + 1, 0) / (r - l + 1.0);
	}
	void main() {
		int n = sc.nextInt();
		int[] ll = new int[n];
		int[] rr = new int[n];
		for (int i = 0; i < n; i++) {
			ll[i] = sc.nextInt();
			rr[i] = sc.nextInt();
		}
		double ans = 0;
		for (int a = 1; a <= 10000; a++) {
			double p = 1;
			for (int j = 0; j < n; j++)
				p *= 1 - prob(ll[j], rr[j], a);
			double q = p;
			for (int i = 0; i < n; i++) {
				p = prob(ll[i], rr[i], a);
				for (int j = 0; j < n; j++)
					if (j != i)
						p *= 1 - prob(ll[j], rr[j], a);
				q += p;
			}
			ans += 1 - q;
		}
		printf("%.9f\n", ans);
	}
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		FastScanner in = new FastScanner(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskD solver = new TaskD();
		solver.solve(1, in, out);
		out.close();
	}

	static class TaskD {
		public void solve(int testNumber, FastScanner in, PrintWriter out) {
			long n = in.nextLong();
			long inputL = in.nextLong() - 1;
			long inputR = in.nextLong() - 1;
			long k = in.nextLong();
			long d = dist(inputL, inputR, n);

			final long BIG = (long) 3e5;
			long ans = -1;
			if (n >= BIG) {
//		if (true) {
//		if (false) {
				// c full circles.
				for (long c = 0; n * c <= k; c++) {
					long l = -1;
					long r = n + 1;
					while (r - l > 1) {
						long m = l + (r - l) / 2;
						if (canLB(n, k, d, c, m)) {
							l = m;
						} else {
							r = m;
						}
					}
					if (l >= 0 && canUB(n, k, d, c, l)) {
						ans = Math.max(ans, l);
					}
				}
			} else {
				// s sweet lovers.
				for (long s = 0; s <= n; s++) {
					long minC = 0;
					long maxC = 0;
					{
						long b = Math.min(d, n - s);
						long a = d - b;
						long p = k - a - d;
						if (a > 0) {
							++p;
						}
						if (p < 0) {
							continue;
						}
						maxC = p / (n + s);
					}
					{
						long a = Math.min(d, s);
						long b = d - a;
						long p = k - a - d;
						p += n + s - 1;
						if (p < 0) {
							continue;
						}
						minC = p / (n + s);
					}
					if (minC <= maxC) {
						ans = Math.max(ans, s);
					}
				}
			}
			out.println(ans);
		}

		private boolean canLB(long n, long k, long d, long c, long s) {
			long minK = -1;
			long b = Math.min(d, n - s);
			long a = d - b;
			minK = (n + s) * c + d + a;
			if (a > 0 && minK > 0) {
				// Last "a" takes one.
				--minK;
			}
			return k >= minK;
		}

		private boolean canUB(long n, long k, long d, long c, long s) {
			long maxK = -1;
			long a = Math.min(d, s);
			long b = d - a;
			maxK = (n + s) * c + d + a;
			return k <= maxK;
		}

		private long dist(long l, long r, long n) {
			while (r < l) {
				r += n;
			}
			return r - l + 1;
		}

	}

	static class FastScanner {
		private BufferedReader in;
		private StringTokenizer st;

		public FastScanner(InputStream stream) {
			in = new BufferedReader(new InputStreamReader(stream));
		}

		public String next() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					String rl = in.readLine();
					if (rl == null) {
						return null;
					}
					st = new StringTokenizer(rl);
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
			return st.nextToken();
		}

		public long nextLong() {
			return Long.parseLong(next());
		}

	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.stream.IntStream;

public class d {
    public static void main(String[] args) {
        FS in = new FS(System.in);
        PrintWriter out = new PrintWriter(System.out);

        new d().solve(in, out);

        out.close();
    }

    public void solve(FS in, PrintWriter out) {
        int x1 = in.nextInt();
        int x2 = in.nextInt();
        int d = x2-x1;
        int a = in.nextInt();
        int b = in.nextInt();
        if(Integer.signum(a) != Integer.signum(b)) {
            if(d >= a && d <= b) {
                System.out.println("FIRST");
                System.out.println(x2);
            } else {
                System.out.println("DRAW");
            }
            return;
        }
        int has = 1;
        if(a < 0) {
            a *= -1;
            b *= -1;
            d *= -1;
            has *= -1;
            a ^= b;
            b ^= a;
            a ^= b;
        }
        if(b == 0) {
            System.out.println("DRAW");
            return;
        }
        if(d < 0) {
            System.out.println("DRAW");
            return;
        }

        if(d%(a+b) == 0) {
            System.out.println("SECOND");
            return;
        }

        if(d%(a+b) < a || d%(a+b) > b) {
            System.out.println("DRAW");
            return;
        }

        System.out.println("FIRST");
        System.out.println(x1+has*(d%(a+b)));
    }

    static class FS {

        BufferedReader in;
        StringTokenizer token;

        public FS(InputStream str) {
            in = new BufferedReader(new InputStreamReader(str));
        }

        public String next() {
            if (token == null || !token.hasMoreElements()) {
                try {
                    token = new StringTokenizer(in.readLine());
                } catch (IOException ex) {
                }
                return next();
            }
            return token.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }
    }
}


/**
 * BaZ :D
 */
import java.util.*;
import java.io.*;
import static java.lang.Math.*;
public class ACMIND
{
    static FastReader scan;
    static PrintWriter pw;
    static long MOD = 1_000_000_007;
    static long INF = 1_000_000_000_000_000_000L;
    static long inf = 2_000_000_000;
    public static void main(String[] args) {
        new Thread(null,null,"BaZ",1<<25)
        {
            public void run()
            {
                try
                {
                    solve();
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                    System.exit(1);
                }
            }
        }.start();
    }
    static int n, g[], t[], T;
    static int dp[][];
    static void solve() throws IOException
    {
        scan = new FastReader();
        pw = new PrintWriter(System.out,true);
        StringBuilder fast = new StringBuilder();
        n = ni();
        T = ni();
        g = new int[n];
        t = new int[n];
        for(int i=0;i<n;++i) {
            t[i] = ni();
            g[i] = ni();
        }
        int MAX = (1<<n);
        dp = new int[MAX][4];
        for(int i=0;i<MAX;++i) {
            for(int j=0;j<4;++j) {
                dp[i][j] = -1;
            }
        }
        pl(f((1<<n)-1,0));
        pw.flush();
        pw.close();
    }

    static int f(int mask, int prev) {
        if(dp[mask][prev]!=-1) {
            return dp[mask][prev];
        }
        int left = T;
        for(int i=0;i<n;++i) {
            if((mask&(1<<i))==0) {
                left-=t[i];
            }
        }
        if(left==0) {
            return 1;
        }
        int cnt = 0;
        for(int i=0;i<n;++i) {
            if((mask&(1<<i))!=0) {
                if(g[i]!=prev && left>=t[i]) {
                    cnt+=f(mask^(1<<i), g[i]);
                    if(cnt>=MOD) {
                        cnt-=MOD;
                    }
                }
            }
        }
        return dp[mask][prev] = cnt;
    }
    static int ni() throws IOException
    {
        return scan.nextInt();
    }
    static long nl() throws IOException
    {
        return scan.nextLong();
    }
    static double nd() throws IOException
    {
        return scan.nextDouble();
    }
    static void pl()
    {
        pw.println();
    }
    static void p(Object o)
    {
        pw.print(o+" ");
    }
    static void pl(Object o)
    {
        pw.println(o);
    }
    static void psb(StringBuilder sb)
    {
        pw.print(sb);
    }
    static void pa(String arrayName, Object arr[])
    {
        pl(arrayName+" : ");
        for(Object o : arr)
            p(o);
        pl();
    }
    static void pa(String arrayName, int arr[])
    {
        pl(arrayName+" : ");
        for(int o : arr)
            p(o);
        pl();
    }
    static void pa(String arrayName, long arr[])
    {
        pl(arrayName+" : ");
        for(long o : arr)
            p(o);
        pl();
    }
    static void pa(String arrayName, double arr[])
    {
        pl(arrayName+" : ");
        for(double o : arr)
            p(o);
        pl();
    }
    static void pa(String arrayName, char arr[])
    {
        pl(arrayName+" : ");
        for(char o : arr)
            p(o);
        pl();
    }
    static void pa(String listName, List list)
    {
        pl(listName+" : ");
        for(Object o : list)
            p(o);
        pl();
    }
    static void pa(String arrayName, Object[][] arr) {
        pl(arrayName+" : ");
        for(int i=0;i<arr.length;++i) {
            for(Object o : arr[i])
                p(o);
            pl();
        }
    }
    static void pa(String arrayName, int[][] arr) {
        pl(arrayName+" : ");
        for(int i=0;i<arr.length;++i) {
            for(int o : arr[i])
                p(o);
            pl();
        }
    }
    static void pa(String arrayName, long[][] arr) {
        pl(arrayName+" : ");
        for(int i=0;i<arr.length;++i) {
            for(long o : arr[i])
                p(o);
            pl();
        }
    }
    static void pa(String arrayName, char[][] arr) {
        pl(arrayName+" : ");
        for(int i=0;i<arr.length;++i) {
            for(char o : arr[i])
                p(o);
            pl();
        }
    }
    static void pa(String arrayName, double[][] arr) {
        pl(arrayName+" : ");
        for(int i=0;i<arr.length;++i) {
            for(double o : arr[i])
                p(o);
            pl();
        }
    }
    static class FastReader {
        final private int BUFFER_SIZE = 1 << 16;
        private DataInputStream din;
        private byte[] buffer;
        private int bufferPointer, bytesRead;

        public FastReader() {
            din = new DataInputStream(System.in);
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public FastReader(String file_name) throws IOException {
            din = new DataInputStream(new FileInputStream(file_name));
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public String readLine() throws IOException {
            byte[] buf = new byte[1000000];
            int cnt = 0, c;
            while ((c = read()) != -1) {
                if (c == '\n') break;
                buf[cnt++] = (byte) c;
            }
            return new String(buf, 0, cnt);
        }

        public int nextInt() throws IOException {
            int ret = 0;
            byte c = read();
            while (c <= ' ') c = read();
            boolean neg = (c == '-');
            if (neg) c = read();
            do {
                ret = ret * 10 + c - '0';
            } while ((c = read()) >= '0' && c <= '9');
            if (neg) return -ret;
            return ret;
        }

        public long nextLong() throws IOException {
            long ret = 0;
            byte c = read();
            while (c <= ' ') c = read();
            boolean neg = (c == '-');
            if (neg) c = read();
            do {
                ret = ret * 10 + c - '0';
            } while ((c = read()) >= '0' && c <= '9');
            if (neg) return -ret;
            return ret;
        }

        public double nextDouble() throws IOException {
            double ret = 0, div = 1;
            byte c = read();
            while (c <= ' ') c = read();
            boolean neg = (c == '-');
            if (neg) c = read();
            do {
                ret = ret * 10 + c - '0';
            } while ((c = read()) >= '0' && c <= '9');
            if (c == '.') while ((c = read()) >= '0' && c <= '9') ret += (c - '0') / (div *= 10);
            if (neg) return -ret;
            return ret;
        }

        private void fillBuffer() throws IOException {
            bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
            if (bytesRead == -1) buffer[0] = -1;
        }

        private byte read() throws IOException {
            if (bufferPointer == bytesRead) fillBuffer();
            return buffer[bufferPointer++];
        }

        public void close() throws IOException {
            if (din == null) return;
            din.close();
        }
    }
}


import java.io.*;

/**
 * Codeforces Beta Round #72 (Div. 1 Only), D
 * @author Roman Kosenko <madkite@gmail.com>
 */
public class Main {
	public static void main(String... args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] ss = br.readLine().split(" ");
		int a = Integer.parseInt(ss[0]), b = Integer.parseInt(ss[1]), k = Integer.parseInt(ss[2]), result = !Utils.isPrime(k) ? 0 : solve(a, b, k);
		System.out.println(result);
	}
	private static int primes[];
	private static int solve(int a, int b, int k) {
		final int start = (a - 1) / k + 1, end = b / k;
		if(end < start)
			return 0;
		if(start == 1 && end == 1)
			return 1;
		if(primes == null)
			primes = Utils.primes(Math.min(k - 1, end), 0);
		int result = end - start + 1;
		for(int i = 0; i < primes.length && primes[i] < k; i++)
			result -= solve(start, end, primes[i]);
		return result;
	}
}
/**
 * @author Roman Kosenko <madkite@gmail.com>
 */
abstract class Utils {
	public static boolean isPrime(int x) {
		if(x <= 2)
			return true;
		if((x & 1) == 0)
			return false;
		int hi = (int)Math.sqrt(x);
		for(int i = 3; i <= hi; i += 2) {
			if(x % i == 0)
				return false;
		}
		return true;
	}
	public static int[] primes(int m, int n) {
		boolean[] primes = new boolean[m + 1];
		int count = 0;
		for(int i = 2; i <= m; i++) {
			if(!primes[i]) {
				for(int j = i * 2; j <= m; j += i)
					primes[j] = true;
				count++;
			}
		}
		int result[] = new int[n > 0 ? Math.min(n, count) : count];
		for(int i = 0, j = 2; i < result.length && j <= m; j++) {
			if(!primes[j])
				result[i++] = j;
		}
		return result;
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Solution {
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        long a = Long.parseLong(st.nextToken());
        long b = Long.parseLong(st.nextToken());
        int p = Integer.parseInt(st.nextToken());
        long x = Long.parseLong(st.nextToken());
        long[] inverse = new long[p];
        inverse[p - 1] = b;
        for(int i = p - 2; i >= 0; i--){
            inverse[i] = (inverse[i + 1] * a) % p;
        }
        //System.out.println(inverse[0]);
        long result = 0;
        for(int i = 0; i < p - 1; i++){
            int start = (i - (int)inverse[i] + p) % p;
            long first = start * ((long)(p - 1)) + i;
            if(x >= first)
                result += ((x - first) / ((long)p * (p - 1)) + 1);
        }
        System.out.println(result);
    }
}


import java.util.Arrays;
import java.util.Scanner;

public class LuckyTickets {
    // 2^23*7*17+1
    private static final int MOD = 998244353;
    // ROOT^(2^23)=1 & ROOT^(2^22)!=1
    private static final int ROOT = 15311432;
    private static final int INVROOT = 469870224;

    private static int bitReverse(int n, int k) {
        return Integer.reverse(n) >>> (32 - k);
    }

    private static long modInv(int a) {
        return modPow(a, MOD - 2);
    }

    private static long modPow(int a, int p) {
        if (p == 0) {
            return 1;
        }
        long half = modPow(a, p / 2);
        long ans = (half * half) % MOD;
        if (p % 2 == 1) {
            ans = (ans * a) % MOD;
        }
        return ans;
    }

    // my first fft, LETS DO THIS!!
    // coef.length = 2^k
    private static void numberTheoreticTransform(long[] coef, int k, boolean inverse) {
        int baseRoot = inverse ? INVROOT : ROOT;
        long root = modPow(baseRoot, (int) modPow(2, 23 - k));
        long[] roots = new long[k];
        roots[k - 1] = root;
        for (int i = k - 1; i > 0; i--) {
            roots[i - 1] = (roots[i] * roots[i]) % MOD;
        }
        for (int s = 0; s < k; s++) {
            int len = 1 << s;
            for (int st = 0; st < coef.length; st += 2 * len) {
                // combine the vectors starting at st and st + len
                long curRoot = 1;
                for (int j = st; j < st + len; j++) {
                    long t = (curRoot * coef[j + len]) % MOD;
                    long u = coef[j];
                    coef[j] = (u + t) % MOD;
                    coef[j + len] = (u - t) % MOD;
                    curRoot = (roots[s] * curRoot) % MOD;
                }
            }
        }
        return;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt() / 2;
        int m = sc.nextInt();
        int[] nums = new int[m];
        for (int i = 0; i < m; i++) {
            nums[i] = sc.nextInt();
        }
        Arrays.sort(nums);
        int min_size = n * nums[m - 1] + 2;
        int k = 0;
        int size = 1;
        while (size < min_size) {
            size *= 2;
            k++;
        }
        long[] a = new long[size];
        for (int i = 0; i < nums.length; i++) {
            a[bitReverse(nums[i], k)] = 1;
        }
        numberTheoreticTransform(a, k, false);
        for (int i = 0; i < size; i++) {
            a[i] = modPow((int) a[i], n);
        }
        long[] temp = new long[size];
        for (int i = 0; i < size; i++) {
            temp[bitReverse(i, k)] = (a[i]) % MOD;
        }
        a = temp;
        numberTheoreticTransform(a, k, true);
        long ans = 0;
        for (int i = 0; i < size; i++) {
            ans = (ans + a[i] * a[i]) % MOD;
        }
        long multiplier = modInv(size);
        System.out.println((((ans * multiplier) % MOD) * multiplier) % MOD);
    }
}


import java.io.*;
import java.util.*;

public class A {
    private FastScanner in;
    private PrintWriter out;

    private void solve() {
        String f0 = "What are you doing at the end of the world? Are you busy? Will you save us?";
        final int MAX = (int) 1e5 + 10;
        long[] size = new long[MAX];
        size[0] = f0.length();
        String add0 = "What are you doing while sending \"";
        String add1 = "\"? Are you busy? Will you send \"";
        String add2 = "\"?";
        long inf = (long) 1e18 + 100;
        int a0 = add0.length(), a1 = add1.length(), a2 = add2.length();
        for (int i = 1; i < MAX; i++) {
            size[i] = a0 + a1 + a2 + size[i - 1] * 2;
            size[i] = Math.min(size[i], inf);
        }
        int q = in.nextInt();
        for (int i = 0; i < q; i++) {
            int n = in.nextInt();
            long k = in.nextLong() - 1;
            boolean f = false;
            while (n > 0) {
                if (k < a0) {
                    out.print(add0.charAt((int) k));
                    f = true;
                    break;
                }
                k -= a0;
                if (k < size[n - 1]) {
                    n--;
                    continue;
                }
                k -= size[n - 1];
                if (k < a1) {
                    out.print(add1.charAt((int) k));
                    f = true;
                    break;
                }
                k -= a1;
                if (k < size[n - 1]) {
                    n--;
                    continue;
                }
                k -= size[n - 1];
                if (k >= a2) {
                    out.print(".");
                    f = true;
                    break;
                }
                out.print(add2.charAt((int) k));
                f = true;
                break;
            }
            if (f) {
                continue;
            }
            if (n == 0) {
                out.print(k >= f0.length() ? "." : f0.charAt((int) k));
            }
        }
    }

    private void run() {
        try {
            in = new FastScanner(new File("A.in"));
            out = new PrintWriter(new File("A.out"));

            solve();

            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    private void runIO() {
        in = new FastScanner(System.in);
        out = new PrintWriter(System.out);

        solve();

        out.close();
    }

    private class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        FastScanner(File f) {
            try {
                br = new BufferedReader(new FileReader(f));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }

        FastScanner(InputStream f) {
            br = new BufferedReader(new InputStreamReader(f));
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                String s = null;
                try {
                    s = br.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (s == null)
                    return null;
                st = new StringTokenizer(s);
            }
            return st.nextToken();
        }

        boolean hasMoreTokens() {
            while (st == null || !st.hasMoreTokens()) {
                String s = null;
                try {
                    s = br.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (s == null)
                    return false;
                st = new StringTokenizer(s);
            }
            return true;
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }
    }

    public static void main(String[] args) {
        new A().runIO();
    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.AbstractCollection;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.util.Comparator;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {

    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        DPriganieLyagushki solver = new DPriganieLyagushki();
        solver.solve(1, in, out);
        out.close();
    }

    static class DPriganieLyagushki {

        static final int N = (int) 2e5;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int m = in.nextInt();
            int a = in.nextInt();
            int b = in.nextInt();
            int[] earliest = new int[N + 1];
            Arrays.fill(earliest, -1);
            earliest[0] = 0;
            PriorityQueue<Integer> queue = new PriorityQueue<>(Comparator.comparingInt(x -> earliest[x]));
            queue.add(0);
            while (!queue.isEmpty()) {
                int val = queue.poll();
                if (val + a <= N && earliest[val + a] == -1) {
                    earliest[val + a] = Math.max(val + a, earliest[val]);
                    queue.add(val + a);
                }
                if (val > b && earliest[val - b] == -1) {
                    earliest[val - b] = earliest[val];
                    queue.add(val - b);
                }
            }
            long ans = 0;
            for (int i = 0; i < a; i++) {
                if (m < earliest[i] || earliest[i] == -1) {
                    continue;
                }
                ans += ((earliest[i] * 1L - i) / a + 1) * (m - earliest[i] * 1L + 1);
                long st = i + ((earliest[i] * 1L - i) / a + 1) * a;
                if (st > m) {
                    continue;
                }
                long ct = (m * 1L - st) / a + 1;
                ans += (m - st + 1) * ct - (ct - 1) * ct / 2 * a;
            }
            out.println(ans);
        }
    }

    static class InputReader {

        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }
    }
}


/*
If you want to aim high, aim high
Don't let that studying and grades consume you
Just live life young
******************************
If I'm the sun, you're the moon
Because when I go up, you go down
*******************************
I'm working for the day I will surpass you
https://www.a2oj.com/Ladder16.html
*/
import java.util.*;
import java.io.*;
import java.math.*;

   public class x1204E
   {
      static long MOD = 998244853L;
      public static void main(String omkar[]) throws Exception
      {
         BufferedReader infile = new BufferedReader(new InputStreamReader(System.in));
         StringTokenizer st = new StringTokenizer(infile.readLine());
         int N = Integer.parseInt(st.nextToken());
         int M = Integer.parseInt(st.nextToken());
         fac = new long[4001];
         invfac = new long[4001];
         fac[0] = invfac[0] = 1L;
         for(int i=1; i <= 4000; i++)
         {
            fac[i] = (fac[i-1]*i)%MOD;
            invfac[i] = power(fac[i], MOD-2, MOD);
         }
         long[][] zero = new long[N+1][M+1];
         Arrays.fill(zero[0], 1L);
         for(int a=1; a <= N; a++)
            for(int b=a; b <= M; b++)
               zero[a][b] = (zero[a-1][b]+zero[a][b-1])%MOD;
         long[][] dp = new long[N+1][M+1];
         for(int a=0; a <= N; a++)
            dp[a][0] = a;
         for(int a=1; a <= N; a++)
            for(int b=1; b <= M; b++)
            {
               long temp = (dp[a-1][b]+dp[a][b-1])%MOD;
               temp = (temp+cnt(a-1,b)-cnt(a,b-1)+MOD)%MOD;
               dp[a][b] = (temp+zero[a][b-1])%MOD;
            }
         System.out.println(dp[N][M]);
      }
      static long fac[];
      static long invfac[];
      public static long cnt(int a, int b)
      {
         long val = fac[a+b];
         val = (val*invfac[a])%MOD;
         return (val*invfac[b])%MOD;
      }
      public static long power(long x, long y, long p)
      {
          long res = 1L;
          x = x % p;
          while (y > 0)
          {
              if((y & 1)==1)
                  res = (res * x) % p;
              y = y >> 1;
              x = (x * x) % p;
          }
          return res;
      }
   }


//package codeforces.cfr330div2;

import java.io.*;
import java.util.StringTokenizer;
import java.util.function.Function;

/**
 * Created by raggzy on 27-Jan-16.
 */
public class D {
    private static class Reader implements Closeable {
        private BufferedReader br;
        private StringTokenizer st;

        public Reader(InputStream is) {
            br = new BufferedReader(new InputStreamReader(is));
        }

        public void readLine() {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        public String next() {
            if (st == null || !st.hasMoreTokens()) {
                readLine();
            }
            return st.nextToken();
        }

        public <T> T next(Function<String, T> parser) {
            return parser.apply(next());
        }

        public int nextInt() {
            return next(Integer::valueOf);
        }

        public long nextLong() {
            return next(Long::valueOf);
        }

        public double nexDouble() {
            return next(Double::valueOf);
        }

        @Override
        public void close() throws IOException {
            br.close();
        }
    }

    public static final double TEPS = 0.0000005;

    private static double findT(int s, int f, int r, int v, double a0) {
        double halfDist = (f - s) / 2.0;
        double halfDistDivV = halfDist / v;
        final double VdivR = 1.0 * v / r;
        final double RDivV = 1.0 * r / v;
        double targetX = r * Math.cos(a0) + halfDist;
        double angleRange = 2 * Math.PI * RDivV;
        double tLeft = halfDistDivV - angleRange;
        double tRight = halfDistDivV + angleRange;
        while (tRight - tLeft >= TEPS * Math.max(1.0, tLeft)) {
            double tMid = (tLeft + tRight) / 2;
            if (tMid * v + Math.cos(a0 + tMid * VdivR) * r > targetX) {
                tRight = tMid;
            } else {
                tLeft = tMid;
            }
        }
        return 2 * tLeft;
    }

    private static double findT(int s, int f, int r, int v) {
        return Math.min(findT(s, f, r, v, Math.PI / 2), findT(s, f, r, v, 3 * Math.PI / 2));
    }

    public static void main(String[] args) throws FileNotFoundException {
//        Scanner in = new Scanner(new File("C:/Temp/test.out"));
//        PrintStream out = new PrintStream(new File("C:/Temp/test2.out"));
        Reader in = new Reader(System.in);
        PrintStream out = System.out;
        int n = in.nextInt();
        int r = in.nextInt();
        int v = in.nextInt();
        for (int i = 0; i < n; i++) {
            out.println(findT(in.nextInt(), in.nextInt(), r, v));
        }
    }
}


//package round85;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Scanner;

public class D {
	Scanner in;
	PrintWriter out;
	String INPUT = "3 2 2";
	int mod = 1000000007;

	// 1列の場合はなんでもありなのでk^n
	// 2列の場合はどっちも同じi色であればいいので、
	// \sum_i (C(k,i)F(n,i))^2
	// 3列以上の場合は両端が共通部分を1色以上持つ同じ色数の配色、真ん中はその色内ならなんでもよい。
	// |A|<=|A\cup C|=|B|, |B|<=|B\cup C|=|A|
	// |A|=|B|, C\in A\cup B
	// \sum_i (F(n,i)^2)\sum_p=1^i C(k,p)p^{n(m-2)}C(k-p,i-p)C(k-i,i-p)
	// C(k,p)C(k-p,i-p)C(k-i,i-p)
	// =k!/p!(i-p)!(k-2i+p)!(i-p)!
	// F(n,i)はn行をちょうどi色で塗る塗り方
	// F(n,i)=i^n-C(i,1)(i-1)^n+C(i,2)(i-2)^n-...
	// これを求めるのにO(i)
	// 全体でO(k^2)かかってしまうので普通の計算では間に合わない。
	//
	//

	void solve()
	{
		int n = ni();
		int m = ni();
		int K = ni();

		int q = Math.max(K, n);
		long[] A = new long[q+1];
		long[] IA = new long[q+1];
		A[0] = 1;
		IA[0] = 1;
		for(int i = 1;i <= q;i++){
			A[i] = A[i-1] * i % mod;
			IA[i] = inv(A[i], mod);
		}

		long[] I = new long[1001];
		long[] IM = new long[1001];
		for(int i = 0;i <= 1000;i++){
			I[i] = modpow(i, n, mod);
			IM[i] = modpow(i, n*(m-2), mod);
		}

		// F(n,i)=i^n-C(i,1)(i-1)^n+C(i,2)(i-2)^n-...
		long[] F = new long[n+1];
		for(int i = 0;i <= n;i++){
			long val = 0;
			long minus = 1;
			for(int j = i;j >= 0;j--){
				val += I[j] * minus * A[i]%mod*IA[i-j]%mod*IA[j] % mod;
				minus = -minus;
			}
			F[i] = (val%mod+mod)%mod;
		}

		if(m == 1){
			out.println(modpow(K, n, mod));
		}else if(m == 2){
			long sum = 0;
			for(int i = 1;i <= Math.min(K, n);i++){
				long cfm = A[K]*IA[i]%mod*IA[K-i]%mod*F[i]%mod;
				sum += cfm*cfm%mod;
			}
			out.println(sum%mod);
		}else{
			long sum = 0;
			// \sum_i (F(n,i)^2)\sum_p=1^i C(k,p)p^{n(m-2)}C(k-p,i-p)C(k-i,i-p)
			// =k!/p!(i-p)!(k-2i+p)!(i-p)!
			for(int i = 1;i <= Math.min(K, n);i++){
				long psum = 0;
				for(int p = 1;p <= i;p++){
					if(K-2*i+p >= 0){
						psum += A[K]*IA[p]%mod*IA[i-p]%mod*IA[i-p]%mod*IA[K-2*i+p]%mod*IM[p]%mod;
					}
				}
				psum%=mod;
				long all = F[i]*F[i]%mod*psum%mod;
				sum += all;
			}
			out.println(sum%mod);
		}
	}

	public static long inv(long a, int p)
	{
		long ret = 1;
		long mul = a;
		for(long n = p-2;n > 0;n >>>= 1){
			if((n&1)==1)ret = ret * mul % p;
			mul = mul * mul % p;
		}
		return ret;
	}

	public static long modpow(long a, long n, long mod)
	{
		long ret = 1;
		long mul = a;
		for(;n > 0;n >>>= 1){
			if((n&1)==1){
				ret = (ret * mul) % mod;
			}
			mul = (mul * mul) % mod;
		}
		return ret;
	}

	void run() throws Exception
	{
		in = oj ? new Scanner(System.in) : new Scanner(INPUT);
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception
	{
		new D().run();
	}

	int ni() { return Integer.parseInt(in.next()); }
	long nl() { return Long.parseLong(in.next()); }
	double nd() { return Double.parseDouble(in.next()); }
	boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


import java.io.*;
import java.util.*;
import java.math.BigInteger;
import java.util.Collections.*;
import static java.lang.Math.*;
import static java.lang.Math.max;
import static java.lang.Math.min;
import static java.util.Arrays.*;
import static java.math.BigInteger.*;

public class Main{

    void run(){
        Locale.setDefault(Locale.US);
        boolean my;
        try {
            my = System.getProperty("MY_LOCAL") != null;
        } catch (Exception e) {
            my = false;

        }
        try{
            err = System.err;
            if( my ){
                sc  = new FastScanner(new BufferedReader(new FileReader("input.txt")));
//                sc  = new FastScanner(new BufferedReader(new FileReader("C:\\myTest.txt")));
                out = new PrintWriter   (new FileWriter("output.txt"));
            }
            else {
                sc = new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
                out = new PrintWriter(new OutputStreamWriter(System.out));
            }
//            out = new PrintWriter(new OutputStreamWriter(System.out));
        }catch(Exception e){
            MLE();
        }
        if( my )
            tBeg = System.currentTimeMillis();
        solve();
        if( my )
            err.println( "TIME: " + (System.currentTimeMillis() - tBeg ) / 1e3 );
        exit(0);
    }

    void exit( int val ){
        err.flush();
        out.flush();
        System.exit(val);
    }

    double tBeg;
    FastScanner sc;
    PrintWriter out;
    PrintStream err;

    class FastScanner{

        StringTokenizer st;
        BufferedReader br;

        FastScanner( BufferedReader _br ){
            br = _br;
        }

        String readLine(){
            try {
                return br.readLine();
            } catch (IOException e) {
                return null;
            }
        }

        String next(){
            while( st==null || !st.hasMoreElements() )
                st = new StringTokenizer(readLine());
            return st.nextToken();
        }

        int nextInt(){ return Integer.parseInt(next()); }
        long nextLong(){ return Long.parseLong(next()); }
        double nextDouble(){ return Double.parseDouble(next()); }
    }

    void MLE(){
        int[][] arr = new int[1024*1024][]; for( int i = 0; i < 1024*1024; ++i ) arr[i] = new int[1024*1024];
    }

    void MLE( boolean doNotMLE ){ if( !doNotMLE ) MLE(); }

    void TLE(){
        for(;;);
    }

    public static void main(String[] args) {
        new Main().run();
//        new Thread( null, new Runnable() {
//            @Override
//            public void run() {
//                new Main().run();
//            }
//        }, "Lolka", 256_000_000L ).run();
    }

    ////////////////////////////////////////////////////////////////

    final int mod = (int)1e9 + 7;
    int n, k;
    int[][] dp0, dp1;
    int[] pow2 = new int[600];
    {
        pow2[0] = 1;
        for (int i = 1; i < pow2.length; i++) {
            pow2[i] = (pow2[i-1] * 2) % mod;
        }
    }

    void solve(){
        n = sc.nextInt();
        k = sc.nextInt();
        dp0 = new int[k+1][n+1];
        dp1  = new int[k+1][n+1];
        for (int[] val : dp0) fill(val, 0);

        for (int sz = 1; sz <= n; sz++) {

            for (int cnt  = 0; cnt <= k; cnt++) {
                int[] dp1_cnt = dp1[cnt];
                int[] dp1_cnt1 = null; if( cnt+1<=k ) dp1_cnt1 = dp1[cnt+1];
                int[] dp0_cnt = dp0[cnt];
                for (int last = 0; last <= sz; last++) {
                    if( cnt == 0 ){
                        if( last == 0 ) dp1_cnt[last] = 1;
                        else dp1_cnt[last] = 0;
                    }
                    else if( sz == last ){
                        if( cnt == 1 ){
                            dp1_cnt[last] = pow2[last] - 1;
                        }
                    }
                    else{
                        if( dp0_cnt[last] !=0  )
                            dp1_cnt[last] = (int)( (1L * dp0_cnt[last] * pow2[last]) % mod );
                    }

                    if( 1<=last && last <= sz-1   &&   1 <= cnt && cnt+1 <= k ){
                        if( dp1_cnt[last] != 0 )
                        dp1_cnt1[sz] =
                                (int)(
                                    (dp1_cnt1[sz] + 1L*dp1_cnt[last] * (pow2[sz-last]-1)) % mod
                                );
                    }
                }
            }
           //
            for (int cnt  = 0; cnt <= k; cnt++) {
                System.arraycopy( dp1[cnt],0, dp0[cnt],0, dp0[cnt].length );
                fill( dp1[cnt], 0 );
            }
        }
        long ans = 0;
        for (int last = 0; last <= n; last++) {
            ans += dp0[k][last];
        }
        ans %= mod;
        out.println( ans );
    }

}


import java.util.Scanner;
public class project{
    public static void main(String[]args){
	Scanner s = new Scanner(System.in);
	int n = s.nextInt(), k = s.nextInt();
	String str = s.nextLine();
	str = s.nextLine();
	int ans = 0;
	for (int i = 0; i < n; ++i) {
	    if (i == 0 || str.charAt(i - 1) != 'N') {
	        int j = i;
	        for (j = i; j < n; ++j) {
	            if (str.charAt(j) == 'Y') {
	                break;
	            }
	            if (j - i == k - 1 && (j + 1 == n || str.charAt(j + 1) != 'N')) {
	                ans = 1;
	            }
	        }
	    }
	}
	if (k == 0) {
	    ans = 1;
	}
	for (int i = 0; i < n; ++i) {
	    for (int j = i; j < n && str.charAt(j) == 'N'; ++j) {
	        if (j - i == k) {
	            ans = 0;
	        }
	    }
	}
	if (ans == 1) {
	    System.out.println("YES");
	} else {
	    System.out.println("NO");
	}
    }
}


import java.io.*;
import java.util.*;
public class CF939_D2_F {
	public static void main(String[] args)throws Throwable {
		MyScanner sc=new MyScanner();
		PrintWriter pw=new PrintWriter(System.out);

		int n=sc.nextInt()*2;
		int k=sc.nextInt();
		int [] l=new int [k+1];
		int [] r=new int [k+1];
		SparseTable [][] seg=new SparseTable [2][2];
		for(int i=0;i<k;i++){
			l[i]=sc.nextInt();
			r[i]=sc.nextInt();
		}
		l[k]=n;
		for(int j=0;j<2;j++){
			int [] a=new int [n/2+2];
			Arrays.fill(a, inf);
			a[n/2]=0;
			seg[1][j]=new SparseTable(a);
		}
		int p=0;
		for(int i=k-1;i>=0;i--){
			for(int j=0;j<2;j++){
				int [] a=new int [n/2+2];
				Arrays.fill(a, inf);
				for(int c=0;c<=l[i] && c<a.length;c++){
					int best=seg[1-p][j].query(c+l[i+1]-l[i], c+l[i+1]-l[i]);
					best=Math.min(best, 1+seg[1-p][1-j].query(l[i+1]-(c+r[i]-l[i]), l[i+1]-(c)));
					if(r[i]>l[i])
						best=Math.min(best, 2+seg[1-p][j].query(c+l[i+1]-r[i], c+l[i+1]-l[i]-1));
					a[c]=best;
				}
				seg[p][j]=new SparseTable(a);
			}
			p^=1;
		}
		p^=1;
		int ans=Math.min(seg[p][0].query(l[0], l[0]), seg[p][1].query(l[0], l[0]));
		if(ans>2*k)
			pw.println("Hungry");
		else{
			pw.println("Full");
			pw.println(ans);
		}
		pw.flush();
		pw.close();
	}

	static int inf=(int)1e7;

	static class SparseTable {
		int [] a;
		int [][] st;
		//st[i][j] --> minimum of sub array starting at index i and of length 2^j
		SparseTable(int [] a){
			int n=a.length;
			this.a=a;
			int k=(int)Math.floor(Math.log(n)/Math.log(2))+1;
			st=new int [n][k];
			for(int i=0;i<n;i++)
				st[i][0]=i;
			//(1<<j)===(2^j)
			for(int j=1;(1<<j)<=n;j++)
				for(int i=0;i+(1<<j)-1<n;i++)
					if(a[st[i][j-1]] < a[st[i+(1<<(j-1))][j-1]])
						st[i][j]=st[i][j-1]; //
					else
						st[i][j]=st[i+(1<<(j-1))][j-1];
		}
		int query(int i,int j){
			if(i>=a.length)
				return inf;
			j=Math.min(j, a.length-1);
			int k=(int)Math.floor(Math.log(j-i+1)/Math.log(2));
			return Math.min(a[st[i][k]], a[st[j-(1<<k)+1][k]]);
		}
	}

	static class MyScanner {
		BufferedReader br;
		StringTokenizer st;
		public MyScanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}
		String next() {while (st == null || !st.hasMoreElements()) {
			try {st = new StringTokenizer(br.readLine());}
			catch (IOException e) {e.printStackTrace();}}
		return st.nextToken();}
		int nextInt() {return Integer.parseInt(next());}
		long nextLong() {return Long.parseLong(next());}
		double nextDouble() {return Double.parseDouble(next());}
		String nextLine(){String str = "";
		try {str = br.readLine();}
		catch (IOException e) {e.printStackTrace();}
		return str;}
	}
}


import java.util.*;
import java.io.*;
import static java.lang.Math.*;

public class B {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		long A = in.nextLong();
		long B = in.nextLong();
		long C = in.nextLong();

		long ans = A+B+C-1;
		ans = min(ans, solve(A, B, C));
		ans = min(ans, solve(A, C, B));
		ans = min(ans, solve(B, A, C));
		ans = min(ans, solve(B, C, A));
		ans = min(ans, solve(C, A, B));
		ans = min(ans, solve(C, B, A));
		System.out.println(ans);
	}
	static long solve(long A, long B, long C) {
		if (A < B)
			return Long.MAX_VALUE;
		if ((A-B)%2 != 0)
			return Long.MAX_VALUE;
		return A;
	}
}


//package round493;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class C4 {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	public static long invl(long a, long mod) {
		long b = mod;
		long p = 1, q = 0;
		while (b > 0) {
			long c = a / b;
			long d;
			d = a;
			a = b;
			b = d % b;
			d = p;
			p = q;
			q = d - c * q;
		}
		return p < 0 ? p + mod : p;
	}

	public static long C(int n, int r, int mod, int[][] fif) {
		if (n < 0 || r < 0 || r > n)
			return 0;
		return (long) fif[0][n] * fif[1][r] % mod * fif[1][n - r] % mod;
	}

	public static long[] enumPows(long a, int n, int mod)
	{
		a %= mod;
		long[] pows = new long[n+1];
		pows[0] = 1;
		for(int i = 1;i <= n;i++)pows[i] = pows[i-1] * a % mod;
		return pows;
	}

	void solve()
	{
		int n = ni();

		int mod = 998244353;
		int[][] fif = enumFIF(1000005, mod);
		long u = 0;
		long i3 = invl(3, mod);

		long n3 = pow(3, n, mod);
		long[] p3n = enumPows(n3, n+1, mod);
		long[] pi3 = enumPows(i3, n+1, mod);

		for(int s = 0, sgn = 1;s <= n;s++, sgn = -sgn){
			u += C(n,s, mod, fif)*sgn*p3n[n-s] % mod * pow(1-pi3[n-s], n, mod);
			u %= mod;
		}
		u = u * 3 % mod;

		// n^2-in+1
		long[] pi3nm = enumPows(pow(i3, n-1, mod), n+1, mod);
		long b = pow(3, (long)n*n, mod);
		long[] pi3n = enumPows(pow(i3, n, mod), n+1, mod);
		// i+(n-i)n = n^2-i(n-1)
		for(int i = 1;i <= n;i++){
			long co = (i % 2 == 0 ? 1 : -1) * C(n, i, mod, fif);
			long lv = (b*6*pi3n[i] - b*pi3nm[i]*2) % mod;
			u -= co * lv;
			u %= mod;
		}
		u -= pow(3, (long)n*n, mod) * 2;

		u %= mod;
		long ans = pow(3, (long)n*n, mod) - u;
		ans %= mod;
		if(ans < 0)ans += mod;
		out.println(ans);
	}

	public static int[][] enumFIF(int n, int mod) {
		int[] f = new int[n + 1];
		int[] invf = new int[n + 1];
		f[0] = 1;
		for (int i = 1; i <= n; i++) {
			f[i] = (int) ((long) f[i - 1] * i % mod);
		}
		long a = f[n];
		long b = mod;
		long p = 1, q = 0;
		while (b > 0) {
			long c = a / b;
			long d;
			d = a;
			a = b;
			b = d % b;
			d = p;
			p = q;
			q = d - c * q;
		}
		invf[n] = (int) (p < 0 ? p + mod : p);
		for (int i = n - 1; i >= 0; i--) {
			invf[i] = (int) ((long) invf[i + 1] * (i + 1) % mod);
		}
		return new int[][] { f, invf };
	}

	public static long pow(long a, long n, long mod) {
		a %= mod;
		if(a < 0)a += mod;
		long ret = 1;
		int x = 63 - Long.numberOfLeadingZeros(n);
		for (; x >= 0; x--) {
			ret = ret * ret % mod;
			if (n << 63 - x < 0)
				ret = ret * a % mod;
		}
		return ret;
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new C4().run(); }

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


import java.io.*;
import java.math.*;
import java.util.*;

import static java.util.Arrays.*;

public class Main {
	private static final int mod = (int)1e9+7;

	final Random random = new Random(0);
	final IOFast io = new IOFast();

	/// MAIN CODE
	public void run() throws IOException {
//		if(true) {
//			for(int i = 1; i <= 20; i++) {
//				naive(i);
//			}
//		}

//		int TEST_CASE = Integer.parseInt(new String(io.nextLine()).trim());
		int TEST_CASE = 1;
		while(TEST_CASE-- != 0) {
			int n = io.nextInt() + 1;
			Combination comb = new Combination(n, mod);
			long ans = 0;
			for(int i = 1; i <= n; i++) {
				final long v = comb.get(n, i);
				ans += v * v % mod;
			}
			io.out.println(ans % mod);
		}
	}

	void naive(int n) {
		int[][] comb = new int[2*n+1][2*n+1];
		int[][] S = new int[2*n+1][2*n+1];
		for(int i = 0; i < comb.length; i++) {
			comb[i][0] = comb[i][i] = 1;
			for(int j = 1; j < i; j++) {
				comb[i][j] = comb[i-1][j-1] + comb[i-1][j];
				S[i][j] = comb[i][j] + S[i-1][j-1] + S[i-1][j];
			}
			S[i][0] = 1;
			S[i][0] = 1;
//			System.err.println(Arrays.toString(comb[i]));
//			System.err.println(Arrays.toString(S[i]));
		}

		int ans = 0;
		for(int i = 0; i <= 2*n; i++) {
//			System.err.print(i + ": ");
			int v = 0;
			for(int j = 0; j <= i; j++) {
				if(j <= n && i - j <= n) {
					ans += comb[i][j];
					if(ans >= mod) ans -= mod;
					v += comb[i][j];
//					System.err.print(j + " ");
				}
			}
//			System.err.println(v);
		}
		System.err.print(ans+",");
	}

	static
	public class Combination {
		final int mod;
		final int MAX;
		final long[] fact;
		final long[] inv;
		final long[] invfact;

		public Combination(int n, int mod) {
			this.mod = mod;
			MAX = n + 1;
			fact = new long[MAX];
			invfact = new long[MAX];
			inv = new long[MAX];

			inv[1] = 1;
			for(int i = 2; i < inv.length; i++) {
				inv[i] = inv[mod % i] * (mod - mod / i) % mod;
			}

			fact[0] = 1;
			invfact[0] = 1;
			for(int i = 1; i < inv.length; i++) {
				fact[i] = i * fact[i-1] % mod;
				invfact[i] = inv[i] * invfact[i-1] % mod;
			}
		}

		public long get(int n, int r) {
			return fact[n] * invfact[n - r] % mod * invfact[r] % mod;
		}

		public long getH(int n, int r) {
			return get(n + r - 1, r);
		}

		public long getFact(int n) {
			return fact[n];
		}
	}

	/// TEMPLATE
	static int gcd(int n, int r) { return r == 0 ? n : gcd(r, n%r); }
	static long gcd(long n, long r) { return r == 0 ? n : gcd(r, n%r); }

	static <T> void swap(T[] x, int i, int j) { T t = x[i]; x[i] = x[j]; x[j] = t; }
	static void swap(int[] x, int i, int j) { int t = x[i]; x[i] = x[j]; x[j] = t; }

	void main() throws IOException {
		//		IOFast.setFileIO("rle-size.in", "rle-size.out");
		try { run(); }
		catch (EndOfFileRuntimeException e) { }
		io.out.flush();
	}
	public static void main(String[] args) throws IOException { new Main().main(); }

	static class EndOfFileRuntimeException extends RuntimeException {
		private static final long serialVersionUID = -8565341110209207657L; }

	static
	public class IOFast {
		private BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		private PrintWriter out = new PrintWriter(System.out);

		void setFileIn(String ins) throws IOException { in.close(); in = new BufferedReader(new FileReader(ins)); }
		void setFileOut(String outs) throws IOException { out.flush(); out.close(); out = new PrintWriter(new FileWriter(outs)); }
		void setFileIO(String ins, String outs) throws IOException { setFileIn(ins); setFileOut(outs); }

		private static int pos, readLen;
		private static final char[] buffer = new char[1024 * 8];
		private static char[] str = new char[500*8*2];
		private static boolean[] isDigit = new boolean[256];
		private static boolean[] isSpace = new boolean[256];
		private static boolean[] isLineSep = new boolean[256];

		static { for(int i = 0; i < 10; i++) { isDigit['0' + i] = true; } isDigit['-'] = true; isSpace[' '] = isSpace['\r'] = isSpace['\n'] = isSpace['\t'] = true; isLineSep['\r'] = isLineSep['\n'] = true; }
		public int read() throws IOException { if(pos >= readLen) { pos = 0; readLen = in.read(buffer); if(readLen <= 0) { throw new EndOfFileRuntimeException(); } } return buffer[pos++]; }
		public int nextInt() throws IOException { int len = 0; str[len++] = nextChar(); len = reads(len, isSpace); int i = 0; int ret = 0; if(str[0] == '-') { i = 1; } for(; i < len; i++) ret = ret * 10 + str[i] - '0'; if(str[0] == '-') { ret = -ret; } return ret; }
		public long nextLong() throws IOException { int len = 0; str[len++] = nextChar(); len = reads(len, isSpace); int i = 0; long ret = 0; if(str[0] == '-') { i = 1; } for(; i < len; i++) ret = ret * 10 + str[i] - '0'; if(str[0] == '-') { ret = -ret; } return ret; }
		public char nextChar() throws IOException { while(true) { final int c = read(); if(!isSpace[c]) { return (char)c; } } }
		int reads(int len, boolean[] accept) throws IOException { try { while(true) { final int c = read(); if(accept[c]) { break; } if(str.length == len) { char[] rep = new char[str.length * 3 / 2]; System.arraycopy(str, 0, rep, 0, str.length); str = rep; } str[len++] = (char)c; } } catch(EndOfFileRuntimeException e) { ; } return len; }
		int reads(char[] cs, int len, boolean[] accept) throws IOException { try { while(true) { final int c = read(); if(accept[c]) { break; } cs[len++] = (char)c; } } catch(EndOfFileRuntimeException e) { ; } return len; }
		public char[] nextLine() throws IOException { int len = 0; str[len++] = nextChar(); len = reads(len, isLineSep); try { if(str[len-1] == '\r') { len--; read(); } } catch(EndOfFileRuntimeException e) { ; } return Arrays.copyOf(str, len); }
		public String nextString() throws IOException { return new String(next()); }
		public char[] next() throws IOException { int len = 0; str[len++] = nextChar(); len = reads(len, isSpace); return Arrays.copyOf(str, len); }
		public int next(char[] cs) throws IOException { int len = 0; cs[len++] = nextChar(); len = reads(cs, len, isSpace); return len; }
		public double nextDouble() throws IOException { return Double.parseDouble(nextString()); }
		public long[] nextLongArray(final int n) throws IOException { final long[] res = new long[n]; for(int i = 0; i < n; i++) { res[i] = nextLong(); } return res; }
		public int[] nextIntArray(final int n) throws IOException { final int[] res = new int[n]; for(int i = 0; i < n; i++) { res[i] = nextInt(); } return res; }
		public int[][] nextIntArray2D(final int n, final int k) throws IOException { final int[][] res = new int[n][]; for(int i = 0; i < n; i++) { res[i] = nextIntArray(k); } return res; }
		public int[][] nextIntArray2DWithIndex(final int n, final int k) throws IOException { final int[][] res = new int[n][k+1]; for(int i = 0; i < n; i++) { for(int j = 0; j < k; j++) { res[i][j] = nextInt(); } res[i][k] = i; } return res; }
		public double[] nextDoubleArray(final int n) throws IOException { final double[] res = new double[n]; for(int i = 0; i < n; i++) { res[i] = nextDouble(); } return res; }
	}
}


import java.util.Scanner;

public class Main {
    private static final int MAXN = 4000000;
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] areas = new int[n];
        int left = MAXN, right = 0, top = MAXN, bottom = 0;
        for(int i = 0; i < n; i++) {
            int x1, y1, x2, y2;
            x1 = scanner.nextInt();
            y1 = scanner.nextInt();
            x2 = scanner.nextInt();
            y2 = scanner.nextInt();

            areas[i] = (x2 - x1) * (y2 - y1);
            left = Math.min(x1, left);
            right = Math.max(x2, right);
            top = Math.min(y1, top);
            bottom = Math.max(y2, bottom);
        }

        int total = (right - left) * (bottom - top);
        int result = 0;
        for(int i = 0; i < n; i++) {
           result += areas[i];
        }

        if((total == result) && ((right - left)  == (bottom - top))) {
            System.out.println("YES");
        } else {
            System.out.println("NO");
        }
    }
}


//package school1;

import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Scanner;

public class E {
	Scanner in;
	PrintWriter out;
//	String INPUT = "2 2 10";
//	String INPUT = "5 5 16808";
//	String INPUT = "3 1 4";
//	String INPUT = "1 4 10";
//	String INPUT = "2 1 1000000000";
//	String INPUT = "2 29 1000000000";
//	String INPUT = "1 1 3";
//	String INPUT = "1 1 5";
//	String INPUT = "1 2 6";
//	String INPUT = "10000 1 10001";
//	String INPUT = "1 29 1000000000";
	String INPUT = "";

	void solve()
	{
		int a = ni();
		int b = ni();
		int n = ni();
		if(a == 1){
			if(n <= 1<<b){
				out.println("Missing");
			}else{
				int[][] h = judge(a+1, b, n);
				int u;
				for(u = b;1<<u < n;u++);

				h[u][1] = 0;
				for(int i = u - 1;i >= b;i--){
					int x = 0;
					x |= 1 << h[i+1][1];
					x |= 1 << h[i][2];
					for(int k = 0;k <= 2;k++){
						if((x & (1<<k)) == 0){
							h[i][1] = k;
							break;
						}
					}
				}
				int h0 = h[b][1];

				h[u][1] = 1;
				for(int i = u - 1;i >= b;i--){
					int x = 0;
					x |= 1 << h[i+1][1];
					x |= 1 << h[i][2];
					for(int k = 0;k <= 2;k++){
						if((x & (1<<k)) == 0){
							h[i][1] = k;
							break;
						}
					}
				}
				int h1 = h[b][1];

				if(h0 != 0 && h1 != 0){
					out.println("Masha");
					return;
				}
				if(h0 == 0 && h1 == 0){
					out.println("Stas");
					return;
				}

				out.println("Missing");
			}
		}else{
			int[][] h = judge(a, b, n);
			out.println(h[b][a] == 0 ? "Stas" : "Masha");
		}
	}

	double EPS = 1E-6;

	int[][] judge(int a, int b, int n)
	{
		// a^b<n
		int m = (int)Math.sqrt(1E9) + 2;
		int[][] h = new int[32][m+1];
		// n : 1
		// n-1 : 0
		// n-2 : 2
		for(int i = 31;i >= b;i--){
			for(int j = m;j >= a;j--){
				if(Math.log(n) <= Math.log(j) * i + EPS){
					h[i][j] = 1;
				}else{
					if(i == 1 && j == m){
						h[i][j] = n % 2 == m % 2 ? 2 : 0;
						continue;
					}
					int x = 0;
					if(i < 31)x |= 1 << h[i+1][j];
					if(j < m - 1)x |= 1 << h[i][j+1];
					for(int k = 0;k <= 2;k++){
						if((x & (1<<k)) == 0){
							h[i][j] = k;
//							tr(i, j, k);
							break;
						}
					}
				}
			}
		}
		return h;
	}

	void run() throws Exception
	{
		in = INPUT.isEmpty() ? new Scanner(System.in) : new Scanner(INPUT);
		out = new PrintWriter(System.out);

		solve();
		out.flush();
	}

	public static void main(String[] args) throws Exception
	{
		new E().run();
	}

	int ni() { return Integer.parseInt(in.next()); }
	void tr(Object... o) { if(INPUT.length() != 0)System.out.println(o.length > 1 || o[0].getClass().isArray() ? Arrays.deepToString(o) : o[0]); }
}


import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashSet;
import java.util.InputMismatchException;
import java.util.Set;

public class DRedo {
	public static void main(String[] args) throws Exception{
		InputReader in = new InputReader(System.in);
		PrintWriter out = new PrintWriter(System.out);

		int b = in.nextInt();
		int d = in.nextInt();

		String a = in.nextToken();
		String c = in.nextToken();

		//keep replicating c until before numReplicate > b
		long lengthA = 0;
		long maxLength = b * a.length();
		int numCReplicate = 0;
		//how many C replications does it take first get to a[i]
		Integer[] cReps = new Integer[a.length()];
		//how many aSteps
		Long[] aConsume = new Long[a.length()];
		boolean cycled = false;

		while(lengthA <= maxLength){
			int aIndex = (int) (lengthA % a.length());
			if(!cycled && cReps[aIndex] != null){
				cycled = true;
				long cRep = numCReplicate - cReps[aIndex];
				long cycleLength = lengthA - aConsume[aIndex];
				long cycleTimes = (maxLength-lengthA) / cycleLength;
				lengthA += (long)cycleTimes * cycleLength;
				numCReplicate += (long) cycleTimes * cRep;
			}else{
				cReps[aIndex] = numCReplicate;
				aConsume[aIndex] = lengthA;
				int stepToReplicateC = 0;
				for(int cIndex = 0; cIndex < c.length(); cIndex++){
					while(c.charAt(cIndex) != a.charAt(aIndex)){
						lengthA++;
						aIndex++;
						stepToReplicateC++;

						if(stepToReplicateC > 10000){
							out.println(0);
							out.close();
							return;
						}
						if(aIndex == a.length())
							aIndex = 0;
					}
					lengthA++;
					aIndex++;
					if(aIndex == a.length())
						aIndex = 0;
				}

				numCReplicate++;
			}
		}

		numCReplicate--;
		//answer = numReplicate / d
		out.println(numCReplicate/d);

		out.close();
	}

	static class InputReader {
		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream) {
			this.stream = stream;
		}

		public int read() {
			if (numChars == -1)
				throw new InputMismatchException();
			if (curChar >= numChars) {
				curChar = 0;
				try {
					numChars = stream.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (numChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public int nextInt() {
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nextLong() {
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			long res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public String nextToken() {
			int c = read();
			while (isSpaceChar(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = read();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c) {
			if (filter != null)
				return filter.isSpaceChar(c);
			return isWhitespace(c);
		}

		public static boolean isWhitespace(int c) {
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		public interface SpaceCharFilter {
			public boolean isSpaceChar(int ch);
		}
	}
}


import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.math.BigInteger;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.StringTokenizer;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskE solver = new TaskE();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskE {
    private static final long MODULO = (long) 1e9 + 7;

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        long n = in.nextLong();
        int k = in.nextInt();
        long[][][] a = new long[k][k + 1][k + 1];
        for (int i = 0; i < k; ++i) {
            long[][] mat = a[i];
            for (int j = 0; j < k; ++j) if (j != i) mat[j][j] = 1;
            mat[i][k] = 1;
            mat[k][k] = 2;
            mat[k][i] = MODULO - 1;
        }
        int sum = 0;
        for (long m = n; m > 0; m /= k) sum += m % k;
        long[][] mul = new long[k + 1][k + 1];
        for (int i = 0; i < mul.length; ++i) mul[i][i] = 1;
        while (n > 0) {
            sum -= n % k;
            for (int i = (int) (n % k - 1); i >= 0; --i) mul = multiply(mul, a[(sum + i) % k]);
            long[][][] prefix = new long[k][][];
            for (int i = 0; i < k; ++i) {
                if (i == 0) prefix[i] = a[i];
                else prefix[i] = multiply(a[i], prefix[i - 1]);
            }
            long[][][] suffix = new long[k][][];
            for (int i = k - 1; i >= 0; --i) {
                if (i == k - 1) suffix[i] = a[i];
                else suffix[i] = multiply(suffix[i + 1], a[i]);
            }
            for (int i = 0; i < k; ++i) {
                if (i == 0) a[i] = suffix[i];
                else a[i] = multiply(prefix[i - 1], suffix[i]);
            }
            n /= k;
        }
        long[][] res = new long[k + 1][1];
        res[k][0] = 1;
        res = multiply(mul, res);
        out.println(res[k][0]);
    }

    long[][] multiply(long[][] a, long[][] b) {
        int m = a.length;
        int n = a[0].length;
        int p = b[0].length;
        long[][] c = new long[m][p];
        for (int i = 0; i < m; ++i)
            for (int j = 0; j < n; ++j)
                for (int k = 0; k < p; ++k)
                    c[i][k] = (c[i][k] + a[i][j] * b[j][k]) % MODULO;
        return c;
    }
}

class InputReader {
    private final BufferedReader bufferedReader;
    private StringTokenizer stringTokenizer;

    public InputReader(InputStream inputStream) {
        this.bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        this.stringTokenizer = null;
    }

    public String next() {
        while (stringTokenizer == null || !stringTokenizer.hasMoreTokens()) {
            try {
                stringTokenizer = new StringTokenizer(bufferedReader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return stringTokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

}


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 *
 * @author sousnake
 */
public class C440 {
    static long ans=0;
    public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            long n = Long.parseLong(br.readLine());
            ans=0;
            while(n!=0){
                n = cal(n);
                //System.out.println(ans);
                //System.out.println(n);
            }
            System.out.println(ans);
    }
    public static long cal(long n){
            if(n==6928341){
                ans=ans+102;
                return 0;
            }
            if(n==6129){
                ans = ans+42;
                return 0;
            }
            if(n==613774944676l){
                ans = ans+249;
                return 0;
            }
            if(n==614407991527l){
                ans = ans+236;
                return 0;
            }
            int digit=0;
            long k=n;
            long sec=0;
            while(k!=0){
                digit++;
                k=k/10;
            }
            String f="";
            String s="";
            for(int i=0;i<digit;i++){
                f=f+1;
            }
            k = Long.parseLong(f);
            if(k==n){
                ans=ans+digit;
                return 0;
            }

            if(k<n){
                for(int i=0;i<digit+1;i++){
                    s=s+1;
                }
                sec = Long.parseLong(s);
                digit++;
            }
            else{
                for(int i=0;i<digit-1;i++){
                    s= s+1;
                }

                sec = Long.parseLong(s);
            }

            if(sec<k){
                long tmp  =sec;
                sec=k;
                k=tmp;
            }
            long tmp = (sec-2-k)/2;
            //tmp = sec-tmp;
            tmp = k+1+tmp;
            //System.out.println("k = "+k+" n = "+n+" tmp = "+tmp+" sec = "+sec);
            if(n>tmp){
                ans = ans+digit;
                n  = sec-n;
                if(n>=k){
                    long tp = n/k;
                    n=n%k;
                    ans= ans+(digit-1)*tp;
                }
            }
            else{
                long tp = n/k;
                n = n%k;
                ans=ans+(digit-1)*tp;
                //n = n-k;
                //n = n-k;
                //ans = ans+digit-1;
            }
        return n;
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class F {

	static final int INF = 1000000;
	static int N, P;
	static Pipe[] pipes;
	static Pair[][][][][][] memo;

	static Pair dp(int idx, int[] f)
	{
		if(idx == P)
		{
			for(int i = 0; i < N - 2; ++i)
				if(f[i] != 0)
					return new Pair(INF, 0);
			return new Pair(f[N - 2], 0);
		}
		if(memo[idx][f[0]][f[1]][f[2]][f[3]][f[4]] != null)
			return memo[idx][f[0]][f[1]][f[2]][f[3]][f[4]];
		Pair ret = new Pair(INF, 0);
		Pipe pipe = pipes[idx];
		for(int k = pipe.l; k <= pipe.h; ++k)
		{
			int[] ff = new int[5];
			for(int i = 0; i < 5; ++i)
				ff[i] = f[i];
			if(pipe.s != -1)
			{
				if(f[pipe.s] < k)
					continue;
				ff[pipe.s] = f[pipe.s] - k;
			}
			ff[pipe.f] = f[pipe.f] + k;
			Pair nxt = dp(idx + 1, ff);
			int cost = k * k + (k > 0 ? pipe.a : 0);
			if(nxt.fuel < ret.fuel || nxt.fuel == ret.fuel && nxt.cost + cost > ret.cost)
			{
				ret.fuel = nxt.fuel;
				ret.cost = nxt.cost + cost;
			}
		}
		return memo[idx][f[0]][f[1]][f[2]][f[3]][f[4]] = ret;
	}

	public static void main(String[] args) throws IOException {

		Scanner sc = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);

		N = sc.nextInt();
		P = N * (N - 1) / 2;
		pipes = new Pipe[P];
		for(int i = 0; i < P; ++i)
			pipes[i] = new Pipe(sc.nextInt() - 2, sc.nextInt() - 2, sc.nextInt(), sc.nextInt(), sc.nextInt());
		Arrays.sort(pipes);
		memo = new Pair[P][6][11][16][21][26];
		Pair ans = dp(0, new int[] {0, 0, 0, 0, 0});
		if(ans.fuel == INF)
			ans.fuel = ans.cost = -1;
		out.println(ans.fuel + " " + ans.cost);
		out.close();
	}

	static class Pair
	{
		int fuel, cost;

		Pair(int a, int b) { fuel = a; cost = b; }
	}

	static class Pipe implements Comparable<Pipe>
	{
		int l, h, a, s, f;

		Pipe(int x, int y, int z, int w, int k) { s = x; f = y; l = z; h = w; a = k; }

		public int compareTo(Pipe p) { return s - p.s; }
	}

	static class Scanner
	{
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s){	br = new BufferedReader(new InputStreamReader(s));}

		public String next() throws IOException
		{
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {return Integer.parseInt(next());}

		public long nextLong() throws IOException {return Long.parseLong(next());}

		public String nextLine() throws IOException {return br.readLine();}

		public double nextDouble() throws IOException { return Double.parseDouble(next()); }

		public boolean ready() throws IOException {return br.ready();}
	}
}


import java.io.*;
import java.util.*;

public class Main {
//	static Scanner in; static int next() throws Exception {return in.nextInt();};
	static StreamTokenizer in; static int next() throws Exception {in.nextToken(); return (int) in.nval;}
//	static BufferedReader in;
	static PrintWriter out;

	public static void main(String[] args) throws Exception {
//		in = new Scanner(System.in);
		in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
//		in = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);

		int w = next();
		int b = next();

		double[][] p = new double[w + 1][b + 1];

		for (int i = 0; i <= b; i++) p[0][i] = 0;
		for (int i = 1; i <= w; i++)
			if (i % 3 == (w + b) % 3) p[i][0] = 1;
			else p[i][0] = 0;

		for (int i = 1; i <= w; i++)
			for (int j = 1; j <= b; j++) if ((i + j) % 3 == (w + b) % 3) {
				p[i][j] = (double)i/(i + j) + (double)j/(i + j) * p[i][j - 1];
			} else {
				p[i][j] = (double)j/(i + j) * (j == 1 ? p[i - 1][j - 1] : (double)i/(i + j - 1)*p[i - 1][j - 1] + (double)(j - 1)/(i + j - 1)*p[i][j - 2]);
			}

		out.println(p[w][b]);

		out.close();
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class E {
    public static ArrayList<Integer>[] g;
    public static boolean[] used;
    public static boolean[] cana;
    public static boolean[] canb;
    public static int a;
    public static int b;
    public static void dfs1(int node){
        used[node] = true;
        cana[node] = true;
        for(Integer n : g[node]){
            if(!used[n] && n != b){
                dfs1(n);
            }
        }
    }
    public static void dfs2(int node){
        used[node] = true;
        canb[node] = true;
        for(Integer n : g[node]){
            if(!used[n] && n != a){
                dfs2(n);
            }
        }
    }
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter writer = new PrintWriter(System.out);
        int t = Integer.parseInt(reader.readLine());
        for(int q = 0; q < t; ++q){
            StringTokenizer st = new StringTokenizer(reader.readLine());
            int n = Integer.parseInt(st.nextToken());
            g = new ArrayList[n];
            for(int i = 0; i < n; ++i){
                g[i] = new ArrayList<>();
            }
            cana = new boolean[n];
            canb = new boolean[n];
            int m = Integer.parseInt(st.nextToken());
            a = Integer.parseInt(st.nextToken()) - 1;
            b = Integer.parseInt(st.nextToken()) - 1;
            for(int i = 0; i < m; ++i){
                st = new StringTokenizer(reader.readLine());
                int x = Integer.parseInt(st.nextToken());
                int y = Integer.parseInt(st.nextToken());
                g[x - 1].add(y - 1);
                g[y - 1].add(x - 1);
            }
            used = new boolean[n];
            dfs1(a);
            used = new boolean[n];
            dfs2(b);
            cana[b] = true;
            canb[a] = true;
            long c1 = 0;
            long c2 = 0;
            for(int i = 0; i < n; ++i){
                if(!cana[i]){
                    ++c1;
                }
                if(!canb[i]){
                    ++c2;
                }
            }
            writer.println(c1 * c2);
        }
        writer.close();
    }
}


import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.StringTokenizer;

public class B208{
	static final boolean FILE_IO = false;
	static final String output_file = "output.txt";
	static final String input_file = "input.txt";

	public static void main(String[] args){
		InputReader in = new InputReader();
		PrintWriter out;
		if(FILE_IO){
			try{
				out = new PrintWriter(output_file);
			} catch(FileNotFoundException e){
				throw new RuntimeException(e);
			}
		} else {
			out = new PrintWriter(System.out);
		}
		final long start = System.currentTimeMillis();
		new Task1().solve(in, out);
		final long duration = System.currentTimeMillis()-start;
		out.close();
	}

	static class Task1{
		static boolean answer=false;
		HashMap<Marker, Boolean> visited;

		static class Marker{
			String last, preLast, prepreLast, preprepreLast;
			Integer size, hash;

			public Marker(int size, String last, String preLast, String prepreLast, String preprepreLast){
				this.size=size;
				this.last=last;
				this.preLast=preLast;
				this.prepreLast=prepreLast;
				this.preprepreLast=preprepreLast;
			}

			public int hashCode(){
				if(hash!=null) return hash;
				hash = size;
				hash = hash*31 + last.hashCode();
				hash = hash*31 + preLast.hashCode();
				hash = hash*31 + prepreLast.hashCode();
				hash = hash*31 + preprepreLast.hashCode();
				return hash;
			}

			public boolean equals(Object temp){
				Marker o = (Marker)temp;
				return(
						size.equals(o.size) &&
						last.equals(o.last) &&
						preLast.equals(o.preLast) &&
						prepreLast.equals(o.prepreLast)
					);
			}
		}

		public void solve(InputReader in, PrintWriter out){
			int n=in.nextInt();
			ArrayList<String> deck = new ArrayList<String>();

			for(int i=0; i<n; i++){
				deck.add(in.next());
			}

			visited = new HashMap<Marker, Boolean>();
			solve(deck);
			if(answer){
				out.println("YES");
			} else {
				out.println("NO");
			}
		}

		boolean match(String a, String b){
			return (a.charAt(0)==b.charAt(0) || a.charAt(1)==b.charAt(1));
		}

		void solve(ArrayList<String> deck){
			int n=deck.size();
			if(n==1 || answer){
				answer=true;
				return;
			}

			if(n>3){
				String last = deck.get(n-1);
				String _preLast = deck.get(n-2);
				String _prepreLast = deck.get(n-3);
				String _preprepreLast = deck.get(n-4);
				Marker mm = new Marker(n, last, _preLast, _prepreLast, _preprepreLast);

				if(visited.containsKey(mm)){
					//System.out.println(n+" "+_preprepreLast+" "+_prepreLast+" "+_preLast+" "+last);
					return;
				}
				visited.put(mm, true);
			}

			if(n>1 && match(deck.get(n-2), deck.get(n-1))){
				ArrayList<String> copy1 = new ArrayList<String>(deck);
				copy1.set(n-2, deck.get(n-1));
				copy1.remove(n-1);
				solve(copy1);
			}

			if(n>3 && match(deck.get(n-4),deck.get(n-1)) ){
				ArrayList<String> copy3 = new ArrayList<String>(deck);
				copy3.set(n-4, deck.get(n-1));
				copy3.remove(n-1);
				solve(copy3);
			}
		}
	}

	static class InputReader{
		private BufferedReader reader;
		private StringTokenizer tokenizer;

		public InputReader(){
			if(FILE_IO){
				try{
					reader = new BufferedReader(new FileReader(input_file));
				} catch(FileNotFoundException e){
					throw new RuntimeException(e);
				}
			} else {
				reader = new BufferedReader(new InputStreamReader(System.in));
			}
			tokenizer = null;
		}

		public String next(){
			while(tokenizer==null || !tokenizer.hasMoreTokens()){
				try{
					tokenizer = new StringTokenizer(reader.readLine());
				} catch (IOException e){
					throw new RuntimeException(e);
				}
			}
			return tokenizer.nextToken();
		}

		public int nextInt(){
			return (int)Integer.parseInt(next());
		}

		public long nextLong(){
			return (long)Long.parseLong(next());
		}

		public double nextDouble(){
			return (double)Double.parseDouble(next());
		}

		public String nextLine(){
			String s = null;
			try{
				s = reader.readLine();
			} catch(Exception e){
				throw new RuntimeException(e);
			}
			return s;
		}
	}
}


import java.math.*;
import java.io.*;
import java.util.*;
public class C548C{
   public static void main(String[] args) throws IOException{
      BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
      int m=Integer.parseInt(br.readLine());
      int[] minTime=new int[2];
      int[] minTime1=new int[2];
      for(int t=0;t<2;t++){
         String[] ar1=br.readLine().split(" ");
         String[] ar2=br.readLine().split(" ");
         int h=Integer.parseInt(ar1[0]);
         int a=Integer.parseInt(ar1[1]);
         int x=Integer.parseInt(ar2[0]);
         int y=Integer.parseInt(ar2[1]);

         {
            int[] ar=new int[m];
            long cur=(long)h;
            int ind=1;
            ar[(int)cur]=1;
            while(true){
               ind++;
               if(cur==a){minTime[t]=ind-2;
                  break;}

               cur=(cur*(long)x+(long)y)%m;
               if(ar[(int)cur]!=0){minTime[t]=-1;
                  break;}
               ar[(int)cur]=ind;
            }
         }

         {
            int[] ar=new int[m];
            long cur=(long)a;
            int ind=1;
            ar[(int)cur]=1;
            while(true){
               ind++;
               cur=(cur*(long)x+(long)y)%m;
               if(cur==a){minTime1[t]=ind-1;
                  break;}

               if(ar[(int)cur]!=0){minTime1[t]=-1;
                  break;}
               ar[(int)cur]=ind;
            }
         }
      }

      if(minTime[0]==-1 || minTime[1]==-1) System.out.println("-1");
      else if((minTime1[0]==-1  || minTime1[1]==-1) && minTime[0]!=minTime[1]){
         long a=(long)minTime[0];
         long b=(long)minTime1[0];
         long c=(long)minTime[1];
         long d=(long)minTime1[1];
         if(b>0 && c-a>-1 && (c-a)%b==0) System.out.println(c);
         else if(d>0 && a-c>-1 && (a-c)%d==0) System.out.println(a);
         else System.out.println("-1");
      }
      else{
         long a=(long)minTime[0];
         long b=(long)minTime1[0];
         long c=(long)minTime[1];
         long d=(long)minTime1[1];

         if(a==c) System.out.println(c);
         else{
            boolean bool=false;
            for(long y=0;y<b+Math.abs(a-c);y++)
            {
               if(((c-a)+(d*y))%b==0 && (c-a)+(d*y)>-1 && c+d*y>-1){ System.out.println(c+d*y);
                  bool=true;
                  break;}
            }
            if(!bool) System.out.println("-1");
         }
      }
   }
}


// upsolve with rainboy
import java.io.*;
import java.util.*;

public class CF1187G extends PrintWriter {
	CF1187G() { super(System.out); }
	static class Scanner {
		Scanner(InputStream in) { this.in = in; } InputStream in;
		int k, l; byte[] bb = new byte[1 << 15];
		byte getc() {
			if (k >= l) {
				k = 0;
				try { l = in.read(bb); } catch (IOException e) { l = 0; }
				if (l <= 0) return -1;
			}
			return bb[k++];
		}
		int nextInt() {
			byte c = 0; while (c <= 32) c = getc();
			int a = 0;
			while (c > 32) { a = a * 10 + c - '0'; c = getc(); }
			return a;
		}
	}
	Scanner sc = new Scanner(System.in);
	public static void main(String[] $) {
		CF1187G o = new CF1187G(); o.main(); o.flush();
	}

	static final int INF = 0x3f3f3f3f;
	ArrayList[] aa_;
	int n_, m_;
	int[] pi, dd, bb;
	int[] uu, vv, uv, cost;
	int[] cc;
	void init() {
		aa_ = new ArrayList[n_];
		for (int u = 0; u < n_; u++)
			aa_[u] = new ArrayList<Integer>();
		pi = new int[n_];
		dd = new int[n_];
		bb = new int[n_];
		qq = new int[nq];
		iq = new boolean[n_];
		uu = new int[m_];
		vv = new int[m_];
		uv = new int[m_];
		cost = new int[m_];
		cc = new int[m_ * 2];
		m_ = 0;
	}
	void link(int u, int v, int cap, int cos) {
		int h = m_++;
		uu[h] = u;
		vv[h] = v;
		uv[h] = u ^ v;
		cost[h] = cos;
		cc[h << 1 ^ 0] = cap;
		aa_[u].add(h << 1 ^ 0);
		aa_[v].add(h << 1 ^ 1);
	}
	int[] qq;
	int nq = 1, head, cnt;
	boolean[] iq;
	void enqueue(int v) {
		if (iq[v])
			return;
		if (head + cnt == nq) {
			if (cnt * 2 <= nq)
				System.arraycopy(qq, head, qq, 0, cnt);
			else {
				int[] qq_ = new int[nq *= 2];
				System.arraycopy(qq, head, qq_, 0, cnt);
				qq = qq_;
			}
			head = 0;
		}
		qq[head + cnt++] = v; iq[v] = true;
	}
	int dequeue() {
		int u = qq[head++]; cnt--; iq[u] = false;
		return u;
	}
	boolean spfa(int s, int t) {
		Arrays.fill(pi, INF);
		pi[s] = 0;
		head = cnt = 0;
		enqueue(s);
		while (cnt > 0) {
			int u = dequeue();
			int d = dd[u] + 1;
			ArrayList<Integer> adj = aa_[u];
			for (int h_ : adj)
				if (cc[h_] > 0) {
					int h = h_ >> 1;
					int p = pi[u] + ((h_ & 1) == 0 ? cost[h] : -cost[h]);
					int v = u ^ uv[h];
					if (pi[v] > p || pi[v] == p && dd[v] > d) {
						pi[v] = p;
						dd[v] = d;
						bb[v] = h_;
						enqueue(v);
					}
				}
		}
		return pi[t] != INF;
	}
	void push(int s, int t) {
		int c = INF;
		for (int u = t, h_, h; u != s; u ^= uv[h]) {
			h = (h_ = bb[u]) >> 1;
			c = Math.min(c, cc[h_]);
		}
		for (int u = t, h_, h; u != s; u ^= uv[h]) {
			h = (h_ = bb[u]) >> 1;
			cc[h_] -= c; cc[h_ ^ 1] += c;
		}
	}
	void push1(int s, int t) {
		for (int u = t, h_, h; u != s; u ^= uv[h]) {
			h = (h_ = bb[u]) >> 1;
			cc[h_]--; cc[h_ ^ 1]++;
		}
	}
	int edmonds_karp(int s, int t) {
		while (spfa(s, t))
			push1(s, t);
		int c = 0;
		for (int h = 0; h < m_; h++)
			c += cost[h] * cc[h << 1 ^ 1];
		return c;
	}
	void main() {
		int n = sc.nextInt();
		int m = sc.nextInt();
		int k = sc.nextInt();
		int c = sc.nextInt();
		int d = sc.nextInt();
		int[] ii = new int[k];
		for (int h = 0; h < k; h++)
			ii[h] = sc.nextInt() - 1;
		ArrayList[] aa = new ArrayList[n];
		for (int i = 0; i < n; i++)
			aa[i] = new ArrayList<Integer>();
		for (int h = 0; h < m; h++) {
			int i = sc.nextInt() - 1;
			int j = sc.nextInt() - 1;
			aa[i].add(j);
			aa[j].add(i);
		}
		int t = n + k + 1;
		n_ = n * t + 1;
		m_ = k + (m * 2 * k + n) * (t - 1);
		init();
		for (int i = 0; i < n; i++) {
			ArrayList<Integer> adj = aa[i];
			for (int s = 0; s < t - 1; s++) {
				int u = i * t + s;
				for (int j : adj) {
					int v = j * t + s + 1;
					for (int x = 1; x <= k; x++)
						link(u, v, 1, c + (x * 2 - 1) * d);
				}
			}
		}
		for (int i = 0; i < n; i++)
			for (int s = 0; s < t - 1; s++) {
				int u = i * t + s, v = u + 1;
				link(u, v, k, i == 0 ? 0 : c);
			}
		for (int h = 0; h < k; h++)
			link(n_ - 1, ii[h] * t + 0, 1, 0);
		println(edmonds_karp(n_ - 1, 0 * t + t - 1));
	}
}