import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

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

    static class TaskG {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int mod = 998244353;
            int n = in.nextInt();
            int k = in.nextInt();
            int[] v = new int[10];
            for (int i = 0; i < k; i++) {
                int x = in.nextInt();
                v[x] = 1;
            }
            int[] ans = {1};
            int p = n / 2;
            while (true) {
                if (p % 2 != 0) {
                    ans = multiplyMod(ans, v, mod);
                }
                p /= 2;
                if (p == 0) break;
                v = multiplyMod(v, v, mod);
            }
            int res = 0;
            for (int x : ans) {
                res = (int) ((res + (long) x * x) % mod);
            }
            out.println(res);
        }

        static int[] multiplyMod(int[] a, int[] b, int mod) {
            int need = a.length + b.length - 1;
            int n = Math.max(2, Integer.highestOneBit(need - 1) << 1);
            double[] aReal = new double[n];
            double[] aImaginary = new double[n];
            for (int i = 0; i < a.length; i++) {
                int x = (a[i] % mod + mod) % mod;
                aReal[i] = x & ((1 << 15) - 1);
                aImaginary[i] = x >> 15;
            }
            if (n == 524288) {

                int z = 1;
            }
            fft(aReal, aImaginary, false);

            double[] bReal = new double[n];
            double[] bImaginary = new double[n];
//        if (a == b) {
//            System.arraycopy(aReal, 0, bReal, 0, n);
//            System.arraycopy(aImaginary, 0, bImaginary, 0, n);
//        } else
            {
                for (int i = 0; i < b.length; i++) {
                    int x = (b[i] % mod + mod) % mod;
                    bReal[i] = x & ((1 << 15) - 1);
                    bImaginary[i] = x >> 15;
                }
                fft(bReal, bImaginary, false);
            }

            double[] faReal = new double[n];
            double[] faImaginary = new double[n];
            double[] fbReal = new double[n];
            double[] fbImaginary = new double[n];

            double cf = 0.25 / n;
            for (int i = 0; i < n; i++) {
                int j = (n - i) & (n - 1);

                double a1r = (aReal[i] + aReal[j]);
                double a1i = (aImaginary[i] - aImaginary[j]);
                double a2r = (aImaginary[i] + aImaginary[j]);
                double a2i = (aReal[j] - aReal[i]);

                double b1r = (bReal[i] + bReal[j]) * cf;
                double b1i = (bImaginary[i] - bImaginary[j]) * cf;
                double b2r = (bImaginary[i] + bImaginary[j]) * cf;
                double b2i = (bReal[j] - bReal[i]) * cf;

                faReal[i] = a1r * b1r - a1i * b1i - a2r * b2i - a2i * b2r;
                faImaginary[i] = a1r * b1i + a1i * b1r + a2r * b2r - a2i * b2i;

                fbReal[i] = a1r * b2r - a1i * b2i + a2r * b1r - a2i * b1i;
                fbImaginary[i] = a1r * b2i + a1i * b2r + a2r * b1i + a2i * b1r;
            }

            fft(faReal, faImaginary, true);
            fft(fbReal, fbImaginary, true);
            int[] res = new int[need];
            for (int i = 0; i < need; i++) {
                long aa = (long) (faReal[i] + 0.5);
                long bb = (long) (fbReal[i] + 0.5);
                long cc = (long) (faImaginary[i] + 0.5);
                res[i] = (int) ((aa + ((bb % mod) << 15) + ((cc % mod) << 30)) % mod);
            }
            if (need + 1 < n && Math.abs(faReal[need + 1]) > 0.5) {
                int z = 1;
            }
            return res;
        }

        static void fft(double[] a, double[] b, boolean inverse) {
            int n = a.length;
            int shift = 32 - Integer.numberOfTrailingZeros(n);
            for (int i = 1; i < n; i++) {
                int j = Integer.reverse(i << shift);
                if (i < j) {
                    double temp = a[i];
                    a[i] = a[j];
                    a[j] = temp;
                    temp = b[i];
                    b[i] = b[j];
                    b[j] = temp;
                }
            }
            for (int len = 2; len <= n; len <<= 1) {
                int halfLen = len >> 1;
                double[] cs = new double[halfLen];
                double[] sn = new double[halfLen];
                for (int i = 0; i < halfLen; i++) {
                    cs[i] = Math.cos(2 * Math.PI * i / len * (inverse ? -1 : 1));
                    sn[i] = Math.sin(2 * Math.PI * i / len * (inverse ? -1 : 1));
                }
                for (int i = 0; i < n; i += len) {
                    for (int j = 0; j < halfLen; j++) {
                        double wA = cs[j];
                        double wB = sn[j];
                        double uA = a[i + j];
                        double uB = b[i + j];
                        double vA = a[i + j + halfLen] * wA - b[i + j + halfLen] * wB;
                        double vB = a[i + j + halfLen] * wB + b[i + j + halfLen] * wA;
                        a[i + j] = uA + vA;
                        b[i + j] = uB + vB;
                        a[i + j + halfLen] = uA - vA;
                        b[i + j + halfLen] = uB - vB;
                    }
                }
            }
//        if (inverse) {
//            for (int i = 0; i < n; i++) {
//                a[i] /= n;
//                b[i] /= n;
//            }
//        }
        }

    }

    static class InputReader {
        final InputStream is;
        final byte[] buf = new byte[1024];
        int pos;
        int size;

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

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

        int read() {
            if (size == -1)
                throw new InputMismatchException();
            if (pos >= size) {
                pos = 0;
                try {
                    size = is.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (size <= 0)
                    return -1;
            }
            return buf[pos++] & 255;
        }

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

    }
}


import java.util.*;
import java.io.*;
import java.lang.reflect.Array;
import java.math.BigInteger;

public class FFT {
	FastScanner in;
	PrintWriter out;
	boolean systemIO = true;

	public class Vector {
		int sz = 1 << 20;
		long[] v;

		public Vector(long[] a) {
			v = new long[sz];
			for (int i = 0; i < a.length; i++) {
				v[i] = a[i];
			}
		}

		public long[] FFT() {
			return DFT(0, 1, true);
		}

		public long[] FFT1() {
			long[] x = DFT(0, 1, false);
			for (int i = 0; i < x.length; i++) {
				x[i] = x[i] * szinv % mod;
			}
			return x;
		}

		public long[] DFT(int first, int pow, boolean straight) {
			if (pow == sz) {
				long[] ans = {v[first]};
				return ans;
			}
			long[] zero = DFT(first, 2 * pow, straight);
			long[] one = DFT(first + pow, 2 * pow, straight);
			int n = zero.length;
			long[] ans = new long[2 * n];
			for (int i = 0; i < n; i++) {
				ans[i] = (zero[i] + (straight ? warr[i * pow] : winvarr[i * pow]) * one[i]) % mod;
			}
			for (int i = 0; i < n; i++) {
				ans[n + i] = (((zero[i] - (straight ? warr[i * pow] : winvarr[i * pow]) * one[i]) % mod) + mod) % mod;
			}
			return ans;
		}
	}

	public long[] fft(long[] a) {
		long wth = 1;
		int sz = 1 << 20;
		long[] ans = new long[sz];
		for (int i = 0; i < ans.length; i++) {
			long x = 1;
			for (int j = 0; j < a.length; j++) {
				ans[i] += a[j] * x;
				ans[i] %= mod;
				x *= wth;
				x %= mod;
			}
			wth *= w;
			wth %= mod;
		}
		return ans;
	}

	public long[] pow(long[] ans, int p) {
		for (int i = 0; i < ans.length; i++) {
			ans[i] = pow(ans[i], p);
		}
		return ans;
	}

	public long pow(long x, int p) {
		if (p == 0) {
			return 1;
		}
		if (p % 2 == 1) {
			return pow(x, p - 1) * x % mod;
		}
		long y = pow(x, p / 2);
		return y * y % mod;
	}

	long mod = 998244353;
	long w = 646;
	long winv = (new BigInteger(w + "")).modInverse(new BigInteger(mod + "")).longValueExact();
	long[] warr = new long[1 << 20];
	long[] winvarr = new long[1 << 20];
	long szinv = (new BigInteger((1 << 20) + "")).modInverse(new BigInteger(mod + "")).longValueExact();

	public void solve() {
		int n = in.nextInt();
		int k = in.nextInt();
		long[] arr = new long[10];
		for (int i = 0; i < k; i++) {
			arr[in.nextInt()] = 1;
		}
		warr[0] = 1;
		winvarr[0] = 1;
		for (int i = 1; i < warr.length; i++) {
			warr[i] = warr[i - 1] * w % mod;
			winvarr[i] = winvarr[i - 1] * w % mod;
		}
		long[] x = fft(arr);
		x = pow(x, n / 2);
		Vector v = new Vector(x);
		x = v.FFT1();
		long ans = 0;
		for (int i = 0; i < x.length; i++) {
			ans += x[i] * x[i];
			ans %= mod;
		}
		out.println(ans);
	}

