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

public class E implements Runnable {
	public static void main (String[] args) {new Thread(null, new E(), "_cf", 1 << 28).start();}

	int n;
	int MAX = 51;
	HashMap<Integer, Integer>[] dp;

	public void run() {
		FastScanner fs = new FastScanner();
		PrintWriter out = new PrintWriter(System.out);
		System.err.println("Go!");

		int a = fs.nextInt(), b = fs.nextInt();
		n = fs.nextInt();

		dp = new HashMap[MAX];
		for(int i = 0; i < MAX; i++) dp[i] = new HashMap<Integer, Integer>();

		int ret = solve(b, a);
		if(ret == 1) System.out.println("Masha");
		else if(ret == 0) System.out.println("Missing");
		else System.out.println("Stas");

		out.close();
	}

	//returns -1 if whoever is playing here loses
	//returns 1 otherwise
	int solve(int a, int b) {
		if(a >= MAX) { //draw
			return 0;
		}
		if(b >= 32000) {
			int moves = (n-1)-b;
			if(moves % 2 == 1) {
				return 1;
			}

			return -1;
		}
		if(dp[a].containsKey(b)) return dp[a].get(b);
//		System.out.printf("Items %d Boxes: %d\n", a, b);

		boolean canDraw = false;
		if(!isBad(a, b + 1)) { //increase number of boxes
			int ret = solve(a, b + 1);
			if(ret == -1) { //i win
				dp[a].put(b, 1);
				return 1;
			}
			canDraw |= ret == 0;
		}

		if(!isBad(a + 1, b)) { //increase number of items
			int ret = solve(a + 1, b);
			if(ret == -1) {
				dp[a].put(b, 1);
				return 1;
			}
			canDraw |= ret == 0;
		}

		int ret = -1;
		if(canDraw) ret = 0;

		dp[a].put(b, ret);
		return ret;
	}

	boolean isBad(int a, int b) {
		double one = a * Math.log(b);
		double two = Math.log(n);
		return one > two || Math.abs(one-two) < 1e-9;
	}

	class FastScanner {
		public int BS = 1<<16;
		public char NC = (char)0;
		byte[] buf = new byte[BS];
		int bId = 0, size = 0;
		char c = NC;
		double num = 1;
		BufferedInputStream in;

		public FastScanner() {
			in = new BufferedInputStream(System.in, BS);
		}

		public FastScanner(String s) throws FileNotFoundException {
			in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
		}

		public char nextChar(){
			while(bId==size) {
				try {
					size = in.read(buf);
				}catch(Exception e) {
					return NC;
				}
				if(size==-1)return NC;
				bId=0;
			}
			return (char)buf[bId++];
		}

		public int nextInt() {
			return (int)nextLong();
		}

		public long nextLong() {
			num=1;
			boolean neg = false;
			if(c==NC)c=nextChar();
			for(;(c<'0' || c>'9'); c = nextChar()) {
				if(c=='-')neg=true;
			}
			long res = 0;
			for(; c>='0' && c <='9'; c=nextChar()) {
				res = (res<<3)+(res<<1)+c-'0';
				num*=10;
			}
			return neg?-res:res;
		}

		public double nextDouble() {
			double cur = nextLong();
			return c!='.' ? cur:cur+nextLong()/num;
		}

		public String next() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c>32) {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public String nextLine() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c!='\n') {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public boolean hasNext() {
			if(c>32)return true;
			while(true) {
				c=nextChar();
				if(c==NC)return false;
				else if(c>32)return true;
			}
		}

		public int[] nextIntArray(int n) {
			int[] res = new int[n];
			for(int i = 0; i < n; i++) res[i] = nextInt();
			return res;
		}

	}

}


//package school1;

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

public class E {

	static StreamTokenizer in =
		new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));

	static int nextInt() throws IOException{
		in.nextToken();
		return (int)in.nval;
	}

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

	public static void main(String[] args) throws IOException{
		int a = nextInt(),
			b = nextInt(),
			n = nextInt();

		if (a==1 && Math.pow(2, b)>=n){
			out.println("Missing");
			out.flush();
			return;
		}

		int B[] = new int[100];
		B[1] = n-1;
		int p = (int)Math.sqrt(n);
		if (p*p == n)
			p--;
		B[2] = p;
		for (int i=3; i<=30; i++)
			for (int j=p; j>=2; j--)
				if (Math.pow(j, i) < n){
					B[i] = j;
					p = j;
					break;
				}

		int x = 1000000000,
			y = 1000000000;
		for (int i=b; i<=30; i++)
			if (B[i]!=B[i+1] && B[i]>=a){
				if (i-b == B[i]-a){
					out.println("Stas");
					out.flush();
					return;
				}
				else{
					if (i-b > B[i]-a)
						x = Math.min(x, i-b-(B[i]-a));
					else
						y = Math.min(y, B[i]-a-(i-b));
				}
			}

		if (x%2==0 && y%2==0){
			out.println("Stas");
			out.flush();
			return;
		}
		else if (x%2==1 && y%2==1){
			out.println("Masha");
			out.flush();
			return;
		}

		int u = a, v = b;
		while (Math.pow(u, v) < n){
			u++;
			v++;
		}

		u--;
		v--;
		if (x%2==1 && Math.pow(u, v+1)<n || y%2==1 && Math.pow(u+1, v)<n){
			out.println("Masha");
			out.flush();
			return;
		}
		else{
			out.println("Stas");
			out.flush();
			return;
		}
	}

}


import java.util.Scanner;

public class Sh1E {

    static final int N = 35000, M = 33;
    static Scanner in;
    static int n, a, b;
    static boolean[][] game = new boolean[N][M];

    public static void main(String[] args) {
        in = new Scanner(System.in);
        a = in.nextInt();
        b = in.nextInt();
        n = in.nextInt();
        long pow;
        for (int i = 2; i < N; ++i) {
            pow = (long) i * (long) i;
            for (int j = 2; j < M; ++j) {
                if (pow >= n) {
                    game[i][j] = true;
                } else {
                    pow *= (long) i;
                }
            }
        }
        game[N - 1][1] = true;
        if (n % 2 == 0)
            game[N - 2][1] = true;
        for (int j = M - 2; j >= 1; --j)
            for (int i = N - 2; i >= 2; --i)
                if (!game[i][j]) {
                    if (!game[i + 1][j] || !game[i][j + 1])
                        game[i][j] = true;
                }
        if (a == 1) {
            for (int i = b; i < M; ++i)
                if (!game[2][i]) {
                    if ((i - b) % 2 == 0)
                        System.out.println("Masha");
                    else
                        System.out.println("Stas");
                    return;
                }
            //if (!game[2][b])
            //  System.out.println("Masha");
            //else if (!game[2][b + 1])
            //  System.out.println("Stas");
            //else
            System.out.println("Missing");
        } else {
            if (game[a][b])
                System.out.println("Masha");
            else
                System.out.println("Stas");
        }
    }
}


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

public class Main implements Runnable {
    BufferedReader in;
    PrintWriter out;
    StringTokenizer st;

    int a, b, n;

    int[][] dp;
    BigInteger need;

    int rec(int item, int box) {
        if (item >= 50)
            return 1;
        if (box >= 35000)
            return 1;
        int ret = dp[item][box];
        if (ret == -1) {
            BigInteger a = BigInteger.valueOf(box).pow(item);
            if (a.compareTo(need) >= 0)
                ret = 0;
            else {
                ret = 100;
                ret = min(ret, rec(item, box + 1));
                ret = min(ret, rec(item + 1, box));
            }
            if (ret == 0)
                ret = 1;
            else
                ret = 0;
            dp[item][box] = ret;
        }
        return ret;
    }

    void solve() throws IOException {
        a = ni();
        b = ni();
        n = ni();
        if (a == 1 && (1 << b) >= n) {
            out.println("Missing");
            return;
        }
        dp = new int[50][35000];
        for (int i = 0; i < dp.length; i++) {
            Arrays.fill(dp[i], -1);
        }
        need = BigInteger.valueOf(n);
        int ret = rec(b, a);
        if (ret == 1)
            out.println("Masha");
        else
            out.println("Stas");
    }

    public Main() throws IOException {

    }

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

    int ni() throws IOException {
        return Integer.valueOf(ns());
    }

    long nl() throws IOException {
        return Long.valueOf(ns());
    }

    double nd() throws IOException {
        return Double.valueOf(ns());
    }

    public static void main(String[] args) throws IOException,
            InterruptedException {
        Thread th = new Thread(null, new Main(), "Main", 67108864);
        th.start();
        th.join();
        if (failed)
            throw new RuntimeException();
    }

    static boolean failed = false;

    @Override
    public void run() {
        Locale.setDefault(Locale.US);
        in = new BufferedReader(new InputStreamReader(System.in));
        out = new PrintWriter(System.out);
        try {
            solve();
            in.close();
            out.close();
        } catch (IOException e) {
            failed = true;
        }
    }
}


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

// you can compare with output.txt and expected out
public class RoundEdu132F {
	MyPrintWriter out;
	MyScanner in;

//	final static long FIXED_RANDOM;
//	static {
//		FIXED_RANDOM = System.currentTimeMillis();
//	}
	final static String IMPOSSIBLE = "IMPOSSIBLE";
	final static String POSSIBLE = "POSSIBLE";
	final static String YES = "YES";
	final static String NO = "NO";

    private void initIO(boolean isFileIO) {
        if (System.getProperty("ONLINE_JUDGE") == null && isFileIO) {
        	try{
	            in = new MyScanner(new FileInputStream("input.txt"));
	            out = new MyPrintWriter(new FileOutputStream("output.txt"));
        	}
        	catch(FileNotFoundException e){
        		e.printStackTrace();
        	}
        }
        else{
    		in = new MyScanner(System.in);
    	    out = new MyPrintWriter(new BufferedOutputStream(System.out));
        }
    }

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