	public void run() {
		try {
			if (systemIO) {
				in = new FastScanner(System.in);
				out = new PrintWriter(System.out);
			} else {
				in = new FastScanner(new File("input.txt"));
				out = new PrintWriter(new File("output.txt"));
			}
			solve();

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

	class FastScanner {
		BufferedReader br;
		StringTokenizer st;

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

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

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

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

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

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

	}

	// AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	public static void main(String[] arg) {
		new FFT().run();
	}
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

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

    static class TaskG {
        static double[] cs = new double[1 << 21];
        static double[] sn = new double[1 << 21];
        static double[] csi = new double[1 << 21];
        static double[] sni = new double[1 << 21];

        static {
            for (int len = 1; len <= cs.length; len <<= 1) {
                for (int i = len / 2; i < len; i++) {
                    cs[i] = Math.cos(2 * Math.PI * (i - len / 2) / len);
                    sn[i] = Math.sin(2 * Math.PI * (i - len / 2) / len);
                    csi[i] = Math.cos(-2 * Math.PI * (i - len / 2) / len);
                    sni[i] = Math.sin(-2 * Math.PI * (i - len / 2) / len);
                }
            }
        }

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int mod = 998244353;
            int n = in.nextInt();
            int k = in.nextInt();
            int[] v = new int[10];
            for (int i = 0; i < k; i++) {
                int x = in.nextInt();
                v[x] = 1;
            }
            int[] ans = {1};
            int p = n / 2;
            while (true) {
                if (p % 2 != 0) {
                    ans = multiplyMod(ans, v, mod);
                }
                p /= 2;
                if (p == 0) break;
                v = multiplyMod(v, v, mod);
            }
            int res = 0;
            for (int x : ans) {
                res = (int) ((res + (long) x * x) % mod);
            }
            out.println(res);
        }

        static int[] multiplyMod(int[] a, int[] b, int mod) {
            int need = a.length + b.length - 1;
            int n = Math.max(2, Integer.highestOneBit(need - 1) << 1);

            double[] aReal = new double[n];
            double[] aImaginary = new double[n];
            for (int i = 0; i < a.length; i++) {
                int x = (a[i] % mod + mod) % mod;
                aReal[i] = x & ((1 << 15) - 1);
                aImaginary[i] = x >> 15;
            }
            fft(aReal, aImaginary, false);

            double[] bReal = new double[n];
            double[] bImaginary = new double[n];
            for (int i = 0; i < b.length; i++) {
                int x = (b[i] % mod + mod) % mod;
                bReal[i] = x & ((1 << 15) - 1);
                bImaginary[i] = x >> 15;
            }
            fft(bReal, bImaginary, false);

            double[] faReal = new double[n];
            double[] faImaginary = new double[n];
            double[] fbReal = new double[n];
            double[] fbImaginary = new double[n];

            for (int i = 0; i < n; i++) {
                int j = (n - i) & (n - 1);

                double a1r = (aReal[i] + aReal[j]) / 2;
                double a1i = (aImaginary[i] - aImaginary[j]) / 2;
                double a2r = (aImaginary[i] + aImaginary[j]) / 2;
                double a2i = (aReal[j] - aReal[i]) / 2;

                double b1r = (bReal[i] + bReal[j]) / 2;
                double b1i = (bImaginary[i] - bImaginary[j]) / 2;
                double b2r = (bImaginary[i] + bImaginary[j]) / 2;
                double b2i = (bReal[j] - bReal[i]) / 2;

                faReal[i] = a1r * b1r - a1i * b1i - a2r * b2i - a2i * b2r;
                faImaginary[i] = a1r * b1i + a1i * b1r + a2r * b2r - a2i * b2i;

                fbReal[i] = a1r * b2r - a1i * b2i + a2r * b1r - a2i * b1i;
                fbImaginary[i] = a1r * b2i + a1i * b2r + a2r * b1i + a2i * b1r;
            }

            fft(faReal, faImaginary, true);
            fft(fbReal, fbImaginary, true);
            int[] res = new int[need];
            for (int i = 0; i < need; i++) {
                long aa = (long) (faReal[i] + 0.5);
                long bb = (long) (fbReal[i] + 0.5);
                long cc = (long) (faImaginary[i] + 0.5);
                res[i] = (int) ((aa + ((bb % mod) << 15) + ((cc % mod) << 30)) % mod);
            }
            return res;
        }

        static void fft(double[] a, double[] b, boolean inverse) {
            int n = a.length;
            int shift = 32 - Integer.numberOfTrailingZeros(n);
            for (int i = 1; i < n; i++) {
                int j = Integer.reverse(i << shift);
                if (i < j) {
                    double temp = a[i];
                    a[i] = a[j];
                    a[j] = temp;
                    temp = b[i];
                    b[i] = b[j];
                    b[j] = temp;
                }
            }
            for (int len = 2; len <= n; len <<= 1) {
                int halfLen = len >> 1;
                for (int i = 0; i < n; i += len) {
                    int w = cs.length / len;
                    for (int j = 0, k = 0; j < halfLen; j++, k += w) {
                        double wA = inverse ? csi[halfLen + j] : cs[halfLen + j];
                        double wB = inverse ? sni[halfLen + j] : sn[halfLen + j];
                        double uA = a[i + j];
                        double uB = b[i + j];
                        double vA = a[i + j + halfLen] * wA - b[i + j + halfLen] * wB;
                        double vB = a[i + j + halfLen] * wB + b[i + j + halfLen] * wA;
                        a[i + j] = uA + vA;
                        b[i + j] = uB + vB;
                        a[i + j + halfLen] = uA - vA;
                        b[i + j + halfLen] = uB - vB;
                    }
                }
            }
            if (inverse) {
                for (int i = 0; i < n; i++) {
                    a[i] /= n;
                    b[i] /= n;
                }
            }
        }

    }

    static class InputReader {
        final InputStream is;
        final byte[] buf = new byte[1024];
        int pos;
        int size;

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

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

        int read() {
            if (size == -1)
                throw new InputMismatchException();
            if (pos >= size) {
                pos = 0;
                try {
                    size = is.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (size <= 0)
                    return -1;
            }
            return buf[pos++] & 255;
        }

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

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

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

    static class TaskG {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int mod = 998244353;
            int n = in.nextInt();
            int k = in.nextInt();
            int[] v = new int[10];
            for (int i = 0; i < k; i++) {
                int x = in.nextInt();
                v[x] = 1;
            }
            int[] ans = {1};
            int p = n / 2;
            while (true) {
                if (p % 2 != 0) {
                    ans = multiplyMod(ans, v, mod);
                }
                p /= 2;
                if (p == 0) break;
                v = multiplyMod(v, v, mod);
            }
            int res = 0;
            for (int x : ans) {
                res = (int) ((res + (long) x * x) % mod);
            }
            out.println(res);
        }

        static int[] multiplyMod(int[] a, int[] b, int mod) {
            int need = a.length + b.length - 1;
            int n = Math.max(2, Integer.highestOneBit(need - 1) << 1);

            double[] aReal = new double[n];
            double[] aImaginary = new double[n];
            for (int i = 0; i < a.length; i++) {
                int x = (a[i] % mod + mod) % mod;
                aReal[i] = x & ((1 << 15) - 1);
                aImaginary[i] = x >> 15;
            }
            fft(aReal, aImaginary, false);

            double[] bReal = new double[n];
            double[] bImaginary = new double[n];
            for (int i = 0; i < b.length; i++) {
                int x = (b[i] % mod + mod) % mod;
                bReal[i] = x & ((1 << 15) - 1);
                bImaginary[i] = x >> 15;
            }
            fft(bReal, bImaginary, false);

            double[] faReal = new double[n];
            double[] faImaginary = new double[n];
            double[] fbReal = new double[n];
            double[] fbImaginary = new double[n];

            for (int i = 0; i < n; i++) {
                int j = (n - i) & (n - 1);

                double a1r = (aReal[i] + aReal[j]) / 2;
                double a1i = (aImaginary[i] - aImaginary[j]) / 2;
                double a2r = (aImaginary[i] + aImaginary[j]) / 2;
                double a2i = (aReal[j] - aReal[i]) / 2;

                double b1r = (bReal[i] + bReal[j]) / 2;
                double b1i = (bImaginary[i] - bImaginary[j]) / 2;
                double b2r = (bImaginary[i] + bImaginary[j]) / 2;
                double b2i = (bReal[j] - bReal[i]) / 2;

                faReal[i] = a1r * b1r - a1i * b1i - a2r * b2i - a2i * b2r;
                faImaginary[i] = a1r * b1i + a1i * b1r + a2r * b2r - a2i * b2i;

                fbReal[i] = a1r * b2r - a1i * b2i + a2r * b1r - a2i * b1i;
                fbImaginary[i] = a1r * b2i + a1i * b2r + a2r * b1i + a2i * b1r;
            }

            fft(faReal, faImaginary, true);
            fft(fbReal, fbImaginary, true);
            int[] res = new int[need];
            for (int i = 0; i < need; i++) {
                long aa = (long) (faReal[i] + 0.5);
                long bb = (long) (fbReal[i] + 0.5);
                long cc = (long) (faImaginary[i] + 0.5);
                res[i] = (int) ((aa + ((bb % mod) << 15) + ((cc % mod) << 30)) % mod);
            }
            return res;
        }

        static void fft(double[] a, double[] b, boolean inverse) {
            int n = a.length;
            int shift = 32 - Integer.numberOfTrailingZeros(n);
            int[] rev = new int[n];
            for (int i = 1; i < n; i++) {
                rev[i] = (rev[i >> 1] >> 1) + ((i & 1) == 0 ? 0 : n / 2);
            }
            for (int i = 1; i < n; i++) {
//            int j = Integer.reverse(i << shift);
                int j = rev[i];
                if (i < j) {
                    double temp = a[i];
                    a[i] = a[j];
                    a[j] = temp;
                    temp = b[i];
                    b[i] = b[j];
                    b[j] = temp;
                }
            }
            for (int len = 2; len <= n; len <<= 1) {
                int halfLen = len >> 1;
                double[] cs = new double[halfLen];
                double[] sn = new double[halfLen];
                for (int i = 0; i < halfLen; i++) {
                    cs[i] = Math.cos(2 * Math.PI * i / len * (inverse ? -1 : 1));
                    sn[i] = Math.sin(2 * Math.PI * i / len * (inverse ? -1 : 1));
                }
                for (int i = 0; i < n; i += len) {
                    for (int j = 0; j < halfLen; j++) {
                        double wA = cs[j];
                        double wB = sn[j];
                        double uA = a[i + j];
                        double uB = b[i + j];
                        double vA = a[i + j + halfLen] * wA - b[i + j + halfLen] * wB;
                        double vB = a[i + j + halfLen] * wB + b[i + j + halfLen] * wA;
                        a[i + j] = uA + vA;
                        b[i + j] = uB + vB;
                        a[i + j + halfLen] = uA - vA;
                        b[i + j + halfLen] = uB - vB;
                    }
                }
            }
            if (inverse) {
                for (int i = 0; i < n; i++) {
                    a[i] /= n;
                    b[i] /= n;
                }
            }
        }

    }

    static class InputReader {
        final InputStream is;
        final byte[] buf = new byte[1024];
        int pos;
        int size;

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

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

        int read() {
            if (size == -1)
                throw new InputMismatchException();
            if (pos >= size) {
                pos = 0;
                try {
                    size = is.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (size <= 0)
                    return -1;
            }
            return buf[pos++] & 255;
        }

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

    }
}


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

public class LuckyTickets {

    // 2^23*7*17+1
    private static final int MOD = 998244353;

    //highest power of 2 that is a factor of MOD-1
    private static final int twoPow = 23;

    // any number such that ROOT^(2^twoPow)=1 & ROOT^(2^(twoPow-1))!=1
    private static final int ROOT = 15311432;

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

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

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

    /**
     * calculate roots of unity for ntt
     */
    private static long[] calcRoots(int k, boolean inverse) {
        long root = modPow(ROOT, modPow(2, twoPow - k));
        if (inverse) {
            root = modInv(root);
        }
        long[] roots = new long[k];
        if (k > 0) {
            roots[k - 1] = root;
        }
        for (int i = k - 1; i > 0; i--) {
            roots[i - 1] = (roots[i] * roots[i]) % MOD;
        }
        return roots;
    }

    /**
     * Change the indicies of an array, putting them into bit-reverse order.
     * array should have length 2^k
     */
    private static long[] reorderArray(long[] a, int k) {
        long[] ans = new long[a.length];
        for (int i = 0; i < a.length; i++) {
            ans[bitReverse(i, k)] = a[i];
        }
        return ans;
    }

    /**
     * coef.length = 2^k
     * Note: When computing the inverse, this function will return 2^k times the
     * correct answer. Please divide as needed.
     */
    private static long[] numberTheoreticTransform(long[] coef, int k, boolean inverse) {
        coef = reorderArray(coef, k);
        long[] roots = calcRoots(k, inverse);
        for (int s = 0; s < k; s++) {
            int len = 1 << s;
            for (int st = 0; st < coef.length; st += 2 * len) {
                // combine the vectors starting at st and st + len
                long curRoot = 1;
                for (int j = st; j < st + len; j++) {
                    long t = (curRoot * coef[j + len]) % MOD;
                    long u = coef[j];
                    coef[j] = (u + t) % MOD;
                    coef[j + len] = (u - t) % MOD;
                    curRoot = (roots[s] * curRoot) % MOD;
                }
            }
        }
        return coef;
    }

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


import java.io.*;
import java.lang.reflect.Array;
import java.util.*;
import java.math.BigInteger;
import java.util.Collections.*;
import java.util.function.Consumer;

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

public class Main{

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

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

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

    class FastScanner{

        StringTokenizer st;
        BufferedReader br;

        FastScanner( BufferedReader _br ){
            br = _br;
        }

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

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

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

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

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

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

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

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

    int n;
    int[] a, pr, nx;
    ArrayList<Integer> Q;
    boolean[] used;

    void solve(){
        n = sc.nextInt();
        a = new int[n];
        pr = new int[n];
        nx = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = sc.nextInt();
            pr[i] = i - 1;
            nx[i] = i + 1;
        }

        Q = new ArrayList<>();
        used = new boolean[n];
        for (int i = 1; i <= n-2; i++) {
            try_add(i);
        }
        long ans = 0;

        while( !Q.isEmpty() ){
            int i = Q.get(Q.size()-1);
            Q.remove( Q.size() - 1 );
            nx[pr[i]] = nx[i];
            pr[nx[i]] = pr[i];
            ans += min( a[pr[i]], a[nx[i]] );
            try_add( pr[i] );
            try_add( nx[i] );
        }

        if( 3 <= n ){
            int i = nx[0];
            while( nx[i] != n ){
                ans += min( a[pr[i]], a[nx[i]] );
                i = nx[i];
            }
        }

        out.println( ans );
    }

    private void try_add(int i) {
        if( used[i] )return;

        if( 1<=i && i <=n-2 && a[pr[i]] >= a[i] && a[i] <= a[nx[i]] ){
            Q.add( i );
            used[i] = true;
        }
    }

}


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

public class CF1384E extends PrintWriter {
	// https://codeforces.com/contest/1384/problem/E
	public Scanner sc = new Scanner(System.in);

	public CF1384E() {
		super(System.out);
	}

	public static void main(String[] args) {
		CF1384E o = new CF1384E();
		o.main();
		o.flush();
	}

	public static final int SZ = 20;
	public int[] ds = new int[SZ];

	public void main() {
		int t = sc.nextInt();
		while (t-- > 0) {
			int n = sc.nextInt();
			byte[] sa = sc.next().getBytes();
			byte[] sb = sc.next().getBytes();
			for (int id = 0; id < SZ; id++) {
				ds[id] = id;
			}
			int[] es = new int[SZ];
			for (int i = 0; i < n; i++) {
				if (sa[i] != sb[i]) {
					int u = sa[i] - 'a';
					int v = sb[i] - 'a';
					join(u, v);
					es[u] |= (1 << v);
				}
			}
			int ans = SZ * 2;
			for (int id = 0; id < SZ; id++) {
				if (ds[id] == id) {
					ans = ans - 1;
				}
			}
			boolean[] dags = new boolean[1 << SZ];
			dags[0] = true;
			int cnt_ = 0;
			for (int state = 1; state < (1 << SZ); state++) {
				int cnt = 0;
				for (int tmp = state; tmp > 0; tmp &= (tmp - 1)) {
					cnt++;
				}
				for (int id = 0; id < SZ; id++) {
					if ((state & (1 << id)) > 0) {
						int a = state ^ (1 << id);
						// chu y thu tu duyet cua cac bai toan
						if (dags[a]) {
							if ((a & es[id]) == 0) {
								dags[state] = true;
								cnt_ = Math.max(cnt_, cnt);
								break;
							}
						}
					}
				}
			}
			ans -= cnt_;
			println(ans);
		}
	}

	private void join(int u, int v) {
		u = find(u);
		v = find(v);
		if (u != v) {
			ds[u] = v;
		}

	}

	private int find(int u) {
		if (ds[u] == u) {
			return u;
		}
		ds[u] = find(ds[u]);
		return ds[u];
	}
}


// https://codeforces.com/blog/entry/80562
import java.io.*;
import java.util.*;

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

	static final int A = 20;
	int[] ds = new int[A];
	int find(int i) {
		return ds[i] < 0 ? i : (ds[i] = find(ds[i]));
	}
	void join(int i, int j) {
		i = find(i);
		j = find(j);
		if (i == j)
			return;
		if (ds[i] > ds[j])
			ds[i] = j;
		else {
			if (ds[i] == ds[j])
				ds[i]--;
			ds[j] = i;
		}
	}
	void main() {
		int t = sc.nextInt();
		while (t-- > 0) {
			int n = sc.nextInt();
			byte[] sa = sc.next().getBytes();
			byte[] sb = sc.next().getBytes();
			Arrays.fill(ds, -1);
			int[] aa = new int[A];
			for (int i = 0; i < n; i++)
				if (sa[i] != sb[i]) {
					int u = sa[i] - 'a';
					int v = sb[i] - 'a';
					join(u, v);
					aa[u] |= 1 << v;
				}
			int ans = A * 2;
			for (int u = 0; u < A; u++)
				if (ds[u] < 0)
					ans--;
			boolean[] dag = new boolean[1 << A]; dag[0] = true;
			int cnt_ = 0;
			for (int a, b = 1; b < 1 << A; b++) {
				int cnt = 0;
				for (a = b; a > 0; a &= a - 1)
					cnt++;
				for (int u = 0; u < A; u++)
					if ((a = b ^ 1 << u) != b && dag[a] && (a & aa[u]) == 0) {
						dag[b] = true;
						cnt_ = Math.max(cnt_, cnt);
						break;
					}
			}
			ans -= cnt_;
			println(ans);
		}
	}
}


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

public class Solution {
    static final FS sc = new FS();
    static final PrintWriter pw = new PrintWriter(System.out);
    static  int alp = 20;
    static List<List<Integer>> G;
    public static void main(String[] args) {
        int t = sc.nextInt();
        while (t-- > 0) {
            int n = sc.nextInt();
            char[] a = sc.next().toCharArray();
            char[] b = sc.next().toCharArray();
            G = new ArrayList<>();
            for(int i = 0;i < alp;i++) {
                G.add(new ArrayList<>());
            }
            int[] adj = new int[alp];
            for(int i = 0;i < n;i++) {
                if (a[i] != b[i]) {
                    G.get(a[i] - 'a').add(b[i] - 'a');
                    G.get(b[i] - 'a').add(a[i] - 'a');
                    adj[a[i] - 'a'] |= 1 << (b[i] - 'a');
                }
            }
            int components = 0;
            boolean[] vis = new boolean[alp];
            for (int i = 0;i < alp;i++) {
                if (!vis[i]) {
                    dfs(i, vis);
                    components++;
                }
            }
            int ans = 0;
            boolean[] dp = new boolean[1 << alp];
            dp[0] = true;
            for (int mask = 0;mask < 1 << alp;mask++) {
                if (dp[mask]) {
                    ans = Math.max(ans, Integer.bitCount(mask));
                    for (int u = 0;u < alp;u++) {
                        if ((~mask >> u & 1) == 1 && (adj[u] & mask) == 0) {
                            dp[mask | 1 << u] = true;
                        }
                    }
                }
            }
            pw.println(2 * alp - components - ans);
        }
        pw.flush();
    }

    private static void dfs(int u, boolean[] vis) {
        vis[u] = true;
        for (Integer v : G.get(u)) {
            if (!vis[v]) {
                dfs(v, vis);
            }
        }
    }