		RoundEdu132F sol = new RoundEdu132F();
		sol.run();
    }

	private void run() {
		boolean isDebug = false;
		boolean isFileIO = true;
		boolean hasMultipleTests = false;

		initIO(isFileIO);

		//test();

		int t = hasMultipleTests? in.nextInt() : 1;

	    for (int i = 1; i <= t; ++i) {
	    	if(isDebug){
		    	out.printf("Test %d\n", i);
	    	}

	    	getInput();

	    	ans = solve();

	    	printOutput();
	    }

	    in.close();
	    out.close();
	}

	private void test() {

		long[] poly = {1, 1, 0, 0};
		square(poly);

		poly = poly;

		long[] poly2 = {1, 1, 1, 1, 0, 0, 0, 0};
		square(poly2);

		poly2 = poly2;

	}

	int n, k, f;
	void getInput() {
		n = in.nextInt();
		k = in.nextInt();
		f = in.nextInt();
	}

	void printOutput() {
		out.printlnAns(ans);
	}

	static final long MOD = 998244353;
	int ans;
	int solve(){
		long ans = 0;

		// for each binary string s,
		// consider binary strings t of length n, where s is a prefix of t
		// we can have <= c_s among t

		// it's a full binary tree
		// where each vertex contains # of records in its subtree
		// and all records are at depth n

		// from each leaf, go up again, update each vertex to min(val, val(child1) + val(child2))
		// then the val(root) must be exactly f
		// where root is null string

		// the problem in this counting is we would have to use inclusion-exclusion due to duplicate cases
		// so we choose vertices representing disjoint subtrees
		// whose union can represent the whole tree
		// and whose sum is exactly f

		// for vertices under the subtrees, we can freely choose val
		// so that sum of siblings in each subtree >= val of root of subtree
		// for vertices above the subtrees, we can freely choose val between sum and k

		// so another approach:
		// for each vertex v of depth h
		// find # of ways to make sum exactly x
		// case 1: val(v) = x
		// add up ways(l, y)*ways(r, z) where y+z >= x
		// case 2: val(v) >= x+1
		// add up ways(l, y)*ways(r, z) where y+z = x

		// 2 1 1
		// case 1: c_0 = 1, c_1 = 0
		// 00 01 10 11
		// 1  0  0/1 0/1
		// 0  1  0/1 0/1
		// 1  1  0/1 0/1
		// -> 12

		// case 2: c_0 = 0, c_1 = 1
		// -> 12

		// case 3: c_0 = 1, c_1 = 1
		// 1 0 0 0
		// 0 1 0 0
		// 1 1 0 0
		// 0 0 1 0
		// 0 0 0 1
		// 0 0 1 1
		// -> 6

		// subtree_0 = 1 -> 3
		// c_0 = 1 -> 1 0, 0 1, 1 1

		// subtree_0 = 0 -> 5
		// c_0 = 0 -> 0/1, 0/1 -> 4
		// c_0 = 1 -> 0, 0 -> 1
		// 3*5 + 3*5 = 30

		// subtree_l = 0 -> 1
		// subtree_l = 1 -> 1

		// long[] ways = new long[f+2];
		int len = 1;
		while (len < f+2 + f+2)
	        len <<= 1;
		long[] ways = new long[len];
		long[] suffix = new long[f+2];

		for(int i=0; i<=k && i<=f; i++)
			ways[i] = 1;
		ways[f+1] = Math.max(0, k-f);

//		long[] ways2 = Arrays.copyOf(ways, f+2);

		for(int i=0; i<n; i++) {
			if(i < n-1) {
				square(ways);
				{
					long val = 0;
					for(int j=ways.length-1; j>=f+1; j--)
						val += ways[j];
					val %= MOD;
					suffix[f+1] = val;
				}
				for(int j=f; j>=0; j--){
					long val = suffix[j+1] + ways[j];
					val = val>=MOD? val-MOD: val;
					suffix[j] = val;
				}

				for(int j=0; j <= k && j<=f; j++) {
					long val = suffix[j]; // c_curr = j
					val += ways[j]*(k-j); // j+1 ~ k
					val %= MOD;
					ways[j] = val;
				}
				{
					long val = suffix[f+1]*Math.max(0, k-f);
					val %= MOD;
					ways[f+1] = val;
				}
				for(int j=k+1; j<f+2; j++)
					ways[j] = 0;
				Arrays.fill(ways, f+2, ways.length, 0);

//				long[] mult = multiplyPolynomial(ways2, ways2);
//				{
//					long val = 0;
//					for(int j=mult.length-1; j>=f+1; j--)
//						val += mult[j];
//					val %= MOD;
//					suffix[f+1] = val;
//				}
//				for(int j=f; j>=0; j--){
//					long val = suffix[j+1] + mult[j];
//					val = val>=MOD? val-MOD: val;
//					suffix[j] = val;
//				}
//				if(i < n-1) {
//					for(int j=0; j <= k && j<=f; j++) {
//						long val = suffix[j]; // c_curr = j
//						val += mult[j]*(k-j); // j+1 ~ k
//						val %= MOD;
//						ways2[j] = val;
//					}
//					{
//						long val = suffix[f+1]*Math.max(0, k-f);
//						val %= MOD;
//						ways2[f+1] = val;
//					}
//				}
//				if(!Arrays.equals(Arrays.copyOf(ways, f+2), ways2)) {
//					for(int j=0; j<f+2; j++)
//						if(ways[j] != ways2[j])
//							ways = ways;
//				}
			}
			else {
				for(int j=0; j<=f; j++)
					ans += ways[j]*ways[f-j] % MOD;
				ans %= MOD;
			}
		}

		return (int)ans;
	}

	static long pow(int a, int k, long p) {
		long m = k;
		long ans = 1;

		// curr = k^(2^i)
		long curr = a;

		// k^(2x+1) = (k^x)^2 * k
		while(m > 0) {
			if( (m&1) == 1 ) {
				ans *= curr;
				ans %= p;
			}
			m >>= 1;
			curr *= curr;
			curr %= p;
		}
		return ans;
	}

	// computes a^(p-2)
	static long inverse(int a, long p) {
		return pow(a, (int)(p-2), p);
	}

	// static final long MOD = 998_244_353; // = 1 + 7*17*2^23
	// primitive root is 3, i.e., the order of 3 is MOD-1
	// we have to find the 1<<23-th root
	static final int ROOT = (int) pow(3, 7*17, MOD);
	static final int ROOT_INV = (int) pow(ROOT, (int)MOD - 2, MOD);
	static final int ORDER = 1 << 23;
	static final long W4 = pow(ROOT, (int)(MOD-1)/4, MOD);
	static final long W4_INV = pow(ROOT, (int)(MOD-1)/4*3, MOD);

	static void swap(long[] a, int i, int j) {
		long temp = a[i];
		a[i] = a[j];
		a[j] = temp;
	}
	static void fft(long[] a, boolean isInvertedFFT) {
	    int n = a.length;

	    for (int i = 1, j = 0; i < n; i++) {
	        int bit = n >> 1;
	        for (; (j & bit) > 0; bit >>= 1)
	            j ^= bit;
	        j ^= bit;

	        if (i < j) {
	        	swap(a, i, j);
	        }
	    }

	    for (int len = 2; len <= n; len <<= 1) {
	        long wlen = isInvertedFFT ? ROOT_INV : ROOT;
	        for (int i = len; i < ORDER; i <<= 1)
	            wlen = wlen * wlen % MOD;

	        for (int i = 0; i < n; i += len) {
	        	long w = 1;
	            for (int j = 0; j < len / 2; j++) {
	                long u = a[i+j];
	                long v = a[i+j+len/2] * w % MOD;
	                a[i+j] =  u + v < MOD ? u + v : u + v - MOD;
	                a[i+j+len/2] = u - v >= 0 ? u - v : u - v + MOD;
	                w = w * wlen % MOD;
	            }
	        }
	    }

	    if (isInvertedFFT) {
	        long inv = inverse(n, MOD);
	        for(int i=0; i<a.length; i++)
	        	a[i] = a[i]*inv%MOD;
	    }
	}

	static void fft4(long[] a, boolean isInvertedFFT) {
		int n = a.length;

	    for (int i = 1, j = 0; i < n; i++) {
	        int bit = n >> 1;
	        for (; (j & bit) > 0; bit >>= 1)
	            j ^= bit;
	        j ^= bit;

	        if (i < j) {
	        	swap(a, i, j);
	        }
	    }

		int parity = 0;
	    for (int len = 2; len <= n; len <<= 1)
	    	parity++;

	    int len;
	    if(parity % 2 == 1) {
	    	len = 2;
		    if(len <= n) {
		        long wlen = isInvertedFFT ? ROOT_INV : ROOT;
		        for (int i = len; i < ORDER; i <<= 1)
		            wlen = wlen * wlen % MOD;

		        for (int i = 0; i < n; i += len) {
		        	long w = 1;
		            for (int j = 0; j < len / 2; j++) {
		                long u = a[i+j];
		                long v = a[i+j+len/2] * w % MOD;
		                a[i+j] =  u + v < MOD ? u + v : u + v - MOD;
		                a[i+j+len/2] = u - v >= 0 ? u - v : u - v + MOD;
		                w = w * wlen % MOD;
		            }
		        }
		        len *= 4;
		    }
	    }
	    else
	    	len = 4;

	    for (; len <= n; len <<= 2) {
	        long wlen = isInvertedFFT ? ROOT_INV : ROOT;
	        long w4 = isInvertedFFT? W4_INV: W4;
	        for (int i = len; i < ORDER; i <<= 1)
	            wlen = wlen * wlen % MOD;

	        for (int i = 0; i < n; i += len) {
	        	long w = 1;
	            for (int j = 0; j < len / 4; j++) {
	            	long x0 = a[i+j];
	            	long x1 = a[i+j+len/2] * w % MOD;
	            	long x2 = a[i+j+len/4] * w % MOD;
	            	x2 = x2 * w % MOD;
	            	long x3 = a[i+j+len*3/4] * w % MOD;
	            	x3 = x3 * w % MOD;
	            	x3 = x3 * w % MOD;

	            	long y0 = x0 + x1 + x2 + x3;
	            	a[i+j] = y0 % MOD;
	            	long y1 = x0 + x1*w4 - x2 - x3*w4;
	            	y1 %= MOD;
	            	a[i+j+len*3/4] = y1 < 0? y1 + MOD: y1;
	            	long y2 = x0 - x1 + x2 - x3;
	            	y2 %= MOD;
	            	a[i+j+len/2] = y2 < 0? y2 + MOD: y2;
	            	long y3 = x0 - x1*w4 - x2 + x3*w4;
	            	y3 %= MOD;
	            	a[i+j+len/4] = y3 < 0? y3 + MOD: y3;

	            	w = w * wlen % MOD;
	            }
	        }
	    }

	    if (isInvertedFFT) {
	        long inv = inverse(n, MOD);
	        for(int i=0; i<a.length; i++)
	        	a[i] = a[i]*inv%MOD;
	    }
	}

	static void square(long[] a) {
	    fft4(a, false);
	    for (int i = 0; i < a.length; i++)
	        a[i] = a[i]*a[i] % MOD;
	    fft4(a, true);
	}

	static long[] multiplyPolynomial(long[] a, long[] b) {
	    int n = 1;
	    while (n < a.length + b.length)
	        n <<= 1;
		long[] fa = Arrays.copyOf(a, n);
		long[] fb = Arrays.copyOf(b, n);

	    fft(fa, false);
	    fft(fb, false);
	    for (int i = 0; i < n; i++)
	        fa[i] = fa[i]*fb[i] % MOD;
	    fft(fa, true);

	    return fa;
	}

	public static class MyScanner {
		BufferedReader br;
		StringTokenizer st;

		// 32768?
		public MyScanner(InputStream is, int bufferSize) {
			br = new BufferedReader(new InputStreamReader(is), bufferSize);
		}

		public MyScanner(InputStream is) {
			br = new BufferedReader(new InputStreamReader(is));
			// br = new BufferedReader(new InputStreamReader(System.in));
			// br = new BufferedReader(new InputStreamReader(new FileInputStream("input.txt")));
		}

		public void close() {
			try {
				br.close();
			} catch (IOException e) {
				e.printStackTrace();
			}

		}

		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;
		}

		int[][] nextTreeEdges(int n, int offset){
			int[][] e = new int[n-1][2];
			for(int i=0; i<n-1; i++){
				e[i][0] = nextInt()+offset;
				e[i][1] = nextInt()+offset;
			}
			return e;
		}

		int[][] nextMatrix(int n, int m) {
			return nextMatrix(n, m, 0);
		}

		int[][] nextMatrix(int n, int m, int offset) {
			int[][] mat = new int[n][m];
			for(int i=0; i<n; i++) {
				for(int j=0; j<m; j++) {
					mat[i][j] = nextInt()+offset;
				}
			}
			return mat;
		}

		int[][] nextPairs(int n){
			return nextPairs(n, 0);
		}

		int[][] nextPairs(int n, int offset) {
			int[][] xy = new int[2][n];
			for(int i=0; i<n; i++) {
				xy[0][i] = nextInt() + offset;
				xy[1][i] = nextInt() + offset;
			}
			return xy;
		}

		int[][] nextGraphEdges(){
			return nextGraphEdges(0);
		}

		int[][] nextGraphEdges(int offset) {
			int m = nextInt();
			int[][] e = new int[m][2];
			for(int i=0; i<m; i++){
				e[i][0] = nextInt()+offset;
				e[i][1] = nextInt()+offset;
			}
			return e;
		}

		int[] nextIntArray(int len) {
			return nextIntArray(len, 0);
		}
		int[] nextIntArray(int len, int offset){
	    	int[] a = new int[len];
			for(int j=0; j<len; j++)
	    		a[j] = nextInt()+offset;
	    	return a;
		}

		long[] nextLongArray(int len) {
			return nextLongArray(len, 0);
		}
		long[] nextLongArray(int len, int offset){
	    	long[] a = new long[len];
			for(int j=0; j<len; j++)
	    		a[j] = nextLong()+offset;
	    	return a;
		}
	}

	public static class MyPrintWriter extends PrintWriter{
		public MyPrintWriter(OutputStream os) {
			super(os);
		}

		public void printlnAns(long ans) {
			println(ans);
		}

		public void printlnAns(int ans) {
			println(ans);
		}

		public void printlnAns(boolean ans) {
			if(ans)
				println(YES);
			else
				println(NO);
		}

		public void printAns(long[] arr){
			if(arr != null && arr.length > 0){
				print(arr[0]);
				for(int i=1; i<arr.length; i++){
					print(" ");
					print(arr[i]);
				}
			}
		}
		public void printlnAns(long[] arr){
			printAns(arr);
			println();
		}

		public void printAns(int[] arr){
			if(arr != null && arr.length > 0){
				print(arr[0]);
				for(int i=1; i<arr.length; i++){
					print(" ");
					print(arr[i]);
				}
			}
		}
		public void printlnAns(int[] arr){
			printAns(arr);
			println();
		}

		public <T> void printAns(ArrayList<T> arr){
			if(arr != null && arr.size() > 0){
				print(arr.get(0));
				for(int i=1; i<arr.size(); i++){
					print(" ");
					print(arr.get(i));
				}
			}
		}
		public <T> void printlnAns(ArrayList<T> arr){
			printAns(arr);
			println();
		}

		public void printAns(int[] arr, int add){
			if(arr != null && arr.length > 0){
				print(arr[0]+add);
				for(int i=1; i<arr.length; i++){
					print(" ");
					print(arr[i]+add);
				}
			}
		}
		public void printlnAns(int[] arr, int add){
			printAns(arr, add);
			println();
		}

		public void printAns(ArrayList<Integer> arr, int add) {
			if(arr != null && arr.size() > 0){
				print(arr.get(0)+add);
				for(int i=1; i<arr.size(); i++){
					print(" ");
					print(arr.get(i)+add);
				}
			}
		}

		public void printlnAns(ArrayList<Integer> arr, int add){
			printAns(arr, add);
			println();
		}

		public void printlnAnsSplit(long[] arr, int split){
			if(arr != null){
				for(int i=0; i<arr.length; i+=split){
					print(arr[i]);
					for(int j=i+1; j<i+split; j++){
						print(" ");
						print(arr[j]);
					}
					println();
				}
			}
		}

		public void printlnAnsSplit(int[] arr, int split){
			if(arr != null){
				for(int i=0; i<arr.length; i+=split){
					print(arr[i]);
					for(int j=i+1; j<i+split; j++){
						print(" ");
						print(arr[j]);
					}
					println();
				}
			}
		}

		public <T> void printlnAnsSplit(ArrayList<T> arr, int split){
			if(arr != null && !arr.isEmpty()){
				for(int i=0; i<arr.size(); i+=split){
					print(arr.get(i));
					for(int j=i+1; j<i+split; j++){
						print(" ");
						print(arr.get(j));
					}
					println();
				}
			}
		}
	}

	static private void permutateAndSort(long[] a) {
		int n = a.length;
		Random R = new Random(System.currentTimeMillis());
		for(int i=0; i<n; i++) {
			int t = R.nextInt(n-i);
			long temp = a[n-1-i];
			a[n-1-i] = a[t];
			a[t] = temp;
		}
		Arrays.sort(a);
	}

	static private void permutateAndSort(int[] a) {
		int n = a.length;
		Random R = new Random(System.currentTimeMillis());
		for(int i=0; i<n; i++) {
			int t = R.nextInt(n-i);
			int temp = a[n-1-i];
			a[n-1-i] = a[t];
			a[t] = temp;
		}
		Arrays.sort(a);
	}

	static private int[][] constructChildren(int n, int[] parent, int parentRoot){
		int[][] childrens = new int[n][];

		int[] numChildren = new int[n];
		for(int i=0; i<parent.length; i++) {
			if(parent[i] != parentRoot)
				numChildren[parent[i]]++;
		}

		for(int i=0; i<n; i++) {
			childrens[i] = new int[numChildren[i]];
		}

		int[] idx = new int[n];
		for(int i=0; i<parent.length; i++) {
			if(parent[i] != parentRoot)
				childrens[parent[i]][idx[parent[i]]++] = i;
		}

		return childrens;
	}

	static private int[][][] constructDirectedNeighborhood(int n, int[][] e){
		int[] inDegree = new int[n];
		int[] outDegree = new int[n];
		for(int i=0; i<e.length; i++) {
			int u = e[i][0];
			int v = e[i][1];
			outDegree[u]++;
			inDegree[v]++;
		}

		int[][] inNeighbors = new int[n][];
		int[][] outNeighbors = new int[n][];
		for(int i=0; i<n; i++) {
			inNeighbors[i] = new int[inDegree[i]];
			outNeighbors[i] = new int[outDegree[i]];
		}

		int[] inIdx = new int[n];
		int[] outIdx = new int[n];
		for(int i=0; i<e.length; i++) {
			int u = e[i][0];
			int v = e[i][1];
			outNeighbors[u][outIdx[u]++] = v;
			inNeighbors[v][inIdx[v]++] = u;
		}

		return new int[][][] {inNeighbors, outNeighbors};
	}

	static private int[][] constructNeighborhood(int n, int[][] e) {
		int[] degree = new int[n];
		for(int i=0; i<e.length; i++) {
			int u = e[i][0];
			int v = e[i][1];
			degree[u]++;
			degree[v]++;
		}

		int[][] neighbors = new int[n][];
		for(int i=0; i<n; i++)
			neighbors[i] = new int[degree[i]];

		int[] idx = new int[n];
		for(int i=0; i<e.length; i++) {
			int u = e[i][0];
			int v = e[i][1];
			neighbors[u][idx[u]++] = v;
			neighbors[v][idx[v]++] = u;
		}

		return neighbors;
	}

	static private void drawGraph(int[][] e) {
		makeDotUndirected(e);
		try {
			final Process process = new ProcessBuilder("dot", "-Tpng", "graph.dot")
					.redirectOutput(new File("graph.png"))
					.start();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

	}

	static private void makeDotUndirected(int[][] e) {
		MyPrintWriter out2 = null;
		 try {
			out2 = new MyPrintWriter(new FileOutputStream("graph.dot"));
		} catch (FileNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		out2.println("strict graph {");
		for(int i=0; i<e.length; i++){
			out2.println(e[i][0] + "--" + e[i][1] + ";");
		}
		out2.println("}");
		out2.close();
	}

	static private void makeDotDirected(int[][] e) {
		MyPrintWriter out2 = null;
		 try {
			out2 = new MyPrintWriter(new FileOutputStream("graph.dot"));
		} catch (FileNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		out2.println("strict digraph {");
		for(int i=0; i<e.length; i++){
			out2.println(e[i][0] + "->" + e[i][1] + ";");
		}
		out2.println("}");
		out2.close();
	}

}


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

// you can compare with output.txt and expected out
public class RoundEdu132F {
	MyPrintWriter out;
	MyScanner in;

//	final static long FIXED_RANDOM;
//	static {
//		FIXED_RANDOM = System.currentTimeMillis();
//	}
	final static String IMPOSSIBLE = "IMPOSSIBLE";
	final static String POSSIBLE = "POSSIBLE";
	final static String YES = "YES";
	final static String NO = "NO";

    private void initIO(boolean isFileIO) {
        if (System.getProperty("ONLINE_JUDGE") == null && isFileIO) {
        	try{
	            in = new MyScanner(new FileInputStream("input.txt"));
	            out = new MyPrintWriter(new FileOutputStream("output.txt"));
        	}
        	catch(FileNotFoundException e){
        		e.printStackTrace();
        	}
        }
        else{
    		in = new MyScanner(System.in);
    	    out = new MyPrintWriter(new BufferedOutputStream(System.out));
        }
    }

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

		RoundEdu132F sol = new RoundEdu132F();
		sol.run();
    }

	private void run() {
		boolean isDebug = false;
		boolean isFileIO = true;
		boolean hasMultipleTests = false;

		initIO(isFileIO);

		int t = hasMultipleTests? in.nextInt() : 1;

	    for (int i = 1; i <= t; ++i) {
	    	if(isDebug){
		    	out.printf("Test %d\n", i);
	    	}

	    	getInput();

	    	ans = solve();

	    	printOutput();
	    }

	    in.close();
	    out.close();
	}

	int n, k, f;
	void getInput() {
		n = in.nextInt();
		k = in.nextInt();
		f = in.nextInt();
	}

	void printOutput() {
		out.printlnAns(ans);
	}

	static final long MOD = 998244353;
	int ans;
	int solve(){
		long ans = 0;

		// for each binary string s,
		// consider binary strings t of length n, where s is a prefix of t
		// we can have <= c_s among t

		// it's a full binary tree
		// where each vertex contains # of records in its subtree
		// and all records are at depth n

		// from each leaf, go up again, update each vertex to min(val, val(child1) + val(child2))
		// then the val(root) must be exactly f
		// where root is null string

		// the problem in this counting is we would have to use inclusion-exclusion due to duplicate cases
		// so we choose vertices representing disjoint subtrees
		// whose union can represent the whole tree
		// and whose sum is exactly f

		// for vertices under the subtrees, we can freely choose val
		// so that sum of siblings in each subtree >= val of root of subtree
		// for vertices above the subtrees, we can freely choose val between sum and k

		// so another approach:
		// for each vertex v of depth h
		// find # of ways to make sum exactly x
		// case 1: val(v) = x
		// add up ways(l, y)*ways(r, z) where y+z >= x
		// case 2: val(v) >= x+1
		// add up ways(l, y)*ways(r, z) where y+z = x

		// 2 1 1
		// case 1: c_0 = 1, c_1 = 0
		// 00 01 10 11
		// 1  0  0/1 0/1
		// 0  1  0/1 0/1
		// 1  1  0/1 0/1
		// -> 12

		// case 2: c_0 = 0, c_1 = 1
		// -> 12

		// case 3: c_0 = 1, c_1 = 1
		// 1 0 0 0
		// 0 1 0 0
		// 1 1 0 0
		// 0 0 1 0
		// 0 0 0 1
		// 0 0 1 1
		// -> 6

		// subtree_0 = 1 -> 3
		// c_0 = 1 -> 1 0, 0 1, 1 1

		// subtree_0 = 0 -> 5
		// c_0 = 0 -> 0/1, 0/1 -> 4
		// c_0 = 1 -> 0, 0 -> 1
		// 3*5 + 3*5 = 30

		// subtree_l = 0 -> 1
		// subtree_l = 1 -> 1

		// long[] ways = new long[f+2];
		int len = 1;
		while (len < f+2 + f+2)
	        len <<= 1;
		long[] ways = new long[len];
		long[] suffix = new long[f+2];

		for(int i=0; i<=k && i<=f; i++)
			ways[i] = 1;
		ways[f+1] = Math.max(0, k-f);

//		long[] ways2 = Arrays.copyOf(ways, f+2);

		for(int i=0; i<n; i++) {
			if(i < n-1) {
				square(ways);
				{
					long val = 0;
					for(int j=ways.length-1; j>=f+1; j--)
						val += ways[j];
					val %= MOD;
					suffix[f+1] = val;
				}
				for(int j=f; j>=0; j--){
					long val = suffix[j+1] + ways[j];
					val = val>=MOD? val-MOD: val;
					suffix[j] = val;
				}

				for(int j=0; j <= k && j<=f; j++) {
					long val = suffix[j]; // c_curr = j
					val += ways[j]*(k-j); // j+1 ~ k
					val %= MOD;
					ways[j] = val;
				}
				{
					long val = suffix[f+1]*Math.max(0, k-f);
					val %= MOD;
					ways[f+1] = val;
				}
				for(int j=k+1; j<f+2; j++)
					ways[j] = 0;
				Arrays.fill(ways, f+2, ways.length, 0);

//				long[] mult = multiplyPolynomial(ways2, ways2);
//				{
//					long val = 0;
//					for(int j=mult.length-1; j>=f+1; j--)
//						val += mult[j];
//					val %= MOD;
//					suffix[f+1] = val;
//				}
//				for(int j=f; j>=0; j--){
//					long val = suffix[j+1] + mult[j];
//					val = val>=MOD? val-MOD: val;
//					suffix[j] = val;
//				}
//				if(i < n-1) {
//					for(int j=0; j <= k && j<=f; j++) {
//						long val = suffix[j]; // c_curr = j
//						val += mult[j]*(k-j); // j+1 ~ k
//						val %= MOD;
//						ways2[j] = val;
//					}
//					{
//						long val = suffix[f+1]*Math.max(0, k-f);
//						val %= MOD;
//						ways2[f+1] = val;
//					}
//				}
//				if(!Arrays.equals(Arrays.copyOf(ways, f+2), ways2)) {
//					for(int j=0; j<f+2; j++)
//						if(ways[j] != ways2[j])
//							ways = ways;
//				}
			}
			else {
				for(int j=0; j<=f; j++)
					ans += ways[j]*ways[f-j] % MOD;
				ans %= MOD;
			}
		}

		return (int)ans;
	}

	static long pow(int a, int k, long p) {
		long m = k;
		long ans = 1;

		// curr = k^(2^i)
		long curr = a;

		// k^(2x+1) = (k^x)^2 * k
		while(m > 0) {
			if( (m&1) == 1 ) {
				ans *= curr;
				ans %= p;
			}
			m >>= 1;
			curr *= curr;
			curr %= p;
		}
		return ans;
	}

	// computes a^(p-2)
	static long inverse(int a, long p) {
		return pow(a, (int)(p-2), p);
	}

	// static final long MOD = 998_244_353; // = 1 + 7*17*2^23
	// primitive root is 3, i.e., the order of 3 is MOD-1
	// we have to find the 1<<23-th root
	static final int ROOT = (int) pow(3, 7*17, MOD);
	static final int ROOT_INV = (int) pow(ROOT, (int)MOD - 2, MOD);
	static final int ORDER = 1 << 23;

	static void swap(long[] a, int i, int j) {
		long temp = a[i];
		a[i] = a[j];
		a[j] = temp;
	}
	static void fft(long[] a, boolean isInvertedFFT) {
	    int n = a.length;

	    for (int i = 1, j = 0; i < n; i++) {
	        int bit = n >> 1;
	        for (; (j & bit) > 0; bit >>= 1)
	            j ^= bit;
	        j ^= bit;

	        if (i < j) {
	        	swap(a, i, j);
	        }
	    }

	    for (int len = 2; len <= n; len <<= 1) {
	        long wlen = isInvertedFFT ? ROOT_INV : ROOT;
	        for (int i = len; i < ORDER; i <<= 1)
	            wlen = wlen * wlen % MOD;

	        for (int i = 0; i < n; i += len) {
	        	long w = 1;
	            for (int j = 0; j < len / 2; j++) {
	                long u = a[i+j];
	                long v = a[i+j+len/2] * w % MOD;
	                a[i+j] =  u + v < MOD ? u + v : u + v - MOD;
	                a[i+j+len/2] = u - v >= 0 ? u - v : u - v + MOD;
	                w = w * wlen % MOD;
	            }
	        }
	    }

	    if (isInvertedFFT) {
	        long inv = inverse(n, MOD);
	        for(int i=0; i<a.length; i++)
	        	a[i] = a[i]*inv%MOD;
	    }
	}

	static void square(long[] a) {
	    fft(a, false);
	    for (int i = 0; i < a.length; i++)
	        a[i] = a[i]*a[i] % MOD;
	    fft(a, true);
	}

	static long[] multiplyPolynomial(long[] a, long[] b) {
	    int n = 1;
	    while (n < a.length + b.length)
	        n <<= 1;
		long[] fa = Arrays.copyOf(a, n);
		long[] fb = Arrays.copyOf(b, n);

	    fft(fa, false);
	    fft(fb, false);
	    for (int i = 0; i < n; i++)
	        fa[i] = fa[i]*fb[i] % MOD;
	    fft(fa, true);

	    return fa;
	}

	public static class MyScanner {
		BufferedReader br;
		StringTokenizer st;

		// 32768?
		public MyScanner(InputStream is, int bufferSize) {
			br = new BufferedReader(new InputStreamReader(is), bufferSize);
		}

		public MyScanner(InputStream is) {
			br = new BufferedReader(new InputStreamReader(is));
			// br = new BufferedReader(new InputStreamReader(System.in));
			// br = new BufferedReader(new InputStreamReader(new FileInputStream("input.txt")));
		}

		public void close() {
			try {
				br.close();
			} catch (IOException e) {
				e.printStackTrace();
			}

		}

		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;
		}

		int[][] nextTreeEdges(int n, int offset){
			int[][] e = new int[n-1][2];
			for(int i=0; i<n-1; i++){
				e[i][0] = nextInt()+offset;
				e[i][1] = nextInt()+offset;
			}
			return e;
		}

		int[][] nextMatrix(int n, int m) {
			return nextMatrix(n, m, 0);
		}

		int[][] nextMatrix(int n, int m, int offset) {
			int[][] mat = new int[n][m];
			for(int i=0; i<n; i++) {
				for(int j=0; j<m; j++) {
					mat[i][j] = nextInt()+offset;
				}
			}
			return mat;
		}

		int[][] nextPairs(int n){
			return nextPairs(n, 0);
		}

		int[][] nextPairs(int n, int offset) {
			int[][] xy = new int[2][n];
			for(int i=0; i<n; i++) {
				xy[0][i] = nextInt() + offset;
				xy[1][i] = nextInt() + offset;
			}
			return xy;
		}

		int[][] nextGraphEdges(){
			return nextGraphEdges(0);
		}

		int[][] nextGraphEdges(int offset) {
			int m = nextInt();
			int[][] e = new int[m][2];
			for(int i=0; i<m; i++){
				e[i][0] = nextInt()+offset;
				e[i][1] = nextInt()+offset;
			}
			return e;
		}

		int[] nextIntArray(int len) {
			return nextIntArray(len, 0);
		}
		int[] nextIntArray(int len, int offset){
	    	int[] a = new int[len];
			for(int j=0; j<len; j++)
	    		a[j] = nextInt()+offset;
	    	return a;
		}

		long[] nextLongArray(int len) {
			return nextLongArray(len, 0);
		}
		long[] nextLongArray(int len, int offset){
	    	long[] a = new long[len];
			for(int j=0; j<len; j++)
	    		a[j] = nextLong()+offset;
	    	return a;
		}
	}

	public static class MyPrintWriter extends PrintWriter{
		public MyPrintWriter(OutputStream os) {
			super(os);
		}

		public void printlnAns(long ans) {
			println(ans);
		}

		public void printlnAns(int ans) {
			println(ans);
		}

		public void printlnAns(boolean ans) {
			if(ans)
				println(YES);
			else
				println(NO);
		}

		public void printAns(long[] arr){
			if(arr != null && arr.length > 0){
				print(arr[0]);
				for(int i=1; i<arr.length; i++){
					print(" ");
					print(arr[i]);
				}
			}
		}
		public void printlnAns(long[] arr){
			printAns(arr);
			println();
		}

		public void printAns(int[] arr){
			if(arr != null && arr.length > 0){
				print(arr[0]);
				for(int i=1; i<arr.length; i++){
					print(" ");
					print(arr[i]);
				}
			}
		}
		public void printlnAns(int[] arr){
			printAns(arr);
			println();
		}

		public <T> void printAns(ArrayList<T> arr){
			if(arr != null && arr.size() > 0){
				print(arr.get(0));
				for(int i=1; i<arr.size(); i++){
					print(" ");
					print(arr.get(i));
				}
			}
		}
		public <T> void printlnAns(ArrayList<T> arr){
			printAns(arr);
			println();
		}

		public void printAns(int[] arr, int add){
			if(arr != null && arr.length > 0){
				print(arr[0]+add);
				for(int i=1; i<arr.length; i++){
					print(" ");
					print(arr[i]+add);
				}
			}
		}
		public void printlnAns(int[] arr, int add){
			printAns(arr, add);
			println();
		}

		public void printAns(ArrayList<Integer> arr, int add) {
			if(arr != null && arr.size() > 0){
				print(arr.get(0)+add);
				for(int i=1; i<arr.size(); i++){
					print(" ");
					print(arr.get(i)+add);
				}
			}
		}

		public void printlnAns(ArrayList<Integer> arr, int add){
			printAns(arr, add);
			println();
		}

		public void printlnAnsSplit(long[] arr, int split){
			if(arr != null){
				for(int i=0; i<arr.length; i+=split){
					print(arr[i]);
					for(int j=i+1; j<i+split; j++){
						print(" ");
						print(arr[j]);
					}
					println();
				}
			}
		}

		public void printlnAnsSplit(int[] arr, int split){
			if(arr != null){
				for(int i=0; i<arr.length; i+=split){
					print(arr[i]);
					for(int j=i+1; j<i+split; j++){
						print(" ");
						print(arr[j]);
					}
					println();
				}
			}
		}

		public <T> void printlnAnsSplit(ArrayList<T> arr, int split){
			if(arr != null && !arr.isEmpty()){
				for(int i=0; i<arr.size(); i+=split){
					print(arr.get(i));
					for(int j=i+1; j<i+split; j++){
						print(" ");
						print(arr.get(j));
					}
					println();
				}
			}
		}
	}

	static private void permutateAndSort(long[] a) {
		int n = a.length;
		Random R = new Random(System.currentTimeMillis());
		for(int i=0; i<n; i++) {
			int t = R.nextInt(n-i);
			long temp = a[n-1-i];
			a[n-1-i] = a[t];
			a[t] = temp;
		}
		Arrays.sort(a);
	}

	static private void permutateAndSort(int[] a) {
		int n = a.length;
		Random R = new Random(System.currentTimeMillis());
		for(int i=0; i<n; i++) {
			int t = R.nextInt(n-i);
			int temp = a[n-1-i];
			a[n-1-i] = a[t];
			a[t] = temp;
		}
		Arrays.sort(a);
	}

	static private int[][] constructChildren(int n, int[] parent, int parentRoot){
		int[][] childrens = new int[n][];

		int[] numChildren = new int[n];
		for(int i=0; i<parent.length; i++) {
			if(parent[i] != parentRoot)
				numChildren[parent[i]]++;
		}

		for(int i=0; i<n; i++) {
			childrens[i] = new int[numChildren[i]];
		}

		int[] idx = new int[n];
		for(int i=0; i<parent.length; i++) {
			if(parent[i] != parentRoot)
				childrens[parent[i]][idx[parent[i]]++] = i;
		}

		return childrens;
	}

	static private int[][][] constructDirectedNeighborhood(int n, int[][] e){
		int[] inDegree = new int[n];
		int[] outDegree = new int[n];
		for(int i=0; i<e.length; i++) {
			int u = e[i][0];
			int v = e[i][1];
			outDegree[u]++;
			inDegree[v]++;
		}

		int[][] inNeighbors = new int[n][];
		int[][] outNeighbors = new int[n][];
		for(int i=0; i<n; i++) {
			inNeighbors[i] = new int[inDegree[i]];
			outNeighbors[i] = new int[outDegree[i]];
		}

		int[] inIdx = new int[n];
		int[] outIdx = new int[n];
		for(int i=0; i<e.length; i++) {
			int u = e[i][0];
			int v = e[i][1];
			outNeighbors[u][outIdx[u]++] = v;
			inNeighbors[v][inIdx[v]++] = u;
		}

		return new int[][][] {inNeighbors, outNeighbors};
	}

	static private int[][] constructNeighborhood(int n, int[][] e) {
		int[] degree = new int[n];
		for(int i=0; i<e.length; i++) {
			int u = e[i][0];
			int v = e[i][1];
			degree[u]++;
			degree[v]++;
		}

		int[][] neighbors = new int[n][];
		for(int i=0; i<n; i++)
			neighbors[i] = new int[degree[i]];

		int[] idx = new int[n];
		for(int i=0; i<e.length; i++) {
			int u = e[i][0];
			int v = e[i][1];
			neighbors[u][idx[u]++] = v;
			neighbors[v][idx[v]++] = u;
		}

		return neighbors;
	}

	static private void drawGraph(int[][] e) {
		makeDotUndirected(e);
		try {
			final Process process = new ProcessBuilder("dot", "-Tpng", "graph.dot")
					.redirectOutput(new File("graph.png"))
					.start();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

	}

	static private void makeDotUndirected(int[][] e) {
		MyPrintWriter out2 = null;
		 try {
			out2 = new MyPrintWriter(new FileOutputStream("graph.dot"));
		} catch (FileNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		out2.println("strict graph {");
		for(int i=0; i<e.length; i++){
			out2.println(e[i][0] + "--" + e[i][1] + ";");
		}
		out2.println("}");
		out2.close();
	}

	static private void makeDotDirected(int[][] e) {
		MyPrintWriter out2 = null;
		 try {
			out2 = new MyPrintWriter(new FileOutputStream("graph.dot"));
		} catch (FileNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		out2.println("strict digraph {");
		for(int i=0; i<e.length; i++){
			out2.println(e[i][0] + "->" + e[i][1] + ";");
		}
		out2.println("}");
		out2.close();
	}

}


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

public class E {

	static final int[] DX = { -1, 0, 1, 0 };
	static final int[] DY = { 0, -1, 0, 1 };

	static final int P = 1_000_000_007;

	static final int CACHE_SIZE = 1 << 19;
	int[] cacheInv = new int[CACHE_SIZE];
	{
		cacheInv[1] = 1;
		for (int i = 2; i < CACHE_SIZE; i++) {
			cacheInv[i] = P - (int) ((long) (P / i) * cacheInv[P % i] % P);
		}
	}

	int inv(int x) {
		return x < CACHE_SIZE ? cacheInv[x] : P
				- (int) ((long) (P / x) * inv(P % x) % P);
	}

	void submit() {
		// long start = System.currentTimeMillis();
		int r = nextInt();
		int[] byDir = new int[4];
		int sum = 0;
		for (int i = 0; i < 4; i++) {
			byDir[i] = nextInt();
			sum += byDir[i];
		}

		int invSum = inv(sum);

		for (int i = 0; i < 4; i++) {
			byDir[i] = (int) ((long) byDir[i] * invSum % P);
		}

		int s = 2 * r + 3;

		int[][] f = new int[s][s];
		int[] cx = new int[s * s];
		int[] cy = new int[s * s];
		int vars = 0;
		for (int i = 0; i < s; i++) {
			for (int j = 0; j < s; j++) {
				int sum2 = (i - r - 1) * (i - r - 1) + (j - r - 1)
						* (j - r - 1);
				if (sum2 <= r * r) {
					cx[vars] = i;
					cy[vars] = j;
					f[i][j] = vars++;
				} else {
					f[i][j] = -1;
				}
			}
		}

		int band = 0;

		for (int i = 0; i < vars; i++) {
			int x0 = cx[i];
			int y0 = cy[i];
			for (int dir = 0; dir < 4; dir++) {
				int x1 = x0 + DX[dir];
				int y1 = y0 + DY[dir];
				if (f[x1][y1] == -1) {
					continue;
				}
				int j = f[x1][y1];
				band = Math.max(band, Math.abs(i - j));
			}
		}

		int[][] bandM = new int[vars][2 * band + 1];

		for (int i = 0; i < vars; i++) {
			int x0 = cx[i];
			int y0 = cy[i];
			for (int dir = 0; dir < 4; dir++) {
				int x1 = x0 + DX[dir];
				int y1 = y0 + DY[dir];
				if (f[x1][y1] == -1) {
					continue;
				}
				int j = f[x1][y1];

				updateBandedMatrix(i, j, band, bandM, byDir[dir]);

			}
		}

		for (int i = 0; i < vars; i++) {
			for (int d = 0; d <= 2 * band; d++) {
				int j = i + d - band;
				bandM[i][d] = (i == j ? 1 : 0) - bandM[i][d];
				if (bandM[i][d] < 0) {
					bandM[i][d] += P;
				}
			}
		}

		// out.println(System.currentTimeMillis() - start);

		int[] ans = inverseBanded(bandM, band, f[r + 1][r + 1]);

		// out.println(System.currentTimeMillis() - start);

		int ret = 0;
		for (int x : ans) {
			ret += x;
			if (ret >= P) {
				ret -= P;
			}
		}

		out.println(ret);

	}

	void updateBandedMatrix(int row, int col, int width, int[][] m, double delta) {
		if (Math.abs(row - col) > width) {
			throw new AssertionError();
		}
		m[row][col - row + width] += delta;
	}

	int[] inverseBanded(int[][] a, int w, int whatCol) {
		int n = a.length;
		if (whatCol > n) {
			throw new AssertionError();
		}
		int[] b = new int[n];
		b[whatCol] = 1;

		for (int j = 0; j < n; j++) {
			int[] aj = a[j];
			for (int i = j + 1; i <= j + w && i < n; i++) {
				int[] ai = a[i];
				int coef = (int) ((long) ai[j - i + w] * inv(aj[w]) % P);

				if (coef == 0) {
					continue;
				}

				int kwiUpTo = Math.min(n, j + w + 1) + w - i;

//				for (int k = j + 1, kwi = (j + 1) + w - i; k < kUpTo; k++, kwi++) {
				for (int kwi = (j + 1) + w - i; kwi < kwiUpTo; kwi++) {
					int kek = ai[kwi]
							- (int) ((long) aj[kwi + i - j] * coef % P);
					if (kek < 0) {
						kek += P;
					}
					ai[kwi] = kek;
				}
				b[i] -= (int) ((long) b[j] * coef % P);
				if (b[i] < 0) {
					b[i] += P;
				}
			}
		}

		for (int i = n - 1; i >= 0; i--) {
			long tot = 0;
			for (int j = i + 1; j < n && j <= i + w; j++) {
				tot += (long) b[j] * a[i][j - i + w];
				if (tot >= P2) {
					tot -= P2;
				}
			}
			b[i] -= (int) (tot % P);
			if (b[i] < 0) {
				b[i] += P;
			}
			b[i] = (int) ((long) b[i] * inv(a[i][w]) % P);
		}

		return b;
	}

	static final long P2 = (long) P * P;

	void preCalc() {

	}

	void test() {

	}

	void stress() {
		for (int tst = 0;; tst++) {
			if (false) {
				throw new AssertionError();
			}
			System.err.println(tst);
		}
	}

	E() throws IOException {
		is = System.in;
		out = new PrintWriter(System.out);
		preCalc();
		submit();
		// stress();
		// test();
		out.close();
	}

	static final Random rng = new Random();
	static final int C = 5;

	static int rand(int l, int r) {
		return l + rng.nextInt(r - l + 1);
	}

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

	private InputStream is;
	PrintWriter out;

	private byte[] buf = new byte[1 << 14];
	private int bufSz = 0, bufPtr = 0;

	private int readByte() {
		if (bufSz == -1)
			throw new RuntimeException("Reading past EOF");
		if (bufPtr >= bufSz) {
			bufPtr = 0;
			try {
				bufSz = is.read(buf);
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
			if (bufSz <= 0)
				return -1;
		}
		return buf[bufPtr++];
	}

	private boolean isTrash(int c) {
		return c < 33 || c > 126;
	}

	private int skip() {
		int b;
		while ((b = readByte()) != -1 && isTrash(b))
			;
		return b;
	}

	String nextToken() {
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while (!isTrash(b)) {
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	String nextString() {
		int b = readByte();
		StringBuilder sb = new StringBuilder();
		while (!isTrash(b) || b == ' ') {
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

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

	char nextChar() {
		return (char) skip();
	}

	int nextInt() {
		int ret = 0;
		int b = skip();
		if (b != '-' && (b < '0' || b > '9')) {
			throw new InputMismatchException();
		}
		boolean neg = false;
		if (b == '-') {
			neg = true;
			b = readByte();
		}
		while (true) {
			if (b >= '0' && b <= '9') {
				ret = ret * 10 + (b - '0');
			} else {
				if (b != -1 && !isTrash(b)) {
					throw new InputMismatchException();
				}
				return neg ? -ret : ret;
			}
			b = readByte();
		}
	}

	long nextLong() {
		long ret = 0;
		int b = skip();
		if (b != '-' && (b < '0' || b > '9')) {
			throw new InputMismatchException();
		}
		boolean neg = false;
		if (b == '-') {
			neg = true;
			b = readByte();
		}
		while (true) {
			if (b >= '0' && b <= '9') {
				ret = ret * 10 + (b - '0');
			} else {
				if (b != -1 && !isTrash(b)) {
					throw new InputMismatchException();
				}
				return neg ? -ret : ret;
			}
			b = readByte();
		}
	}
}


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

public class Main {

	public static class FastReader {
		BufferedReader br;
		StringTokenizer root;

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

		String next() {
			while (root == null || !root.hasMoreTokens()) {
				try {
					root = new StringTokenizer(br.readLine());
				} catch (Exception addd) {
					addd.printStackTrace();
				}
			}
			return root.nextToken();
		}

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

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

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

		String nextLine() {
			String str = "";
			try {
				str = br.readLine();
			} catch (Exception addd) {
				addd.printStackTrace();
			}
			return str;
		}
	}

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

	public static FastReader sc = new FastReader();

	static int mod = (int) (1e9+7),MAX=(int) (2e5);
    static List<Integer>[] edges;

	public static void main(String[] args){
		 int b = sc.nextInt();
		 int d = sc.nextInt();
		 char[] a = sc.next().toCharArray();
		 char[] c = sc.next().toCharArray();
		 int m = a.length;
		 int n = c.length;
		 int[] dp = new int[n]; // starting from i idx max len of C we can match in A
		 for(int i=0;i<n;++i) {
			 int cnt = 0;
			 for(int j=0;j<m;++j) {
				 if(c[(i+cnt)%n] == a[j]) ++cnt;
			 }
			 dp[i] = cnt;
		 }

		 long totalChars = 0;
		 int idx = 0;
		 for(int i=1;i<=b;++i) {
			 totalChars+=dp[idx];
			 idx = (idx + dp[idx])%n;
		 }
		 long strs = totalChars/n;
		 long p = strs/d;
		 out.print(p);

	    out.close();
	}

}


import java.util.*;

public class TaskD {
    public static void main(String[] args) {
        new TaskD().solve();
    }

    TaskD() {
    }

    int b, d, lenA, lenC;
    String a, c;
    int[][] next, delta;

    public void solve() {
        Scanner in = new Scanner(System.in);
        b = in.nextInt();
        d = in.nextInt();
        a = in.next();
        c = in.next();

        lenA = a.length();
        lenC = c.length();

        next = new int[lenA][lenC];
        delta = new int[lenA][lenC];
        for (int i = 0; i < lenA; ++i) {
            Arrays.fill(next[i], -1);
            Arrays.fill(delta[i], -1);

            for (int j = 0; j < lenC; ++j) {
                if (a.charAt(i) != c.charAt(j)) continue;

                int l = 1, dd = 0, lastL = 0;
                while (l <= lenA) {
                    int ii = (i + l) % lenA;
                    int jj = (j + dd + 1) % lenC;
                    if (a.charAt(ii) == c.charAt(jj)) {
                        ++dd;
                        lastL = l;
                    }
                    ++l;
                }

                if (lastL > 0) {
                    next[i][j] = lastL;
                    delta[i][j] = dd;
                }
            }
        }

        int cnt = 0, i = 0, j = 0;
        while (i < lenA && next[i][j] == -1) ++i;
        if (i >= lenA || next[i][j] == -1) {
            System.out.println(0);
            return;
        }

        while (next[i % lenA][j] != -1 && i + next[i % lenA][j] < lenA * b) {
            assert a.charAt(i % lenA) == c.charAt(j);
            int ii = i % lenA;
            int jj = j;
            cnt += delta[ii][jj];
            i += next[ii][jj];
            j = (j + delta[ii][jj]) % lenC;
        }

        if (next[i % lenA][j] != -1) {
            while (i < lenA * b) {
                if (a.charAt(i % lenA) == c.charAt(j)) {
                    ++cnt;
                    j = (j + 1) % lenC;
                }
                ++i;
            }
        }

        System.out.println(cnt / (d * lenC));
    }
}


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

public class D {

	private static StringTokenizer tokenizer;
    private static BufferedReader bf;
    private static PrintWriter out;

	private static int nextInt() throws IOException {
    	return Integer.parseInt(nextToken());
    }

    private static String nextToken() throws IOException {
    	while(tokenizer == null || !tokenizer.hasMoreTokens()) {
    		tokenizer = new StringTokenizer(bf.readLine());
    	}
    	return tokenizer.nextToken();
    }

	public static void main(String[] args) throws IOException {
		bf = new BufferedReader(new InputStreamReader(System.in));
    	tokenizer = null;
    	out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
    	int b = nextInt(); int d = nextInt();
    	String a = nextToken(); String c = nextToken();
    	int la = a.length(); int lc = c.length();
    	int[] pos = new int[lc+1]; int[] res = new int[lc+1];
    	int ind, ans;
    	for(int i = 0; i < lc; i++) {
    		ind = i;
    		for(int j = 0; j < la; j++) {
    			if(a.charAt(j) == c.charAt(ind)) ind++;
    			if(ind == lc) {
    				ind = 0; res[i]++;
    			}
    		}
    		pos[i] = ind;
    	}
    	ind = ans = 0;
    	for(int i = 0; i < b; i++) {
    		ans += res[ind];
    		ind = pos[ind];
    	}
    	out.println(ans/d);
    	out.close();
	}

}


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

public class F {

    static int N = 250;
    static int M = 28;
    static int INF = (int) 1e9;
    static int[][][][] dp = new int[2][M * 2 + 1][N][N];

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder(br.readLine());
        String s = sb.reverse().append("0").toString();

        for (int carry = 0; carry < M * 2 + 1; carry++) {
            for (int cp = 0; cp < N; cp++) {
                for (int cn = 0; cn < N; cn++) {
                    dp[0][carry][cp][cn] = INF;
                }
            }
        }
        dp[0][M][N - 1][N - 1] = 0;

        for (int i = 0; i < s.length(); i++) {
            for (int carry = 0; carry < M * 2 + 1; carry++) {
                for (int cp = 0; cp < N; cp++) {
                    for (int cn = 0; cn < N; cn++) {
                        dp[1][carry][cp][cn] = INF;
                    }
                }
            }
            for (int carry = 0; carry < M * 2 + 1; carry++) {
                for (int cp = N - 1; cp >= 0; cp--) {
                    for (int cn = N - 1; cn >= 0; cn--) {
                        if (dp[0][carry][cp][cn] != INF) {
                            if (cp > 0) {
                                dp[0][carry][cp - 1][cn] = Math.min(dp[0][carry][cp - 1][cn], dp[0][carry][cp][cn]);
                            }
                            if (cn > 0) {
                                dp[0][carry][cp][cn - 1] = Math.min(dp[0][carry][cp][cn - 1], dp[0][carry][cp][cn]);
                            }
                            int rcarry = carry - M;
                            int val = rcarry + cp - cn;
                            int digit = val % 10;
                            if (digit < 0) {
                                digit += 10;
                            }
                            int ncarry = val / 10;
                            if (val < 0 && digit != 0) {
                                --ncarry;
                            }
                            if (digit == s.charAt(i) - '0') {
                                dp[1][ncarry + M][cp][cn] = Math.min(dp[1][ncarry + M][cp][cn],
                                        dp[0][carry][cp][cn] + cp + cn);
                            }
                        }
                    }
                }
            }
            int[][][] tmp = dp[0];
            dp[0] = dp[1];
            dp[1] = tmp;
        }

        int ans = INF;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                ans = Math.min(ans, dp[0][M][i][j]);
            }
        }
        System.out.println(ans);
    }

}


//package ecr104;

import java.io.*;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.Queue;

public class F {
	InputStream is;
	FastWriter out;
//	String INPUT = "11451481091145148109114514810911451481091145148109";
//	String INPUT = "99999999999999999999999999999999999999999999999999";
//	String INPUT = "37373737373737373737373737373737373737373737373737";
	String INPUT = "";

	void solve()
	{
		char[] N = ("000" + ns()).toCharArray();
		int n = N.length;
		final int D = 50;
		final int B = 1200;
		int[][] dp = new int[D][B]; // delta from ideal, previous balance = #
		final int O = 500;
		final int Q = 25;
		final int I = 9999999;
		for(int i = 0;i < D;i++)Arrays.fill(dp[i], I);
		dp[Q][O] = 0;
		for(int d = 0;d < n;d++){
			int[][] ndp = new int[D][B]; // delta from ideal, previous balance = #
			for(int i = 0;i < D;i++)Arrays.fill(ndp[i], I);

			for(int i = 0;i < D;i++) {
				for (int j = 0; j < B; j++) {
					if (dp[i][j] >= I) continue;
					int del = (i - Q) * 10 + j - O - (N[d] - '0');
					for (int k = -11; k <= 11; k++) {
						if (0 <= del + k + Q && del + k + Q < D) {
							ndp[del + k + Q][j + k] = Math.min(ndp[del + k + Q][j + k],
									dp[i][j] + Math.abs(k) * (n - d));
						}
					}
				}

			}

			dp = ndp;
		}

		int ans = Integer.MAX_VALUE;
		for(int j = 0;j < B;j++){
			ans = Math.min(ans, dp[Q][j]);
		}
		out.println(ans);
	}

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

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

	public static void main(String[] args) throws Exception { new F().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 int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private long[] nal(int n)
	{
		long[] a = new long[n];
		for(int i = 0;i < n;i++)a[i] = nl();
		return a;
	}

	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[][] nmi(int n, int m) {
		int[][] map = new int[n][];
		for(int i = 0;i < n;i++)map[i] = na(m);
		return map;
	}

	private int ni() { return (int)nl(); }

	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();
		}
	}

	public static class FastWriter
	{
		private static final int BUF_SIZE = 1<<13;
		private final byte[] buf = new byte[BUF_SIZE];
		private final OutputStream out;
		private int ptr = 0;

		private FastWriter(){out = null;}

		public FastWriter(OutputStream os)
		{
			this.out = os;
		}

		public FastWriter(String path)
		{
			try {
				this.out = new FileOutputStream(path);
			} catch (FileNotFoundException e) {
				throw new RuntimeException("FastWriter");
			}
		}

		public FastWriter write(byte b)
		{
			buf[ptr++] = b;
			if(ptr == BUF_SIZE)innerflush();
			return this;
		}

		public FastWriter write(char c)
		{
			return write((byte)c);
		}

		public FastWriter write(char[] s)
		{
			for(char c : s){
				buf[ptr++] = (byte)c;
				if(ptr == BUF_SIZE)innerflush();
			}
			return this;
		}

		public FastWriter write(String s)
		{
			s.chars().forEach(c -> {
				buf[ptr++] = (byte)c;
				if(ptr == BUF_SIZE)innerflush();
			});
			return this;
		}

		private static int countDigits(int l) {
			if (l >= 1000000000) return 10;
			if (l >= 100000000) return 9;
			if (l >= 10000000) return 8;
			if (l >= 1000000) return 7;
			if (l >= 100000) return 6;
			if (l >= 10000) return 5;
			if (l >= 1000) return 4;
			if (l >= 100) return 3;
			if (l >= 10) return 2;
			return 1;
		}

		public FastWriter write(int x)
		{
			if(x == Integer.MIN_VALUE){
				return write((long)x);
			}
			if(ptr + 12 >= BUF_SIZE)innerflush();
			if(x < 0){
				write((byte)'-');
				x = -x;
			}
			int d = countDigits(x);
			for(int i = ptr + d - 1;i >= ptr;i--){
				buf[i] = (byte)('0'+x%10);
				x /= 10;
			}
			ptr += d;
			return this;
		}

		private static int countDigits(long l) {
			if (l >= 1000000000000000000L) return 19;
			if (l >= 100000000000000000L) return 18;
			if (l >= 10000000000000000L) return 17;
			if (l >= 1000000000000000L) return 16;
			if (l >= 100000000000000L) return 15;
			if (l >= 10000000000000L) return 14;
			if (l >= 1000000000000L) return 13;
			if (l >= 100000000000L) return 12;
			if (l >= 10000000000L) return 11;
			if (l >= 1000000000L) return 10;
			if (l >= 100000000L) return 9;
			if (l >= 10000000L) return 8;
			if (l >= 1000000L) return 7;
			if (l >= 100000L) return 6;
			if (l >= 10000L) return 5;
			if (l >= 1000L) return 4;
			if (l >= 100L) return 3;
			if (l >= 10L) return 2;
			return 1;
		}

		public FastWriter write(long x)
		{
			if(x == Long.MIN_VALUE){
				return write("" + x);
			}
			if(ptr + 21 >= BUF_SIZE)innerflush();
			if(x < 0){
				write((byte)'-');
				x = -x;
			}
			int d = countDigits(x);
			for(int i = ptr + d - 1;i >= ptr;i--){
				buf[i] = (byte)('0'+x%10);
				x /= 10;
			}
			ptr += d;
			return this;
		}

		public FastWriter write(double x, int precision)
		{
			if(x < 0){
				write('-');
				x = -x;
			}
			x += Math.pow(10, -precision)/2;
			//		if(x < 0){ x = 0; }
			write((long)x).write(".");
			x -= (long)x;
			for(int i = 0;i < precision;i++){
				x *= 10;
				write((char)('0'+(int)x));
				x -= (int)x;
			}
			return this;
		}

		public FastWriter writeln(char c){
			return write(c).writeln();
		}

		public FastWriter writeln(int x){
			return write(x).writeln();
		}

		public FastWriter writeln(long x){
			return write(x).writeln();
		}

		public FastWriter writeln(double x, int precision){
			return write(x, precision).writeln();
		}

		public FastWriter write(int... xs)
		{
			boolean first = true;
			for(int x : xs) {
				if (!first) write(' ');
				first = false;
				write(x);
			}
			return this;
		}

		public FastWriter write(long... xs)
		{
			boolean first = true;
			for(long x : xs) {
				if (!first) write(' ');
				first = false;
				write(x);
			}
			return this;
		}

		public FastWriter writeln()
		{
			return write((byte)'\n');
		}

		public FastWriter writeln(int... xs)
		{
			return write(xs).writeln();
		}

		public FastWriter writeln(long... xs)
		{
			return write(xs).writeln();
		}

		public FastWriter writeln(char[] line)
		{
			return write(line).writeln();
		}

		public FastWriter writeln(char[]... map)
		{
			for(char[] line : map)write(line).writeln();
			return this;
		}

		public FastWriter writeln(String s)
		{
			return write(s).writeln();
		}

		private void innerflush()
		{
			try {
				out.write(buf, 0, ptr);
				ptr = 0;
			} catch (IOException e) {
				throw new RuntimeException("innerflush");
			}
		}

		public void flush()
		{
			innerflush();
			try {
				out.flush();
			} catch (IOException e) {
				throw new RuntimeException("flush");
			}
		}

		public FastWriter print(byte b) { return write(b); }
		public FastWriter print(char c) { return write(c); }
		public FastWriter print(char[] s) { return write(s); }
		public FastWriter print(String s) { return write(s); }
		public FastWriter print(int x) { return write(x); }
		public FastWriter print(long x) { return write(x); }
		public FastWriter print(double x, int precision) { return write(x, precision); }
		public FastWriter println(char c){ return writeln(c); }
		public FastWriter println(int x){ return writeln(x); }
		public FastWriter println(long x){ return writeln(x); }
		public FastWriter println(double x, int precision){ return writeln(x, precision); }
		public FastWriter print(int... xs) { return write(xs); }
		public FastWriter print(long... xs) { return write(xs); }
		public FastWriter println(int... xs) { return writeln(xs); }
		public FastWriter println(long... xs) { return writeln(xs); }
		public FastWriter println(char[] line) { return writeln(line); }
		public FastWriter println(char[]... map) { return writeln(map); }
		public FastWriter println(String s) { return writeln(s); }
		public FastWriter println() { return writeln(); }
	}

	public void trnz(int... o)
	{
		for(int i = 0;i < o.length;i++)if(o[i] != 0)System.out.print(i+":"+o[i]+" ");
		System.out.println();
	}

	// print ids which are 1
	public void trt(long... o)
	{
		Queue<Integer> stands = new ArrayDeque<>();
		for(int i = 0;i < o.length;i++){
			for(long x = o[i];x != 0;x &= x-1)stands.add(i<<6|Long.numberOfTrailingZeros(x));
		}
		System.out.println(stands);
	}

	public void tf(boolean... r)
	{
		for(boolean x : r)System.out.print(x?'#':'.');
		System.out.println();
	}

	public void tf(boolean[]... b)
	{
		for(boolean[] r : b) {
			for(boolean x : r)System.out.print(x?'#':'.');
			System.out.println();
		}
		System.out.println();
	}

	public void tf(long[]... b)
	{
		if(INPUT.length() != 0) {
			for (long[] r : b) {
				for (long x : r) {
					for (int i = 0; i < 64; i++) {
						System.out.print(x << ~i < 0 ? '#' : '.');
					}
				}
				System.out.println();
			}
			System.out.println();
		}
	}

	public void tf(long... b)
	{
		if(INPUT.length() != 0) {
			for (long x : b) {
				for (int i = 0; i < 64; i++) {
					System.out.print(x << ~i < 0 ? '#' : '.');
				}
			}
			System.out.println();
		}
	}

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


// Don't place your source in a package
import javax.swing.*;
import java.lang.reflect.Array;
import java.text.DecimalFormat;
import java.util.*;
import java.lang.*;
import java.io.*;
import java.math.*;
import java.util.stream.Stream;

// Please name your class Main
public class Main {
    static FastScanner fs=new FastScanner();
    static class FastScanner {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st=new StringTokenizer("");
        public String next() {
            while (!st.hasMoreElements())
                try {
                    st=new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            return st.nextToken();
        }
        int Int() {
            return Integer.parseInt(next());
        }

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

        String Str(){
            return next();
        }
    }

    public static void main (String[] args) throws java.lang.Exception {
        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        //reading /writing file
        //Scanner sc=new Scanner(new File("input.txt"));
        //PrintWriter pr=new PrintWriter("output.txt");

        int T=1;
        for(int t=0;t<T;t++){
            String s=Str();

            Solution sol=new Solution(out);
            sol.solution(s);
        }
        out.close();

    }

    public static int[] Arr(int n){
        int A[]=new int[n];
        for(int i=0;i<n;i++)A[i]=Int();
        return A;
    }
    public static int Int(){
        return fs.Int();
    }
    public static long Long(){
        return fs.Long();
    }
    public static String Str(){
        return fs.Str();
    }

}

class Solution{
    PrintWriter out;
    int INF=Integer.MAX_VALUE;
    int MOD=1000000007;
    public Solution(PrintWriter out){
        this.out=out;
    }

    long dp[][][];
    public void solution(String s) {
        dp=new long[s.length()+1][800][800];
        for(int i=0;i<dp.length;i++){
            for(int j=0;j<dp[0].length;j++)Arrays.fill(dp[i][j],-1);
        }
        long res=dfs("0"+s,0,0,0);
        out.println(res);

    }

    public long dfs(String s,int pos,int diff,int chunk){
        if(pos>=s.length()){
            if(diff!=0)return INF;
            return 0;
        }
        if(chunk>350||Math.abs(diff)>350){
            return INF;
        }
        if(dp[pos][diff+400][chunk+400]!=-1)return dp[pos][diff+400][chunk+400];

        int d=s.charAt(pos)-'0';
        long res=INF;
        int newdiff=diff*10+chunk-d;
        for(int i=-6;i<=6;i++){
            long cnt=Math.abs(i)*(s.length()-pos);
            res=Math.min(res,cnt+dfs(s,pos+1,newdiff+i,chunk+i));
        }
        dp[pos][diff+400][chunk+400]=res;
        return res;
    }
}


import java.util.*;
import java.io.*;
public class Edu104F{
	public static void main(String[] main) throws Exception{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		PrintWriter out = new PrintWriter(System.out);
		String s = st.nextToken();
		int[] num = new int[s.length()+1];
		num[1] = s.charAt(0) - 48;
		for(int i = 2; i <= s.length(); i++) {
			num[i] = s.charAt(i-1) - s.charAt(i-2);
		}
		int iters = 0;
		boolean edit = true;
		int min = 10000;
		while(edit) {
			iters++;
			edit = false;
			for(int i = 1; i < s.length(); i++) {
				if(num[i] > 5) {
					num[i-1]++;
					num[i] = num[i]-10;
					num[s.length()]--;
					edit = true;
				}
				else if(num[i] == 5 && num[i-1] < 0) {
					num[i-1]++;
					num[i] = num[i]-10;
					num[s.length()]--;
					edit = true;
				}
				else if(i >= 2 && num[i] == 5 && num[i-1] == 4 && num[i-2] < 0 && (num[s.length()] > 0 || num[s.length()] <= -4)) {
					num[i-2]++;
					num[i-1] = -5;
					num[i] = -5;
					num[s.length()]-=2;
					edit = true;
				}
				else if(i >= 2 && num[i] == 5 && num[i-1] == 4 && num[i-2] < 0 && num[s.length()] < -3 && num[s.length() - 1] > 0) {
					num[i-2]++;
					num[i-1] = -5;
					num[i] = -5;
					num[s.length()]-=2;
					edit = true;
				}
				else if(num[i] == 5 && num[i-1] == 5 && num[s.length()] > 1) {
					num[i-2]++;
					num[i-1] = -4;
					num[i] = -5;
					num[s.length()]-=2;
					edit = true;
				}
				else if(num[i] == 5 && num[i-1] == 5 && num[i-2] == 5) {
					num[i-2]++;
					num[i-1] = -4;
					num[i] = -5;
					num[s.length()]-=2;
					edit = true;
				}
				else if(num[i] < -5) {
					num[i-1]--;
					num[i] = num[i]+10;
					num[s.length()]++;
					edit = true;
				}
				else if(num[i] == -5 && num[i-1] > 0) {
					num[i-1]--;
					num[i] = num[i]+10;
					num[s.length()]++;
					edit = true;
				}
				else if(i >= 2 && num[i] == -5 && num[i-1] == -4 && (num[i-2] > 0) && (num[s.length()] < 0 || num[s.length()] >= 4)) {
					num[i-2]--;
					num[i-1] = 5;
					num[i] = 5;
					num[s.length()]+=2;
					edit = true;
				}
				else if(i >= 2 && num[i] == -5 && num[i-1] == -4 && (num[i-2] == -4 && num[i-3] > 0) && (num[s.length()] < 0 || num[s.length()] >= 4)) {
					num[i-2]--;
					num[i-1] = 5;
					num[i] = 5;
					num[s.length()]+=2;
					edit = true;
				}
				else if(i >= 2 && num[i] == -5 && num[i-1] == -4 && num[i-2] > 0 && num[s.length()] > 3 && num[s.length() - 1] < 0) {
					num[i-2]--;
					num[i-1] = 5;
					num[i] = 5;
					num[s.length()]+=2;
					edit = true;
				}
				else if(num[i] == -5 && num[i-1] == -5 && num[s.length()] < -1) {
					num[i-2]--;
					num[i-1] = 4;
					num[i] = 5;
					num[s.length()]+=2;
					edit = true;
				}
				else if(num[i] == -5 && num[i-1] == -5 && num[i-2] == -5) {
					num[i-2]--;
					num[i-1] = 4;
					num[i] = 5;
					num[s.length()]+=2;
					edit = true;
				}
			}
			if(num[s.length()] > 6) {
				num[s.length()-1]++;
				num[s.length()] -= 11;
				edit = true;
			}
			else if(num[s.length()] >= 5 && num[s.length() - 1] < 0) {
				num[s.length()-1]++;
				num[s.length()] -= 11;
				edit = true;
			}
			else if(s.length() >= 2 && num[s.length()] == 6 && num[s.length()-1] == 4 && num[s.length()-2] < 0) {
				num[s.length()-1]++;
				num[s.length()] -= 11;
				edit = true;
			}
			else if(num[s.length()] < -6) {
				num[s.length()-1]--;
				num[s.length()] += 11;
				edit = true;
			}
			else if(num[s.length()] <= -5 && num[s.length() - 1] > 0) {
				num[s.length()-1]--;
				num[s.length()] += 11;
				edit = true;
			}
			else if(s.length() >= 2 && num[s.length()] == -6 && num[s.length()-1] == -4 && num[s.length()-2] > 0) {
				num[s.length()-1]--;
				num[s.length()] += 11;
				edit = true;
			}
			int ans = 0;
			for(int i = 0; i <= s.length(); i++) {
				//out.print(num[i] + " ");
				ans += (s.length() + 1 - i)*Math.abs(num[i]);
			}
			min = Math.min(ans, min);
			if(iters > 7000000) {
				break;
			}
		}
		int ans = 0;
		for(int i = 0; i <= s.length(); i++) {
			//out.print(num[i] + " ");
			ans += (s.length() + 1 - i)*Math.abs(num[i]);
		}
		out.println(Math.min(min,ans));
		out.close();
	}
}


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

/**
 *
 * @author Arles
 */
public class C {

    static int N = 250;
    static int M = 28;
    static int INF = (int) 1e9;
    static int[][][][] dp = new int[2][M * 2 + 1][N][N];

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder(br.readLine());
        String s = sb.reverse().append("0").toString();

        for (int carry = 0; carry < M * 2 + 1; carry++) {
            for (int cp = 0; cp < N; cp++) {
                for (int cn = 0; cn < N; cn++) {
                    dp[0][carry][cp][cn] = INF;
                }
            }
        }
        dp[0][M][N - 1][N - 1] = 0;

        for (int i = 0; i < s.length(); i++) {
            for (int carry = 0; carry < M * 2 + 1; carry++) {
                for (int cp = 0; cp < N; cp++) {
                    for (int cn = 0; cn < N; cn++) {
                        dp[1][carry][cp][cn] = INF;
                    }
                }
            }
            for (int carry = 0; carry < M * 2 + 1; carry++) {
                for (int cp = N - 1; cp >= 0; cp--) {
                    for (int cn = N - 1; cn >= 0; cn--) {
                        if (dp[0][carry][cp][cn] != INF) {
                            if (cp > 0) {
                                dp[0][carry][cp - 1][cn] = Math.min(dp[0][carry][cp - 1][cn], dp[0][carry][cp][cn]);
                            }
                            if (cn > 0) {
                                dp[0][carry][cp][cn - 1] = Math.min(dp[0][carry][cp][cn - 1], dp[0][carry][cp][cn]);
                            }
                            int rcarry = carry - M;
                            int val = rcarry + cp - cn;
                            int digit = val % 10;
                            if (digit < 0) {
                                digit += 10;
                            }
                            int ncarry = val / 10;
                            if (val < 0 && digit != 0) {
                                --ncarry;
                            }
                            if (digit == s.charAt(i) - '0') {
                                dp[1][ncarry + M][cp][cn] = Math.min(dp[1][ncarry + M][cp][cn],
                                        dp[0][carry][cp][cn] + cp + cn);
                            }
                        }
                    }
                }
            }
            int[][][] tmp = dp[0];
            dp[0] = dp[1];
            dp[1] = tmp;
        }

        int ans = INF;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                ans = Math.min(ans, dp[0][M][i][j]);
            }
        }
        System.out.println(ans);
    }

}


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

public class D {
    FastScanner in;
    PrintWriter out;

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

    void solve() throws IOException {
        int n = in.nextInt();
        long m = 1; // one is bad number
        int[] primes = new int[n + 1];
        int[] primesMin = new int[n + 1];
        int primesCnt = 0;
        int[] sieve = new int[n + 1];
        for (int i = 2; i < n + 1; i++) {
            if (sieve[i] == 0) {
                primes[primesCnt++] = i;
                if (2 * i > n) {
                    m++;
                }
                int cnt = 0;
                for (int j = i; j < n + 1; j += i) {
                    if (sieve[j] == 0) {
                        sieve[j] = i;
                        cnt++;
                    }
                }
                primesMin[primesCnt - 1] = cnt;
            }
        }
        int[] prefPrimesMin = new int[n + 1];
        for (int i = 0; i < primesCnt; i++) {
            prefPrimesMin[i + 1] = prefPrimesMin[i] + primesMin[i];
        }
        boolean[] squareFree = new boolean[n + 1];
        squareFree[1] = true;
        for (int i = 2; i < n + 1; i++) {
            int prev = i / sieve[i];
            squareFree[i] = prev % sieve[i] != 0 && squareFree[prev];
//            out.print(squareFree[i] + " ");
        }
//        out.println();

        int[] countPrimeInDecomposition = new int[n + 1];
        for (int i = 2; i < n + 1; i++) {
            if (sieve[i] == 0) {
                countPrimeInDecomposition[i] = 1;
            } else {
                countPrimeInDecomposition[i] = 1 + countPrimeInDecomposition[i / sieve[i]];
            }
        }
        long sum1 = 0;
        for (int i = 2; i < n + 1; i++) {
            if (!squareFree[i]) continue;
            long cnt = n / i;
            cnt *= cnt;
            if (countPrimeInDecomposition[i] % 2 == 0) {
                sum1 -= cnt;
            } else {
                sum1 += cnt;
            }
        }
        long sum0 = 2 * (n - m) * m + m * (m - 1) + 1;
//        out.println(sum0);
        long sum3 = 0;
        int p1i = -1;
        for (int pi = 0; pi < primesCnt; pi++) {
            long p2 = primes[pi];
            if (p2 * 2 > n) {
                break;
            }
            if (p2 * p2 > n) {
                if (p1i == -1) {
                    p1i = pi;
                }
                while (p1i >= 0 && primes[p1i] * p2 > n) {
                    p1i--;
                }
                p1i++;
                sum3 += prefPrimesMin[pi] - prefPrimesMin[p1i];
            }
        }
        sum3 *= 2;
        long sum2 = (long) n * n - sum0 - sum1 - sum3;
//        out.println(m + " " + sum0 + " " + sum1 + " " + sum2 + " " + sum3);
        out.println((sum1 + sum2 * 2 + sum3 * 3 - (n - 1)) / 2);
    }

    void run() {
        try {
            in = new FastScanner(System.in);
            out = new PrintWriter(System.out);
            solve();

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

    class FastScanner {
        BufferedReader br;
        StringTokenizer st;

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

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

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


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.io.Closeable;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(null, new TaskAdapter(), "", 1 << 27);
        thread.start();
        thread.join();
    }

    static class TaskAdapter implements Runnable {
        @Override
        public void run() {
            InputStream inputStream = System.in;
            OutputStream outputStream = System.out;
            FastInput in = new FastInput(inputStream);
            FastOutput out = new FastOutput(outputStream);
            DPaths solver = new DPaths();
            solver.solve(1, in, out);
            out.close();
        }
    }

    static class DPaths {
        Debug debug = new Debug(true);

        public void solve(int testNumber, FastInput in, FastOutput out) {
            int n = in.readInt();
            MultiplicativeFunctionSieve sieve = new MultiplicativeFunctionSieve(n, false, true, false);

            long twoCnt = 0;
            long threeCnt = 0;
            int[] ps = new int[n + 1];
            for (int i = 2; i <= n; i++) {
                ps[sieve.smallestPrimeFactor[i]]++;
            }
            for (int i = 1; i <= n; i++) {
                ps[i] += ps[i - 1];
            }
            for (int i = 1; i * 2 <= n; i++) {
                int num = (ps[i] - ps[i - 1]);

                int j = Math.min(i - 1, n / i);
                twoCnt += (long) ps[j] * num;

                int k = Math.min(i - 1, n / 2);
                threeCnt += (long) ps[k] * num;
            }
            for (int i = 1; i <= n; i++) {
                int num = ps[i] - ps[i - 1];
                if (i * i <= n) {
                    twoCnt += (long) num * (num - 1) / 2;
                }
                if (i * 2 <= n) {
                    threeCnt += (long) num * (num - 1) / 2;
                }
            }

            threeCnt -= twoCnt;
            long coprime = 0;
            for (int i = 2; i <= n; i++) {
                coprime += sieve.euler[i];
            }

            long notCoprime = (long) n * (n - 1) / 2 - coprime;
            long ans = twoCnt * 2 - notCoprime + threeCnt * 3;

            debug.debug("coprime", coprime);
            debug.debug("twoCnt", twoCnt);
            debug.debug("notCporime", notCoprime);
            debug.debug("threeCnt", threeCnt);
            out.println(ans);
        }

    }

    static class Debug {
        private boolean offline;
        private PrintStream out = System.err;

        public Debug(boolean enable) {
            offline = enable && System.getSecurityManager() == null;
        }

        public Debug debug(String name, long x) {
            if (offline) {
                debug(name, "" + x);
            }
            return this;
        }

        public Debug debug(String name, String x) {
            if (offline) {
                out.printf("%s=%s", name, x);
                out.println();
            }
            return this;
        }

    }

    static class FastInput {
        private final InputStream is;
        private byte[] buf = new byte[1 << 13];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastInput(InputStream is) {
            this.is = is;
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    bufLen = -1;
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public int readInt() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            int val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

    }

    static class FastOutput implements AutoCloseable, Closeable, Appendable {
        private StringBuilder cache = new StringBuilder(10 << 20);
        private final Writer os;

        public FastOutput append(CharSequence csq) {
            cache.append(csq);
            return this;
        }

        public FastOutput append(CharSequence csq, int start, int end) {
            cache.append(csq, start, end);
            return this;
        }

        public FastOutput(Writer os) {
            this.os = os;
        }

        public FastOutput(OutputStream os) {
            this(new OutputStreamWriter(os));
        }

        public FastOutput append(char c) {
            cache.append(c);
            return this;
        }

        public FastOutput append(long c) {
            cache.append(c);
            return this;
        }

        public FastOutput println(long c) {
            return append(c).println();
        }

        public FastOutput println() {
            cache.append(System.lineSeparator());
            return this;
        }

        public FastOutput flush() {
            try {
                os.append(cache);
                os.flush();
                cache.setLength(0);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
            return this;
        }

        public void close() {
            flush();
            try {
                os.close();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }

        public String toString() {
            return cache.toString();
        }

    }

    static class MultiplicativeFunctionSieve {
        public int[] primes;
        public boolean[] isComp;
        public int primeLength;
        public int[] mobius;
        public int[] euler;
        public int[] factors;
        public int[] smallestPrimeFactor;
        public int[] numberOfSmallestPrimeFactor;

        public MultiplicativeFunctionSieve(int limit, boolean enableMobius, boolean enableEuler, boolean enableFactors) {
            isComp = new boolean[limit + 1];
            primes = new int[limit + 1];
            numberOfSmallestPrimeFactor = new int[limit + 1];
            smallestPrimeFactor = new int[limit + 1];
            primeLength = 0;
            for (int i = 2; i <= limit; i++) {
                if (!isComp[i]) {
                    primes[primeLength++] = i;
                    numberOfSmallestPrimeFactor[i] = smallestPrimeFactor[i] = i;
                }
                for (int j = 0, until = limit / i; j < primeLength && primes[j] <= until; j++) {
                    int pi = primes[j] * i;
                    smallestPrimeFactor[pi] = primes[j];
                    numberOfSmallestPrimeFactor[pi] = smallestPrimeFactor[i] == primes[j]
                            ? (numberOfSmallestPrimeFactor[i] * numberOfSmallestPrimeFactor[primes[j]])
                            : numberOfSmallestPrimeFactor[primes[j]];
                    isComp[pi] = true;
                    if (i % primes[j] == 0) {
                        break;
                    }
                }
            }

            if (enableMobius) {
                mobius = new int[limit + 1];
                mobius[1] = 1;
                for (int i = 2; i <= limit; i++) {
                    if (!isComp[i]) {
                        mobius[i] = -1;
                    } else {
                        if (numberOfSmallestPrimeFactor[i] != smallestPrimeFactor[i]) {
                            mobius[i] = 0;
                        } else {
                            mobius[i] = mobius[numberOfSmallestPrimeFactor[i]] * mobius[i / numberOfSmallestPrimeFactor[i]];
                        }
                    }
                }
            }

            if (enableEuler) {
                euler = new int[limit + 1];
                euler[1] = 1;
                for (int i = 2; i <= limit; i++) {
                    if (!isComp[i]) {
                        euler[i] = i - 1;
                    } else {
                        if (numberOfSmallestPrimeFactor[i] == i) {
                            euler[i] = i - i / smallestPrimeFactor[i];
                        } else {
                            euler[i] = euler[numberOfSmallestPrimeFactor[i]] * euler[i / numberOfSmallestPrimeFactor[i]];
                        }
                    }
                }
            }

            if (enableFactors) {
                factors = new int[limit + 1];
                factors[1] = 1;
                for (int i = 2; i <= limit; i++) {
                    if (!isComp[i]) {
                        factors[i] = 2;
                    } else {
                        if (numberOfSmallestPrimeFactor[i] == i) {
                            factors[i] = 1 + factors[i / smallestPrimeFactor[i]];
                        } else {
                            factors[i] = factors[numberOfSmallestPrimeFactor[i]]
                                    * factors[i / numberOfSmallestPrimeFactor[i]];
                        }
                    }
                }
            }
        }

    }
}


//package educational.round68;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.InputMismatchException;

public class G3 {
	InputStream is;
	PrintWriter out;
//	String INPUT = "42";
	String INPUT = "";

	public static void trnz(long... o)
	{
		for(int i = 0;i < o.length;i++)if(o[i] != 0)System.out.print(i+":"+o[i]+" ");
		System.out.println();
	}

	void solve()
	{
		BigInteger n = new BigInteger(ns());
		long ans = 0;
		for(int i = 1;i <= 9;i++){
			for(int j = 1;j <= i;j++){
				if(gcd(i, j) == 1){
					if(i == 1){
						ans += n.mod(BigInteger.valueOf(998244353L)).longValue();
					}else{
						long lans = count(n, i, j);
						if(i != j){
							ans += lans*2;
						}else{
							ans += lans;
						}
//						if(lans > 0)tr(i, j, lans, ans);
					}
				}
			}
		}
		out.println(ans % 998244353);
	}

	long count(BigInteger N, int u, int v)
	{
		char[] s = ("0" + N.divide(BigInteger.valueOf(u)).add(BigInteger.ONE).toString()).toCharArray();

		int n = s.length;
		// u:2 v:1
		// u倍したときにt*uを含んでいるか
		// v倍したときにt*vを含んでいるか
		int w = 9/u;
		long[][][][] dp = new long[1<<w][1<<w][10][10]; // valid carry
		long[][][][] ep = new long[1<<w][1<<w][10][10]; // valid carry
		int mod = 998244353;
		ep[0][0][0][0] = 1;

		int[][] va0 = new int[10][10];
		int[][] va1 = new int[10][10];
		int[][] nextc0 = new int[10][10];
		int[][] nextc1 = new int[10][10];
		for(int d = 0;d < 10;d++){
			for(int c0 = 0;c0 <= 9;c0++){
				int v0 = d*u + c0;
				for(int t = 1;t <= w;t++){
					if(t*u == v0%10){
						va0[d][c0] |= 1<<t-1;
					}
				}
				nextc0[d][c0] = v0 / 10;
			}
			for(int c1 = 0;c1 <= 9;c1++){
				int v1 = d*v + c1;
				for(int t = 1;t <= w;t++){
					if(t*v == v1%10){
						va1[d][c1] |= 1<<t-1;
					}
				}
				nextc1[d][c1] = v1 / 10;
			}
		}

		for(int i = n-1;i >= 0;i--){
			long[][][][] ndp = new long[1<<w][1<<w][10][10]; // valid carry
			long[][][][] nep = new long[1<<w][1<<w][10][10]; // valid carry

			for(int j = 0;j < 1<<w;j++){
				for(int k = 0;k < 1<<w;k++){
					for(int l = 0;l < 10;l++){
						for(int m = 0;m < 10;m++){
							int d = s[i]-'0';
							int nj = j|va0[d][l];
							int nk = k|va1[d][m];
							int nl = nextc0[d][l];
							int nm = nextc1[d][m];
							ndp[nj][nk][nl][nm] += dp[j][k][l][m];
							if(ndp[nj][nk][nl][nm] >= mod)ndp[nj][nk][nl][nm] -= mod;
						}
					}
				}
			}

			for(int j = 0;j < 1<<w;j++){
				for(int k = 0;k < 1<<w;k++){
					for(int l = 0;l < 10;l++){
						for(int m = 0;m < 10;m++){
							for(int d = 0;d < 10;d++){
								int nj = j|va0[d][l];
								int nk = k|va1[d][m];
								int nl = nextc0[d][l];
								int nm = nextc1[d][m];
								nep[nj][nk][nl][nm] += ep[j][k][l][m];
								if(nep[nj][nk][nl][nm] >= mod)nep[nj][nk][nl][nm] -= mod;
								if(d < s[i]-'0'){
									ndp[nj][nk][nl][nm] += ep[j][k][l][m];
									if(ndp[nj][nk][nl][nm] >= mod)ndp[nj][nk][nl][nm] -= mod;
								}
							}
						}
					}
				}
			}

			dp = ndp;
			ep = nep;
		}

		long ret = 0;
		for(int i = 0;i < 1<<w;i++){
			for(int j = 0;j < 1<<w;j++){
				if((i&j) != 0){
					ret += dp[i][j][0][0];
				}
			}
		}
		return ret % mod;
	}

	public static int gcd(int a, int b) {
		while (b > 0) {
			int c = a;
			a = b;
			b = c % b;
		}
		return a;
	}

	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 G3().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)); }
}