    static class FS {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer("");
        String next() {
            while(!st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch(Exception ignored) {}
            }
            return st.nextToken();
        }
        int[] nextArray(int n) {
            int[] a = new int[n];
            for(int i = 0;i < n;i++) {
                a[i] = nextInt();
            }
            return a;
        }
        int nextInt() {
            return Integer.parseInt(next());
        }
        long nextLong() {
            return Long.parseLong(next());
        }
    }
}


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

public class C {

	static final int P = 1_000_000_007;

	static boolean nextPermutation(int[] a) {
		int n = a.length;
		int ptr = n - 1;
		while (ptr > 0 && a[ptr - 1] >= a[ptr]) {
			ptr--;
		}

		for (int i = ptr, j = n - 1; i < j; i++, j--) {
			int tmp = a[i];
			a[i] = a[j];
			a[j] = tmp;
		}

		if (ptr == 0) {
			return false;
		}

		for (int i = ptr;; i++) {
			if (a[ptr - 1] < a[i]) {
				int tmp = a[ptr - 1];
				a[ptr - 1] = a[i];
				a[i] = tmp;
				return true;
			}
		}
	}

	int slow(int n, int k) {
		int[] p = new int[n];
		for (int i = 0; i < n; i++) {
			p[i] = i;
		}
		int ans = 0;
		do {
			int m = 0;
			int offset = 0;
			for (int i = 0; i < n; ++i)
				if (m < p[i]) {
					m = p[i];
					offset = 0;
				} else {
					offset = offset + 1;
					if (offset == k)
						break;
				}
			ans += m == n - 1 ? 1 : 0;
		} while (nextPermutation(p));
		return ans;
	}

	void submit() {
		int n = nextInt();
		int k = nextInt();
		int[] a = new int[n + 1];
		a[0] = 1;
		for (int i = 1; i <= k && i <= n; i++) {
			a[i] = (int) ((long) (i + 1) * a[i - 1] % P);
		}

		if (n <= k) {
			out.println(0);
			return;
		}

		int mult = a[k - 1];

		for (int i = k + 1; i <= n; i++) {
			a[i] = (int) ((long) (i + 1) * a[i - 1] % P);
			a[i] -= (int) ((long) mult * a[i - k - 1] % P);
			if (a[i] < 0) {
				a[i] += P;
			}

			mult = (int) ((long) mult * i % P * inv(i - k) % P);
		}

		int fact = 1;
		for (int i = 1; i <= n; i++) {
			fact = (int) ((long) fact * i % P);
		}

		n--;

		fact -= a[n];
		if (fact < 0) {
			fact += P;
		}

		out.println(fact);
	}

	int inv(int x) {
		return x == 1 ? 1 : (P - (int) ((long) (P / x) * inv(P % x) % P));
	}

	void preCalc() {

	}

	void stress() {

	}

	void test() {
		int[] a = new int[11];
		a[0] = 1;
		a[1] = 2;
		a[2] = 6;
		for (int i = 3; i < a.length; i++) {
			a[i] = (i + 1) * a[i - 1] - (i - 1) * (i - 2) * a[i - 3];
		}
		System.err.println(Arrays.toString(a));

		a[0] = 1;
		a[1] = 2;
		a[2] = 6;
		a[3] = 24;
		for (int i = 4; i < a.length; i++) {
			a[i] = (i + 1) * a[i - 1] - (i - 1) * (i - 2) * (i - 3) * a[i - 4];
		}
		System.err.println(Arrays.toString(a));

		for (int n = 1; n <= 11; n++) {
			System.err.println(slow(n, 2) + " " + a[n]);
		}
	}

	C() throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		preCalc();
		submit();
		// stress();
		// test();
		out.close();
	}

	static final Random rng = new Random();

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

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

	BufferedReader br;
	PrintWriter out;
	StringTokenizer st;

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

	String nextString() {
		try {
			return br.readLine();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

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

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

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


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

public class Main {

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

class Solve {

    InputStream is;
    PrintWriter out;
    String INPUT = "";

    //------------> Solution
    public void solve() {
        int n = nextInt();
        for (int i = 0; i < n; i++) {
            String s = nextString();
            s = s.split("'", 2)[1];
            System.out.println(check(s));;
        }
    }

    public String check(String s) {
        switch (s.length()) {
            case 1:
                if (s.equals("9")) {
                    return "1989";
                } else {
                    return "199" + s;
                }
            case 2:
                if (s.equals("99")) {
                    return "1999";
                } else {
                    return "20" + s;
                }
            case 3:
                String s1 = check(s.substring(2));
                String s2 = check(s.substring(1));
                for (int i = 1; i < 100; i++) {
                    String ans = i + s;
                    if (!ans.equals(s1) && !ans.equals(s2) && Integer.parseInt(ans) >= 1989) {
                        return ans;
                    }
                }
                break;
            default:

                ArrayList<String> list = new ArrayList<>();
                for (int i = 1; i < s.length(); i++) {
                    list.add(check(s.substring(i)));
                }
                if (!list.contains(s) && !s.startsWith("0") && Integer.parseInt(s) >= 1989) {
                    return s;
                }
                int i = 1;
                while (true) {
                    String ans = i++ + s;
                    if (!list.contains(ans)) {
                        return ans;
                    }
                }
        }
        return s;
    }

    //End !!!
    void run() throws Exception {
        is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        out = new PrintWriter(System.out);
        long s = System.currentTimeMillis();
        solve();
        out.flush();
        if (!INPUT.isEmpty()) {
            print(System.currentTimeMillis() - s + "ms");
        }
    }

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

    private void sout(Object s) {
        out.print(s);
    }

    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 nextDouble() {
        return Double.parseDouble(nextString());
    }

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

    private String nextString() {
        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[] nextString(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] = nextString(m);
        }
        return map;
    }

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

    private int nextInt() {
        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 nextLong() {
        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 void print(Object... o) {
        if (INPUT.length() > 0) {
            System.out.println(Arrays.deepToString(o));
        }
    }

}


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

public class E {

	BufferedReader br;
	PrintWriter out;
	StringTokenizer st;
	boolean eof;

	static final int[] PS = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41,
			43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 };

	int l, r, p;
	List<Integer> goodAL = new ArrayList<>();

	static int[] toIntArray(List<Integer> a) {
		int[] ret = new int[a.size()];
		int i = 0;
		for (Integer x : a) {
			ret[i++] = x;
		}
		return ret;
	}

	void dfs(int x, int i) {
		if (i == PS.length) {
			return;
		}
		dfs(x, i + 1);
		if (x <= r / PS[i]) {
			int next = x * PS[i];
			goodAL.add(next);
			dfs(next, i);
		}
	}

	void solve() throws IOException {
		l = nextInt();
		r = nextInt();
		p = nextInt();
		goodAL.add(1);
		dfs(1, 0);
		int[] good = toIntArray(goodAL);
		Arrays.sort(good);

		int n = good.length;

		int[] dp = new int[n];
		int oo = Integer.MAX_VALUE / 3;
		Arrays.fill(dp, oo);
		dp[0] = 0;
		for (int x = 2; x <= p; x++) {
			for (int i = 0, j = 0; i < n; i++) {
				long needL = (long) good[i] * x;
				if (needL > r) {
					break;
				}
				while (j < n && good[j] < needL) {
					j++;
				}
				if (j == n || good[j] != needL) {
					continue;
				}
				if (dp[i] + x < p) {
					int a = dp[j];
					int b = dp[i] + 1;
					dp[j] = (a <= b) ? a : b;
				}
			}
		}

		int ans = 0;

		for (int i = 0; i < n; i++) {
			if (good[i] >= l && dp[i] != oo) {
				ans++;
			}
		}

		out.println(ans);
	}

	E() throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		solve();
		out.close();
	}

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

	String nextToken() {
		while (st == null || !st.hasMoreTokens()) {
			try {
				st = new StringTokenizer(br.readLine());
			} catch (Exception e) {
				eof = true;
				return null;
			}
		}
		return st.nextToken();
	}

	String nextString() {
		try {
			return br.readLine();
		} catch (IOException e) {
			eof = true;
			return null;
		}
	}

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

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

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


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

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

class TaskE {

    int ptrNumbers;
    int numbers[];
    int primes[];

    void dfs(int depth, int now, int maxCont, int count) {
        if (depth == primes.length) {
            if (maxCont + count <= 100) {
                numbers[ptrNumbers++] = now;
            }
            return;
        }

        boolean enable = (primes[depth] * primes[depth]) > 100;
        for (int i = 0; ; ++i) {
            dfs(depth + 1, now, i == 0 ? maxCont : primes[depth], enable ? count + i : count);
            if (now * (long)primes[depth] > 1000000000) {
                break;
            }
            now *= primes[depth];
        }
    }

    void find() {
        ArrayList<Integer> primes = new ArrayList<Integer>();
        for (int i = 2; i <= 100; ++i) {
            boolean isPrime = true;
            for (int j = 2; j < i; ++j) {
                if (i % j == 0) {
                    isPrime = false;
                }
            }

            if (isPrime) {
                primes.add(i);
            }
        }

        this.primes = new int[primes.size()];
        for (int i = 0; i < primes.size(); ++i) {
            this.primes[i] = primes.get(i);
        }

        numbers = new int[2759075];
        ptrNumbers = 0;
        dfs(0, 1, 1, 0);

        Arrays.sort(numbers);
    }

    int leastNeed[];
    boolean included[];

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        find();
        leastNeed = new int[ptrNumbers];
        included = new boolean[ptrNumbers];
        Arrays.fill(leastNeed, Integer.MAX_VALUE / 100);

        int l = in.nextInt();
        int r = in.nextInt();
        int maxSteps = in.nextInt();

        leastNeed[0] = 0;

        int ans = 0;
        for (int i = 0; i < ptrNumbers; ++i) {
            if (numbers[i] < l || numbers[i] > r) {
                included[i] = true;
            }
        }

        for (int i = 2; i < maxSteps; ++i) {

            int leftPtr = 0;
            for (int j = 0; j < ptrNumbers; ++j) {

                while (numbers[leftPtr] * i < numbers[j]) {
                    ++leftPtr;
                }

                if (numbers[leftPtr] * (long)i == numbers[j]) {

                    if (leastNeed[leftPtr] + 1 < leastNeed[j]) {

                        leastNeed[j] = leastNeed[leftPtr] + 1;

                        if (!included[j]) {
                            if (leastNeed[j] + i <= maxSteps) {
                                ++ans;
                                included[j] = true;
                            }
                        }
                    }
                }
            }
        }

        out.println(ans);
    }
}

class InputReader {
    BufferedReader reader;
    StringTokenizer tokenizer;

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

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

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

    }


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

public class E {

	BufferedReader br;
	PrintWriter out;
	StringTokenizer st;
	boolean eof;

	static final int[] PS = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41,
			43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 };

	int l, r, p;
	List<Integer> goodAL = new ArrayList<>();

	static int[] toIntArray(List<Integer> a) {
		int[] ret = new int[a.size()];
		int i = 0;
		for (Integer x : a) {
			ret[i++] = x;
		}
		return ret;
	}

	void dfs(int x, int i) {
		if (i == PS.length) {
			return;
		}
		dfs(x, i + 1);
		if (x <= r / PS[i]) {
			int next = x * PS[i];
			goodAL.add(next);
			dfs(next, i);
		}
	}

	void solve() throws IOException {
		l = nextInt();
		r = nextInt();
		p = nextInt();
		goodAL.add(1);
		dfs(1, 0);
		int[] good = toIntArray(goodAL);
		Arrays.sort(good);

		int n = good.length;

		int[] dp = new int[n];
		int oo = Integer.MAX_VALUE / 3;
		Arrays.fill(dp, oo);
		dp[0] = 0;
		for (int x = 2; x <= p; x++) {
			for (int i = 0, j = 0; i < n; i++) {
				long needL = (long) good[i] * x;
				if (needL > r) {
					break;
				}
				while (j < n && good[j] < needL) {
					j++;
				}
				if (j == n || good[j] != needL) {
					continue;
				}
				if (dp[i] + x < p) {
					dp[j] = Math.min(dp[j], dp[i] + 1);
				}
			}
		}

		int ans = 0;

		for (int i = 0; i < n; i++) {
			if (good[i] >= l && dp[i] != oo) {
				ans++;
			}
		}

		out.println(ans);
	}

	E() throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		solve();
		out.close();
	}

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

	String nextToken() {
		while (st == null || !st.hasMoreTokens()) {
			try {
				st = new StringTokenizer(br.readLine());
			} catch (Exception e) {
				eof = true;
				return null;
			}
		}
		return st.nextToken();
	}

	String nextString() {
		try {
			return br.readLine();
		} catch (IOException e) {
			eof = true;
			return null;
		}
	}

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

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

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


import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
import java.io.PrintStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import java.io.Writer;
import java.util.Collection;
import java.util.List;
import java.util.BitSet;
import java.io.IOException;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import java.util.TreeSet;
import java.math.BigInteger;
import java.util.Collections;
import java.io.InputStream;

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

class TaskE {
    // 2944730
    int[] primes;
    int[] candidates;
    int numCandidates;
    public void solve(int testNumber, MyScanner in, MyPrintWriter out) {
        int N = (int) 1e9;
        int L = in.nextInt(), R = in.nextInt();
        int p = in.nextInt();
        if(p<3){
            out.println(0);return;
        }
        primes = MathUtils.generatePrimes(p + 1);
        candidates = new int[2944730];
        Arrays.fill(candidates, Integer.MAX_VALUE);
        numCandidates = 0;
        gen(0, 1L, N);
        Arrays.sort(candidates);
        int[] dist = new int[numCandidates];
        Arrays.fill(dist, Integer.MAX_VALUE);
        dist[0] = 0;// 1
        boolean[] answer = new boolean[numCandidates];
        answer[0] = true;
        for(int n=2;n<=p;n++){
            for (int i = 0, j = 0; i < dist.length; i++)if(dist[i] < p - n && candidates[i] <= N/n){
                int nxt = candidates[i] * n;
                while(candidates[j] != nxt)j++;
                if(dist[j] > dist[i] + 1){
                    dist[j] = dist[i] + 1;
                    answer[j] = true;
                }
            }
        }
        int res = 0;
        for (int i = 0; i < answer.length; i++)if(answer[i] && L <= candidates[i] && candidates[i] <= R)res++;
        out.println(res);
    }

    private void gen(int p, long number, int N) {
        if (p >= primes.length) {
            candidates[numCandidates++] = (int) number;
            return;
        }
        while (number <= N) {
            gen(p + 1, number, N);
            number *= primes[p];
        }
    }
}

class MyScanner {
    private final InputStream in;

    public MyScanner(InputStream in) {
        this.in = in;
    }

    int bufLen;
    int bufPtr;
    byte[] buf = new byte[1024];

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

    public int nextInt() {
        try {
            int c = read();
            if (c == -1) return c;
            while (c != '-' && (c < '0' || '9' < c)) {
                c = read();
                if (c == -1) return c;
            }
            if (c == '-') return -nextInt();
            int res = 0;
            do {
                res *= 10;
                res += c - '0';
                c = read();
            } while ('0' <= c && c <= '9');
            return res;
        } catch (Exception e) {
            return -1;
        }
    }

    }

class MyPrintWriter {
    PrintWriter out;

    public MyPrintWriter(OutputStream outputStream) {
        out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
    }

    public MyPrintWriter(Writer writer) {
        out = new PrintWriter(writer);
    }

    public void println(Object... os) {
        for (int i = 0; i < os.length - 1; i++) {
            out.print(os[i]);
            out.print(' ');
        }
        out.println(os[os.length - 1]);
    }

    public void close() {
        out.close();
    }

    }

class MathUtils {

    public static int[] generatePrimes(int upTo) {
        int N = upTo;
        boolean[] isPrime = generatePrimaryTable(N);
        int m = 0;
        for (boolean p : isPrime) if (p) m++;
        int[] res = new int[m];
        m = 0;
        for (int i = 0; i < isPrime.length; i++) {
            if (isPrime[i]) res[m++] = i;
        }
        return res;
    }

    public static boolean[] generatePrimaryTable(int n) {
        boolean[] isPrime = new boolean[n];
        Arrays.fill(isPrime, true);
        if (0 < n) isPrime[0] = false;
        if (1 < n) isPrime[1] = false;
        for (int i = 2; i * i < n; i++) {
            if (isPrime[i]) {
                for (int j = i * i; j < n; j += i)
                    isPrime[j] = false;
            }
        }
        return isPrime;
    }

    }


import java.io.IOException;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.ArrayList;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.io.InputStream;

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

class TaskE {
    public void solve(int testNumber, InputReader in, OutputWriter out) {
        long l = in.readLong();
        long r = in.readLong();
        int p = in.readInt();

        boolean[] is_prime = Prime.GetIsPrimeList(100);
        long[] v = new long[3000000];
        v[0] = 1;
        int e = 1;
        for (int i = 2; i < 100; ++i) {
            if (is_prime[i]) {
                int ee = e;
                for (int j = 0; j < ee; ++j) {
                    long temp = v[j];
                    while (temp * i <= r) {
                        temp *= i;
                        v[e++] = temp;
                    }
                }
            }
        }
        long[] D = new long[v.length];
        boolean [] good = new boolean[D.length];

        Arrays.sort(v, 0, e);

        for (int i = 1; i < e; ++i) {
            D[i] = 200;
        }
        good[0] = true;

        for (int i = 2; i <= p; ++i) {
            int j = 0;
            int k = 0;
            while (true) {
                long temp = v[j] * i;
                while (k < e && v[k] < temp) k++;
                if (k == e) break;
                if (v[k] == temp && D[k] > D[j] + 1) {
                    D[k] = D[j] + 1;
                    if (D[k] + i <= p) {
                        good[k] = true;
                    }
                }
                j++;
            }
        }
        long res = 0;
        for (int i = 0; i < e; ++i) {
            if (l <= v[i] && v[i] <= r && good[i]) {
                res++;
            }
        }
        out.printLine(res);
    }
}

class InputReader {

    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;

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

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

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

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

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

    }

class OutputWriter {
    private final PrintWriter writer;

    public OutputWriter(OutputStream outputStream) {
        writer = new PrintWriter(outputStream);
    }

    public OutputWriter(Writer writer) {
        this.writer = new PrintWriter(writer);
    }

    public void print(Object...objects) {
        for (int i = 0; i < objects.length; i++) {
            if (i != 0)
                writer.print(' ');
            writer.print(objects[i]);
        }
    }

    public void printLine(Object...objects) {
        print(objects);
        writer.println();
    }

    public void close() {
        writer.close();
    }

}

class Prime {
    // returns a list of n + 1 boolean, 0 to n - 1.
    // ith value true means i is prime, false means i is not a prime.
    public static boolean[] GetIsPrimeList(int n) {
        boolean[] res = new boolean[n + 1];
        for (int i = 0; i < res.length; ++i) {
            res[i] = true;
        }
        res[0] = false;
        res[1] = false;
        for (int i = 2; i * i < res.length; ++i) {
            if (res[i] == true) {
                for (int j = i * i; j < res.length; j += i) {
                    res[j] = false;
                }
            }
        }
        return res;
    }

    }


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

public class E {

	BufferedReader br;
	PrintWriter out;
	StringTokenizer st;
	boolean eof;

	static final int[] PS = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41,
			43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 };

	int l, r, p;
	List<Integer> goodAL = new ArrayList<>();

	static int[] toIntArray(List<Integer> a) {
		int[] ret = new int[a.size()];
		int i = 0;
		for (Integer x : a) {
			ret[i++] = x;
		}
		return ret;
	}

	void dfs(int x, int i) {
		if (i == PS.length) {
			return;
		}
		dfs(x, i + 1);
		long next = (long) x * PS[i];
		if (next <= r) {
			goodAL.add((int) next);
			dfs((int) next, i);
		}
	}

	void solve() throws IOException {
		l = nextInt();
		r = nextInt();
		p = nextInt();
		goodAL.add(1);
		dfs(1, 0);
		int[] good = toIntArray(goodAL);
		Arrays.sort(good);

		int n = good.length;

		int[] dp = new int[n];
		int oo = Integer.MAX_VALUE / 3;
		Arrays.fill(dp, oo);
		dp[0] = 0;
		for (int x = 2; x <= p; x++) {
			for (int i = 0, j = 0; i < n; i++) {
				long needL = (long) good[i] * x;
				if (needL > r) {
					break;
				}
				while (j < n && good[j] < needL) {
					j++;
				}
				if (j == n || good[j] != needL) {
					continue;
				}
				if (dp[i] + x < p) {
					dp[j] = Math.min(dp[j], dp[i] + 1);
				}
			}
		}

		int ans = 0;

		for (int i = 0; i < n; i++) {
			if (good[i] >= l && dp[i] != oo) {
				ans++;
			}
		}

		out.println(ans);
	}

	E() throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		solve();
		out.close();
	}

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

	String nextToken() {
		while (st == null || !st.hasMoreTokens()) {
			try {
				st = new StringTokenizer(br.readLine());
			} catch (Exception e) {
				eof = true;
				return null;
			}
		}
		return st.nextToken();
	}

	String nextString() {
		try {
			return br.readLine();
		} catch (IOException e) {
			eof = true;
			return null;
		}
	}

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

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

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


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

public class E {

	BufferedReader br;
	PrintWriter out;
	StringTokenizer st;
	boolean eof;

	static final int[] PS = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41,
			43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 };

	int l, r, p;
	List<Integer> goodAL = new ArrayList<>();

	static int[] toIntArray(List<Integer> a) {
		int[] ret = new int[a.size()];
		int i = 0;
		for (Integer x : a) {
			ret[i++] = x;
		}
		return ret;
	}

	void dfs(int x, int i) {
		if (i == PS.length) {
			return;
		}
		dfs(x, i + 1);
		if (x <= r / PS[i]) {
			int next = x * PS[i];
			goodAL.add(next);
			dfs(next, i);
		}
	}

	void solve() throws IOException {
		l = nextInt();
		r = nextInt();
		p = nextInt();
		goodAL.add(1);
		dfs(1, 0);
		int[] good = toIntArray(goodAL);
		Arrays.sort(good);

		int n = good.length;

		int[] dp = new int[n];
		int oo = Integer.MAX_VALUE / 3;
		Arrays.fill(dp, oo);
		dp[0] = 0;
		for (int x = 2; x <= p; x++) {
			for (int i = 0, j = 0; i < n; i++) {
				long needL = (long) good[i] * x;
				if (needL > r) {
					break;
				}
				while (j < n && good[j] < needL) {
					j++;
				}
				if (j == n || good[j] != needL) {
					continue;
				}
				if (dp[i] + x < p && dp[j] > dp[i] + 1) {
					dp[j] = dp[i] + 1;
				}
			}
		}

		int ans = 0;

		for (int i = 0; i < n; i++) {
			if (good[i] >= l && dp[i] != oo) {
				ans++;
			}
		}

		out.println(ans);
	}

	E() throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		solve();
		out.close();
	}

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

	String nextToken() {
		while (st == null || !st.hasMoreTokens()) {
			try {
				st = new StringTokenizer(br.readLine());
			} catch (Exception e) {
				eof = true;
				return null;
			}
		}
		return st.nextToken();
	}

	String nextString() {
		try {
			return br.readLine();
		} catch (IOException e) {
			eof = true;
			return null;
		}
	}

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

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

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


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

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

	public void run() {
		Scanner sc = new Scanner(System.in);
		long n = sc.nextLong();
		System.out.println(f(n));
	}

	long f(long n) {
		int Len = (int) 4e5;
		long[] pi_upper = new long[Len];
		long[] pi_lower = new long[Len];
		for (int i = 1; i < Len; ++i) {
			pi_lower[i] = i;
			pi_upper[i] = n / i;
		}
		boolean[] isPrime = new boolean[Len];
		Arrays.fill(isPrime, true);
		isPrime[0] = false;
		isPrime[1] = false;

		ArrayList<Integer> primeList = new ArrayList<>();
		for (int i = 2; i < isPrime.length; ++i) {
			if (!isPrime[i]) {
				continue;
			}
			primeList.add(i);
			for (int j = i * 2; j < isPrime.length; j += i) {
				isPrime[j] = false;
			}
		}
		for (int t = 0; t < primeList.size(); ++t) {
			int p = primeList.get(t);
			for (int i = 1; i < Len && n / i >= (long) p * p; ++i) {
				pi_upper[i] -= ((long) p * i < Len ? pi_upper[p * i] : pi_lower[(int) (n / i / p)]) - (t + 1);
			}
			for (int i = Len - 1; i >= (long) p * p; --i) {
				pi_lower[i] -= pi_lower[i / p] - (t + 1);
			}
		}
		long ans = 0;
		for (long p : primeList) {
			if (p * p > n) {
				break;
			}
			if (p * p * p <= n && p * p * p > 0) {
				++ans;
			}
			if (n / p > p) {
				if (p < Len)
					ans += pi_upper[(int) p] - pi_lower[(int) p];
				else
					ans += pi_lower[(int) (n / p)] - pi_lower[(int) p];
			}
		}
		return ans;
	}

	void tr(Object... objects) {
		System.out.println(Arrays.deepToString(objects));
	}
}


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

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

	public static int[] sieveEratosthenes(int n) {
		if (n <= 32) {
			int[] primes = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };
			for (int i = 0; i < primes.length; i++) {
				if (n < primes[i]) {
					return Arrays.copyOf(primes, i);
				}
			}
			return primes;
		}

		int u = n + 32;
		double lu = Math.log(u);
		int[] ret = new int[(int) (u / lu + u / lu / lu * 1.5)];
		ret[0] = 2;
		int pos = 1;

		int[] isnp = new int[(n + 1) / 32 / 2 + 1];
		int sup = (n + 1) / 32 / 2 + 1;

		int[] tprimes = { 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };
		for (int tp : tprimes) {
			ret[pos++] = tp;
			int[] ptn = new int[tp];
			for (int i = (tp - 3) / 2; i < tp << 5; i += tp)
				ptn[i >> 5] |= 1 << (i & 31);
			for (int j = 0; j < sup; j += tp) {
				for (int i = 0; i < tp && i + j < sup; i++) {
					isnp[j + i] |= ptn[i];
				}
			}
		}

		// 3,5,7
		// 2x+3=n
		int[] magic = { 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13, 31, 22, 28, 18, 26, 10, 7, 12, 21, 17,
				9, 6, 16, 5, 15, 14 };
		int h = n / 2;
		for (int i = 0; i < sup; i++) {
			for (int j = ~isnp[i]; j != 0; j &= j - 1) {
				int pp = i << 5 | magic[(j & -j) * 0x076be629 >>> 27];
				int p = 2 * pp + 3;
				if (p > n)
					break;
				ret[pos++] = p;
				if ((long) p * p > n)
					continue;
				for (int q = (p * p - 3) / 2; q <= h; q += p)
					isnp[q >> 5] |= 1 << q;
			}
		}

		return Arrays.copyOf(ret, pos);
	}

	int[] primes = sieveEratosthenes(400000);

	void solve()
	{
		long n = nl();
		long ans = 0;
		MeisselLehmer2 ml = new MeisselLehmer2(n/2);
		for(int i = 0;i < primes.length;i++) {
			long plus = ml.pi(n/primes[i]) - (i+1);
			if(plus <= 0)break;
			ans += plus;
		}

		for(int p : primes) {
			if((long)p*p*p <= n) {
				ans++;
			}else {
				break;
			}
		}
		out.println(ans);
	}

	public static class MeisselLehmer2 {
		int[] primes;
//		int[] cump;
		int[] xcums;
		long[] isp;

		int cachelimit;
//		Map<Long, Long> picache;
//		Map<Long, Long> phicache;
		LongHashCounterL picache;
		LongHashCounterL phicache;
		boolean cachePhi = false;

		int[][] cumps;
//		int[] FP = {2,3,5,7,11,13,17};
		int[] FP = {2,3,5,7,11,13,17,19};
		int M = FP.length;

		int B = 100;
		// 10^14 -> 200
		// 10^14/8 -> 100~200

		public MeisselLehmer2(long n)
		{
			assert n >= 4;
//			picache = new HashMap<>();
//			phicache = new HashMap<>();
			picache = new LongHashCounterL();
			phicache = new LongHashCounterL();

			int s = (int)Math.sqrt(n)*B; // not overflow!
			cachelimit = s;
			this.primes = sieveEratosthenes(s);
			xcums = new int[(s>>>6)+1];
			isp = new long[(s>>>6)+1];
			for(int p : primes)isp[p>>>6] |= 1L<<p;
			for(int i = 0;i < xcums.length-1;i++)xcums[i+1] = xcums[i] + Long.bitCount(isp[i]);

			cumps = new int[M][];
			boolean[] b = {true};
			int len = 1;
			for(int i = 0;i < M;i++){
				len *= FP[i];
				boolean[] c = new boolean[len];
				for(int j = 0;j < FP[i];j++){
					System.arraycopy(b, 0, c, j*b.length, b.length);
				}
				for(int k = 0;k < len;k+=FP[i])c[k] = false;
				cumps[i] = new int[len+1];
				for(int j = 0;j < len;j++)cumps[i][j+1] = cumps[i][j] + (c[j] ? 1 : 0);
				FP[i] = len;
				b = c;
			}
		}

		private long sqrt(long n)
		{
			long i = Math.max(0, (long)Math.sqrt(n)-2);
			while(i*i <= n)i++;
			return i-1;
		}

		private long cbrt(long n)
		{
			long i = Math.max(0, (long)Math.cbrt(n)-2);
			while(i*i*i <= n)i++;
			return i-1;
		}

		public long pi(long x)
		{
			if(x <= cachelimit){
				int ix = (int)x;
				return xcums[ix>>>6] + Long.bitCount(isp[ix>>>6]<<~ix);
//				return cump[(int)x];
			}
			if(picache.containsKey(x))return picache.get(x);

			int A = (int)pi(sqrt(sqrt(x)));
			long ret = A + phi(x, A) - P2(x, A) - P3(x, A) - 1;
			picache.put(x, ret);
			return ret;
		}

		private long phi(long x, int A)
		{
			if(A > 0 && A-1 < M){
				return cumps[A-1][FP[A-1]] * (x/FP[A-1]) + cumps[A-1][(int)(x%FP[A-1]+1)];
			}
			if(A > 0 && x <= (long)primes[A-1]*primes[A-1]){
				return pi(x) - A + 1;
			}
//			long code = x<<13|A;
//			if(phicache.containsKey(code))return phicache.get(code);

			long ret = x;
			for(int i = A-1;i >= 0;i--)ret -= phi(x/primes[i], i);

//			if(cachePhi)phicache.put(code, ret);
			return ret;
		}

		private long P2(long x, int A)
		{
			int B = (int)pi(sqrt(x));
			long ret = 0;
			for(int i = A;i < B;i++){
				ret += pi(x/primes[i]);
			}
			ret -= (long)(B-A)*(B+A-1)/2;
			return ret;
		}

		private long P3(long x, int A)
		{
			int C = (int)pi(cbrt(x));
			long ret = 0;
			for(int i = A;i < C;i++){
				long xi = x/primes[i];
				int B = (int)pi(sqrt(xi));
				for(int j = i;j < B;j++){
					ret += pi(xi/primes[j]) - j;
				}
			}
			return ret;
		}

		public static int[] sieveEratosthenes(int n) {
			if (n <= 32) {
				int[] primes = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };
				for (int i = 0; i < primes.length; i++) {
					if (n < primes[i]) {
						return Arrays.copyOf(primes, i);
					}
				}
				return primes;
			}

			int u = n + 32;
			double lu = Math.log(u);
			int[] ret = new int[(int) (u / lu + u / lu / lu * 1.5)];
			ret[0] = 2;
			int pos = 1;

			int[] isnp = new int[(n + 1) / 32 / 2 + 1];
			int sup = (n + 1) / 32 / 2 + 1;

			int[] tprimes = { 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };
			for (int tp : tprimes) {
				ret[pos++] = tp;
				int[] ptn = new int[tp];
				for (int i = (tp - 3) / 2; i < tp << 5; i += tp)
					ptn[i >> 5] |= 1 << (i & 31);
				for (int j = 0; j < sup; j += tp) {
					for (int i = 0; i < tp && i + j < sup; i++) {
						isnp[j + i] |= ptn[i];
					}
				}
			}

			// 3,5,7
			// 2x+3=n
			int[] magic = { 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13, 31, 22, 28, 18, 26, 10, 7, 12, 21, 17,
					9, 6, 16, 5, 15, 14 };
			int h = n / 2;
			for (int i = 0; i < sup; i++) {
				for (int j = ~isnp[i]; j != 0; j &= j - 1) {
					int pp = i << 5 | magic[(j & -j) * 0x076be629 >>> 27];
					int p = 2 * pp + 3;
					if (p > n)
						break;
					ret[pos++] = p;
					if ((long) p * p > n)
						continue;
					for (int q = (p * p - 3) / 2; q <= h; q += p)
						isnp[q >> 5] |= 1 << q;
				}
			}

			return Arrays.copyOf(ret, pos);
		}

		private static class LongHashCounterL {
			public long[] keys;
			public long[] allocated;
			private int scale = 1<<2;
			private int rscale = 1<<1;
			private int mask = scale-1;
			public int size = 0;

			public LongHashCounterL(){
				allocated = new long[scale];
				Arrays.fill(allocated, NG);
				keys = new long[scale];
			}

			// if value is NG, entry is removed. (e.g. 0)
			private static final int NG = 0;

			public boolean containsKey(long x)
			{
				int pos = h(x)&mask;
				while(allocated[pos] != NG){
					if(x == keys[pos])return true;
					pos = pos+1&mask;
				}
				return false;
			}

			public long get(long x)
			{
				int pos = h(x)&mask;
				while(allocated[pos] != NG){
					if(x == keys[pos])return allocated[pos];
					pos = pos+1&mask;
				}
				return NG;
			}

			public long put(long x, long v)
			{
				int pos = h(x)&mask;
				while(allocated[pos] != NG){
					if(x == keys[pos]){
						long oldval = allocated[pos];
						allocated[pos] = v;
						return oldval;
					}
					pos = pos+1&mask;
				}
				if(size == rscale){
					resizeAndPut(x, v);
				}else{
					keys[pos] = x;
					allocated[pos] = v;
				}
				size++;
				return 0;
			}

			public long inc(long x, long v)
			{
				int pos = h(x)&mask;
				while(allocated[pos] != NG){
					if(x == keys[pos]){
						allocated[pos] += v;
						return allocated[pos];
					}
					pos = pos+1&mask;
				}
				if(size == rscale){
					resizeAndPut(x, v);
				}else{
					keys[pos] = x;
					allocated[pos] = v;
				}
				size++;
				return v;
			}

			public boolean remove(long x)
			{
				int pos = h(x)&mask;
				while(allocated[pos] != NG){
					if(x == keys[pos]){
						size--;
						// take last and fill rmpos
						int last = pos;
						pos = pos+1&mask;
						while(allocated[pos] != NG){
							int lh = h(keys[pos])&mask;
							// lh <= last < pos
							if(
									lh <= last && last < pos ||
									pos < lh && lh <= last ||
									last < pos && pos < lh
									){
								keys[last] = keys[pos];
								allocated[last] = allocated[pos];
								last = pos;
							}
							pos = pos+1&mask;
						}
						keys[last] = 0;
						allocated[last] = NG;

						return true;
					}
					pos = pos+1&mask;
				}
				return false;
			}

			private void resizeAndPut(long x, long v)
			{
				int nscale = scale<<1;
				int nrscale = rscale<<1;
				int nmask = nscale-1;
				long[] nallocated = new long[nscale];
				Arrays.fill(nallocated, NG);
				long[] nkeys = new long[nscale];
				for(int i = next(0);i < scale;i = next(i+1)){
					long y = keys[i];
					int pos = h(y)&nmask;
					while(nallocated[pos] != NG)pos = pos+1&nmask;
					nkeys[pos] = y;
					nallocated[pos] = allocated[i];
				}
				{
					int pos = h(x)&nmask;
					while(nallocated[pos] != NG)pos = pos+1&nmask;
					nkeys[pos] = x;
					nallocated[pos] = v;
				}
				allocated = nallocated;
				keys = nkeys;
				scale = nscale;
				rscale = nrscale;
				mask = nmask;
			}

			public int next(int itr)
			{
				while(itr < scale && allocated[itr] == NG)itr++;
				return itr;
			}

			private int h(long x)
			{
				x ^= x>>>33;
				x *= 0xff51afd7ed558ccdL;
				x ^= x>>>33;
				x *= 0xc4ceb9fe1a85ec53L;
				x ^= x>>>33;
				return (int)x;
			}

			@Override
			public String toString()
			{
				StringBuilder sb = new StringBuilder();
				for(int i = next(0);i < scale;i = next(i+1)){
					sb.append(",");
					sb.append(keys[i] + ":" + allocated[i]);
				}
				return sb.length() == 0 ? "" : sb.substring(1);
			}
		}
	}

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


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

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

	public static int[] sieveEratosthenes(int n) {
		if (n <= 32) {
			int[] primes = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };
			for (int i = 0; i < primes.length; i++) {
				if (n < primes[i]) {
					return Arrays.copyOf(primes, i);
				}
			}
			return primes;
		}

		int u = n + 32;
		double lu = Math.log(u);
		int[] ret = new int[(int) (u / lu + u / lu / lu * 1.5)];
		ret[0] = 2;
		int pos = 1;

		int[] isnp = new int[(n + 1) / 32 / 2 + 1];
		int sup = (n + 1) / 32 / 2 + 1;

		int[] tprimes = { 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };
		for (int tp : tprimes) {
			ret[pos++] = tp;
			int[] ptn = new int[tp];
			for (int i = (tp - 3) / 2; i < tp << 5; i += tp)
				ptn[i >> 5] |= 1 << (i & 31);
			for (int j = 0; j < sup; j += tp) {
				for (int i = 0; i < tp && i + j < sup; i++) {
					isnp[j + i] |= ptn[i];
				}
			}
		}

		// 3,5,7
		// 2x+3=n
		int[] magic = { 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13, 31, 22, 28, 18, 26, 10, 7, 12, 21, 17,
				9, 6, 16, 5, 15, 14 };
		int h = n / 2;
		for (int i = 0; i < sup; i++) {
			for (int j = ~isnp[i]; j != 0; j &= j - 1) {
				int pp = i << 5 | magic[(j & -j) * 0x076be629 >>> 27];
				int p = 2 * pp + 3;
				if (p > n)
					break;
				ret[pos++] = p;
				if ((long) p * p > n)
					continue;
				for (int q = (p * p - 3) / 2; q <= h; q += p)
					isnp[q >> 5] |= 1 << q;
			}
		}

		return Arrays.copyOf(ret, pos);
	}

	int[] primes = sieveEratosthenes(400000);

	void solve()
	{
		long n = nl();
		long ans = 0;
		MeisselLehmer2 ml = new MeisselLehmer2(n/2);
		for(int i = 0;i < primes.length;i++) {
			long plus = ml.pi(n/primes[i]) - (i+1);
			if(plus <= 0)break;
			ans += plus;
		}

		for(int p : primes) {
			if((long)p*p*p <= n) {
				ans++;
			}else {
				break;
			}
		}
		out.println(ans);
	}

	public static class MeisselLehmer2 {
		int[] primes;
//		int[] cump;
		int[] xcums;
		long[] isp;

		int cachelimit;
//		Map<Long, Long> picache;
//		Map<Long, Long> phicache;
		LongHashCounterL picache;
		LongHashCounterL phicache;
		boolean cachePhi = false;

		int[][] cumps;
//		int[] FP = {2,3,5,7,11,13,17};
		int[] FP = {2,3,5,7,11,13,17,19};
		int M = FP.length;

		int B = 100;
		// 10^14 -> 200
		// 10^14/8 -> 100~200

		public MeisselLehmer2(long n)
		{
			assert n >= 4;
//			picache = new HashMap<>();
//			phicache = new HashMap<>();
			picache = new LongHashCounterL();
			phicache = new LongHashCounterL();

			int s = (int)Math.sqrt(n)*B; // not overflow!
			cachelimit = s;
			this.primes = sieveEratosthenes(s);
			xcums = new int[(s>>>6)+1];
			isp = new long[(s>>>6)+1];
			for(int p : primes)isp[p>>>6] |= 1L<<p;
			for(int i = 0;i < xcums.length-1;i++)xcums[i+1] = xcums[i] + Long.bitCount(isp[i]);

			cumps = new int[M][];
			boolean[] b = {true};
			int len = 1;
			for(int i = 0;i < M;i++){
				len *= FP[i];
				boolean[] c = new boolean[len];
				for(int j = 0;j < FP[i];j++){
					System.arraycopy(b, 0, c, j*b.length, b.length);
				}
				for(int k = 0;k < len;k+=FP[i])c[k] = false;
				cumps[i] = new int[len+1];
				for(int j = 0;j < len;j++)cumps[i][j+1] = cumps[i][j] + (c[j] ? 1 : 0);
				FP[i] = len;
				b = c;
			}
		}

		private long sqrt(long n)
		{
			long i = Math.max(0, (long)Math.sqrt(n)-2);
			while(i*i <= n)i++;
			return i-1;
		}

		private long cbrt(long n)
		{
			long i = Math.max(0, (long)Math.cbrt(n)-2);
			while(i*i*i <= n)i++;
			return i-1;
		}

		public long pi(long x)
		{
			if(x <= cachelimit){
				int ix = (int)x;
				return xcums[ix>>>6] + Long.bitCount(isp[ix>>>6]<<~ix);
//				return cump[(int)x];
			}
			if(picache.containsKey(x))return picache.get(x);

			int A = (int)pi(sqrt(sqrt(x)));
			long ret = A + phi(x, A) - P2(x, A) - P3(x, A) - 1;
			picache.put(x, ret);
			return ret;
		}

		private long phi(long x, int A)
		{
			if(A > 0 && A-1 < M){
				return cumps[A-1][FP[A-1]] * (x/FP[A-1]) + cumps[A-1][(int)(x%FP[A-1]+1)];
			}
			if(A > 0 && x <= (long)primes[A-1]*primes[A-1]){
				return pi(x) - A + 1;
			}
			long code = x<<13|A;
			if(phicache.containsKey(code))return phicache.get(code);

			long ret = x;
			for(int i = A-1;i >= 0;i--)ret -= phi(x/primes[i], i);

			if(cachePhi)phicache.put(code, ret);
			return ret;
		}

		private long P2(long x, int A)
		{
			int B = (int)pi(sqrt(x));
			long ret = 0;
			for(int i = A;i < B;i++){
				ret += pi(x/primes[i]);
			}
			ret -= (long)(B-A)*(B+A-1)/2;
			return ret;
		}

		private long P3(long x, int A)
		{
			int C = (int)pi(cbrt(x));
			long ret = 0;
			for(int i = A;i < C;i++){
				long xi = x/primes[i];
				int B = (int)pi(sqrt(xi));
				for(int j = i;j < B;j++){
					ret += pi(xi/primes[j]) - j;
				}
			}
			return ret;
		}

		public static int[] sieveEratosthenes(int n) {
			if (n <= 32) {
				int[] primes = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };
				for (int i = 0; i < primes.length; i++) {
					if (n < primes[i]) {
						return Arrays.copyOf(primes, i);
					}
				}
				return primes;
			}

			int u = n + 32;
			double lu = Math.log(u);
			int[] ret = new int[(int) (u / lu + u / lu / lu * 1.5)];
			ret[0] = 2;
			int pos = 1;

			int[] isnp = new int[(n + 1) / 32 / 2 + 1];
			int sup = (n + 1) / 32 / 2 + 1;

			int[] tprimes = { 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };
			for (int tp : tprimes) {
				ret[pos++] = tp;
				int[] ptn = new int[tp];
				for (int i = (tp - 3) / 2; i < tp << 5; i += tp)
					ptn[i >> 5] |= 1 << (i & 31);
				for (int j = 0; j < sup; j += tp) {
					for (int i = 0; i < tp && i + j < sup; i++) {
						isnp[j + i] |= ptn[i];
					}
				}
			}

			// 3,5,7
			// 2x+3=n
			int[] magic = { 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13, 31, 22, 28, 18, 26, 10, 7, 12, 21, 17,
					9, 6, 16, 5, 15, 14 };
			int h = n / 2;
			for (int i = 0; i < sup; i++) {
				for (int j = ~isnp[i]; j != 0; j &= j - 1) {
					int pp = i << 5 | magic[(j & -j) * 0x076be629 >>> 27];
					int p = 2 * pp + 3;
					if (p > n)
						break;
					ret[pos++] = p;
					if ((long) p * p > n)
						continue;
					for (int q = (p * p - 3) / 2; q <= h; q += p)
						isnp[q >> 5] |= 1 << q;
				}
			}

			return Arrays.copyOf(ret, pos);
		}

		private static class LongHashCounterL {
			public long[] keys;
			public long[] allocated;
			private int scale = 1<<2;
			private int rscale = 1<<1;
			private int mask = scale-1;
			public int size = 0;

			public LongHashCounterL(){
				allocated = new long[scale];
				Arrays.fill(allocated, NG);
				keys = new long[scale];
			}

			// if value is NG, entry is removed. (e.g. 0)
			private static final int NG = 0;

			public boolean containsKey(long x)
			{
				int pos = h(x)&mask;
				while(allocated[pos] != NG){
					if(x == keys[pos])return true;
					pos = pos+1&mask;
				}
				return false;
			}

			public long get(long x)
			{
				int pos = h(x)&mask;
				while(allocated[pos] != NG){
					if(x == keys[pos])return allocated[pos];
					pos = pos+1&mask;
				}
				return NG;
			}

			public long put(long x, long v)
			{
				int pos = h(x)&mask;
				while(allocated[pos] != NG){
					if(x == keys[pos]){
						long oldval = allocated[pos];
						allocated[pos] = v;
						return oldval;
					}
					pos = pos+1&mask;
				}
				if(size == rscale){
					resizeAndPut(x, v);
				}else{
					keys[pos] = x;
					allocated[pos] = v;
				}
				size++;
				return 0;
			}

			public long inc(long x, long v)
			{
				int pos = h(x)&mask;
				while(allocated[pos] != NG){
					if(x == keys[pos]){
						allocated[pos] += v;
						return allocated[pos];
					}
					pos = pos+1&mask;
				}
				if(size == rscale){
					resizeAndPut(x, v);
				}else{
					keys[pos] = x;
					allocated[pos] = v;
				}
				size++;
				return v;
			}

			public boolean remove(long x)
			{
				int pos = h(x)&mask;
				while(allocated[pos] != NG){
					if(x == keys[pos]){
						size--;
						// take last and fill rmpos
						int last = pos;
						pos = pos+1&mask;
						while(allocated[pos] != NG){
							int lh = h(keys[pos])&mask;
							// lh <= last < pos
							if(
									lh <= last && last < pos ||
									pos < lh && lh <= last ||
									last < pos && pos < lh
									){
								keys[last] = keys[pos];
								allocated[last] = allocated[pos];
								last = pos;
							}
							pos = pos+1&mask;
						}
						keys[last] = 0;
						allocated[last] = NG;

						return true;
					}
					pos = pos+1&mask;
				}
				return false;
			}

			private void resizeAndPut(long x, long v)
			{
				int nscale = scale<<1;
				int nrscale = rscale<<1;
				int nmask = nscale-1;
				long[] nallocated = new long[nscale];
				Arrays.fill(nallocated, NG);
				long[] nkeys = new long[nscale];
				for(int i = next(0);i < scale;i = next(i+1)){
					long y = keys[i];
					int pos = h(y)&nmask;
					while(nallocated[pos] != NG)pos = pos+1&nmask;
					nkeys[pos] = y;
					nallocated[pos] = allocated[i];
				}
				{
					int pos = h(x)&nmask;
					while(nallocated[pos] != NG)pos = pos+1&nmask;
					nkeys[pos] = x;
					nallocated[pos] = v;
				}
				allocated = nallocated;
				keys = nkeys;
				scale = nscale;
				rscale = nrscale;
				mask = nmask;
			}

			public int next(int itr)
			{
				while(itr < scale && allocated[itr] == NG)itr++;
				return itr;
			}

			private int h(long x)
			{
				x ^= x>>>33;
				x *= 0xff51afd7ed558ccdL;
				x ^= x>>>33;
				x *= 0xc4ceb9fe1a85ec53L;
				x ^= x>>>33;
				return (int)x;
			}

			@Override
			public String toString()
			{
				StringBuilder sb = new StringBuilder();
				for(int i = next(0);i < scale;i = next(i+1)){
					sb.append(",");
					sb.append(keys[i] + ":" + allocated[i]);
				}
				return sb.length() == 0 ? "" : sb.substring(1);
			}
		}
	}

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