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

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);
		Task solver = new Task();
		solver.solve(1, in, out);
		out.close();
	}
}

class Task {

	Map<Long, Integer> map=new EHashMap<>();
	Map<Long, List<Long>> divides=new TreeMap<>();
	Map<Long, Long>[] dp;
	int idx=0;

	public void solve(int testNumber, InputReader in, OutputWriter out) {
		long A=in.readLong();
		for (long i=1; i*i<=A; i++) if (A%i==0) {
			process(i);
			if (i*i!=A) process(A/i);
		}
		dp=new Map[divides.size()+1];
		for (int i=0; i<dp.length; i++) {
			dp[i]=new EHashMap<Long, Long>();
			for (long j: map.keySet()) dp[i].put(j, 0L);
		}
		dp[0].put(1L, 1L);
		int idx=0;
		for (long i: divides.keySet()) {
			idx++;
			if (idx>1) dp[idx-2].clear();
			for (long j: map.keySet()) {
				dp[idx].put(j, dp[idx-1].get(j));
				for (long x: divides.get(i))
					if (j%x==0) {
//						System.out.println(idx);
//						System.out.println(dp[idx]);
//						System.out.println(dp[idx-1]);
						dp[idx].put(j, dp[idx].get(j)+dp[idx-1].get(j/x));
					}
			}
		}
		out.printLine(dp[idx].get(A));
	}

	long prime(long n) {
		if (n<=1) return -1;
		for (long i=2; i*i<=n; i++) if (n%i==0) {
			while (n%i==0) n/=i;
			return n==1?i:-1;
		}
		return n;
	}

	void process(long x) {
		map.put(x, idx++);
		long p=prime(x-1);
		if (p>0) {
			if (!divides.containsKey(p)) divides.put(p, new ArrayList<Long>());
			divides.get(p).add(x);
		}
	}
}

class InputReader {
	private boolean finished = false;

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

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

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

	public int peek() {
		if (numChars == -1)
			return -1;
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				return -1;
			}
			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();
		}
		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 String readString() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			if (Character.isValidCodePoint(c))
				res.appendCodePoint(c);
			c = read();
		} while (!isSpaceChar(c));
		return res.toString();
	}

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

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

	private String readLine0() {
		StringBuilder buf = new StringBuilder();
		int c = read();
		while (c != '\n' && c != -1) {
			if (c != '\r')
				buf.appendCodePoint(c);
			c = read();
		}
		return buf.toString();
	}

	public String readLine() {
		String s = readLine0();
		while (s.trim().length() == 0)
			s = readLine0();
		return s;
	}

	public String readLine(boolean ignoreEmptyLines) {
		if (ignoreEmptyLines)
			return readLine();
		else
			return readLine0();
	}

	public BigInteger readBigInteger() {
		try {
			return new BigInteger(readString());
		} catch (NumberFormatException e) {
			throw new InputMismatchException();
		}
	}

	public char readCharacter() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		return (char) c;
	}

	public double readDouble() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		double res = 0;
		while (!isSpaceChar(c) && c != '.') {
			if (c == 'e' || c == 'E')
				return res * Math.pow(10, readInt());
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		}
		if (c == '.') {
			c = read();
			double m = 1;
			while (!isSpaceChar(c)) {
				if (c == 'e' || c == 'E')
					return res * Math.pow(10, readInt());
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				m /= 10;
				res += (c - '0') * m;
				c = read();
			}
		}
		return res * sgn;
	}

	public boolean isExhausted() {
		int value;
		while (isSpaceChar(value = peek()) && value != -1)
			read();
		return value == -1;
	}

	public String next() {
		return readString();
	}

	public SpaceCharFilter getFilter() {
		return filter;
	}

	public void setFilter(SpaceCharFilter filter) {
		this.filter = filter;
	}

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

class OutputWriter {
	private final PrintWriter writer;

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

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

	public void print(char[] array) {
		writer.print(array);
	}

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

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

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

	public void print(Collection<Integer> collection) {
		boolean first = true;
		for (int i : collection) {
			if (first)
				first = false;
			else
				writer.print(' ');
			writer.print(i);
		}
	}

	public void printLine(int[] array) {
		print(array);
		writer.println();
	}

	public void printLine(long[] array) {
		print(array);
		writer.println();
	}

	public void printLine(Collection<Integer> collection) {
		print(collection);
		writer.println();
	}

	public void printLine() {
		writer.println();
	}

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

	public void print(char i) {
		writer.print(i);
	}

	public void printLine(char i) {
		writer.println(i);
	}

	public void printLine(char[] array) {
		writer.println(array);
	}

	public void printFormat(String format, Object... objects) {
		writer.printf(format, objects);
	}

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

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

	public void print(long i) {
		writer.print(i);
	}

	public void printLine(long i) {
		writer.println(i);
	}

	public void print(int i) {
		writer.print(i);
	}

	public void printLine(int i) {
		writer.println(i);
	}
}

class Polygon {
	public final Point[] vertices;
	private Segment[] sides;

	public Polygon(Point... vertices) {
		this.vertices = vertices.clone();
	}

	public double square() {
		double sum = 0;
		for (int i = 1; i < vertices.length; i++)
			sum += (vertices[i].x - vertices[i - 1].x)
					* (vertices[i].y + vertices[i - 1].y);
		sum += (vertices[0].x - vertices[vertices.length - 1].x)
				* (vertices[0].y + vertices[vertices.length - 1].y);
		return Math.abs(sum) / 2;
	}

	public Point center() {
		double sx = 0;
		double sy = 0;
		for (Point point : vertices) {
			sx += point.x;
			sy += point.y;
		}
		return new Point(sx / vertices.length, sy / vertices.length);
	}

	public static boolean over(Point a, Point b, Point c) {
		return a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y) < -GeometryUtils.epsilon;
	}

	private static boolean under(Point a, Point b, Point c) {
		return a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y) > GeometryUtils.epsilon;
	}

	public static Polygon convexHull(Point[] points) {
		if (points.length == 1)
			return new Polygon(points);
		Arrays.sort(points, new Comparator<Point>() {
			public int compare(Point o1, Point o2) {
				int value = Double.compare(o1.x, o2.x);
				if (value != 0)
					return value;
				return Double.compare(o1.y, o2.y);
			}
		});
		Point left = points[0];
		Point right = points[points.length - 1];
		List<Point> up = new ArrayList<Point>();
		List<Point> down = new ArrayList<Point>();
		for (Point point : points) {
			if (point == left || point == right || !under(left, point, right)) {
				while (up.size() >= 2
						&& under(up.get(up.size() - 2), up.get(up.size() - 1),
								point))
					up.remove(up.size() - 1);
				up.add(point);
			}
			if (point == left || point == right || !over(left, point, right)) {
				while (down.size() >= 2
						&& over(down.get(down.size() - 2),
								down.get(down.size() - 1), point))
					down.remove(down.size() - 1);
				down.add(point);
			}
		}
		Point[] result = new Point[up.size() + down.size() - 2];
		int index = 0;
		for (Point point : up)
			result[index++] = point;
		for (int i = down.size() - 2; i > 0; i--)
			result[index++] = down.get(i);
		return new Polygon(result);
	}

	public boolean contains(Point point) {
		return contains(point, false);
	}

	public boolean contains(Point point, boolean strict) {
		for (Segment segment : sides()) {
			if (segment.contains(point, true))
				return !strict;
		}
		double totalAngle = GeometryUtils.canonicalAngle(Math.atan2(
				vertices[0].y - point.y, vertices[0].x - point.x)
				- Math.atan2(vertices[vertices.length - 1].y - point.y,
						vertices[vertices.length - 1].x - point.x));
		for (int i = 1; i < vertices.length; i++) {
			totalAngle += GeometryUtils.canonicalAngle(Math.atan2(vertices[i].y
					- point.y, vertices[i].x - point.x)
					- Math.atan2(vertices[i - 1].y - point.y, vertices[i - 1].x
							- point.x));
		}
		return Math.abs(totalAngle) > Math.PI;
	}

	public Segment[] sides() {
		if (sides == null) {
			sides = new Segment[vertices.length];
			for (int i = 0; i < vertices.length - 1; i++)
				sides[i] = new Segment(vertices[i], vertices[i + 1]);
			sides[sides.length - 1] = new Segment(
					vertices[vertices.length - 1], vertices[0]);
		}
		return sides;
	}

	public static double triangleSquare(Point a, Point b, Point c) {
		return Math.abs((a.x - b.x) * (a.y + b.y) + (b.x - c.x) * (b.y + c.y)
				+ (c.x - a.x) * (c.y + a.y)) / 2;
	}

	public double perimeter() {
		double result = vertices[0].distance(vertices[vertices.length - 1]);
		for (int i = 1; i < vertices.length; i++)
			result += vertices[i].distance(vertices[i - 1]);
		return result;
	}
}

class Point {
	public static final Point ORIGIN = new Point(0, 0);
	public final double x;
	public final double y;

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

	public Point(double x, double y) {
		this.x = x;
		this.y = y;
	}

	public Line line(Point other) {
		if (equals(other))
			return null;
		double a = other.y - y;
		double b = x - other.x;
		double c = -a * x - b * y;
		return new Line(a, b, c);
	}

	@Override
	public boolean equals(Object o) {
		if (this == o)
			return true;
		if (o == null || getClass() != o.getClass())
			return false;

		Point point = (Point) o;

		return Math.abs(x - point.x) <= GeometryUtils.epsilon
				&& Math.abs(y - point.y) <= GeometryUtils.epsilon;
	}

	@Override
	public int hashCode() {
		int result;
		long temp;
		temp = x != +0.0d ? Double.doubleToLongBits(x) : 0L;
		result = (int) (temp ^ (temp >>> 32));
		temp = y != +0.0d ? Double.doubleToLongBits(y) : 0L;
		result = 31 * result + (int) (temp ^ (temp >>> 32));
		return result;
	}

	public double distance(Point other) {
		return GeometryUtils.fastHypot(x - other.x, y - other.y);
	}

	public double distance(Line line) {
		return Math.abs(line.a * x + line.b * y + line.c);
	}

	public double value() {
		return GeometryUtils.fastHypot(x, y);
	}

	public double angle() {
		return Math.atan2(y, x);
	}

	public static Point readPoint(InputReader in) {
		double x = in.readDouble();
		double y = in.readDouble();
		return new Point(x, y);
	}

	public Point rotate(double angle) {
		double nx = x * Math.cos(angle) - y * Math.sin(angle);
		double ny = y * Math.cos(angle) + x * Math.sin(angle);
		return new Point(nx, ny);
	}
}

class Segment {
	public final Point a;
	public final Point b;
	private double distance = Double.NaN;
	private Line line = null;

	public Segment(Point a, Point b) {
		this.a = a;
		this.b = b;
	}

	public double length() {
		if (Double.isNaN(distance))
			distance = a.distance(b);
		return distance;
	}

	public double distance(Point point) {
		double length = length();
		double left = point.distance(a);
		if (length < GeometryUtils.epsilon)
			return left;
		double right = point.distance(b);
		if (left * left > right * right + length * length)
			return right;
		if (right * right > left * left + length * length)
			return left;
		return point.distance(line());
	}

	public Point intersect(Segment other, boolean includeEnds) {
		Line line = line();
		Line otherLine = other.a.line(other.b);
		if (line.parallel(otherLine))
			return null;
		Point intersection = line.intersect(otherLine);
		if (contains(intersection, includeEnds)
				&& other.contains(intersection, includeEnds))
			return intersection;
		else
			return null;
	}

	public boolean contains(Point point, boolean includeEnds) {
		if (a.equals(point) || b.equals(point))
			return includeEnds;
		if (a.equals(b))
			return false;
		Line line = line();
		if (!line.contains(point))
			return false;
		Line perpendicular = line.perpendicular(a);
		double aValue = perpendicular.value(a);
		double bValue = perpendicular.value(b);
		double pointValue = perpendicular.value(point);
		return aValue < pointValue && pointValue < bValue
				|| bValue < pointValue && pointValue < aValue;
	}

	public Line line() {
		if (line == null)
			line = a.line(b);
		return line;
	}

	public Point middle() {
		return new Point((a.x + b.x) / 2, (a.y + b.y) / 2);
	}

	public Point[] intersect(Circle circle) {
		Point[] result = line().intersect(circle);
		if (result.length == 0)
			return result;
		if (result.length == 1) {
			if (contains(result[0], true))
				return result;
			return new Point[0];
		}
		if (contains(result[0], true)) {
			if (contains(result[1], true))
				return result;
			return new Point[] { result[0] };
		}
		if (contains(result[1], true))
			return new Point[] { result[1] };
		return new Point[0];
	}

	public Point intersect(Line line) {
		Line selfLine = line();
		Point intersect = selfLine.intersect(line);
		if (intersect == null)
			return null;
		if (contains(intersect, true))
			return intersect;
		return null;
	}

	public double distance(Segment other) {
		Line line = line();
		Line otherLine = other.line();
		Point p = line == null || otherLine == null ? null : line
				.intersect(otherLine);
		if (p != null && contains(p, true) && other.contains(p, true))
			return 0;
		return Math.min(Math.min(other.distance(a), other.distance(b)),
				Math.min(distance(other.a), distance(other.b)));
	}
}

class GeometryUtils {
	public static double epsilon = 1e-8;

	public static double fastHypot(double... x) {
		if (x.length == 0)
			return 0;
		else if (x.length == 1)
			return Math.abs(x[0]);
		else {
			double sumSquares = 0;
			for (double value : x)
				sumSquares += value * value;
			return Math.sqrt(sumSquares);
		}
	}

	public static double fastHypot(double x, double y) {
		return Math.sqrt(x * x + y * y);
	}

	public static double fastHypot(double[] x, double[] y) {
		if (x.length == 0)
			return 0;
		else if (x.length == 1)
			return Math.abs(x[0] - y[0]);
		else {
			double sumSquares = 0;
			for (int i = 0; i < x.length; i++) {
				double diff = x[i] - y[i];
				sumSquares += diff * diff;
			}
			return Math.sqrt(sumSquares);
		}
	}

	public static double fastHypot(int[] x, int[] y) {
		if (x.length == 0)
			return 0;
		else if (x.length == 1)
			return Math.abs(x[0] - y[0]);
		else {
			double sumSquares = 0;
			for (int i = 0; i < x.length; i++) {
				double diff = x[i] - y[i];
				sumSquares += diff * diff;
			}
			return Math.sqrt(sumSquares);
		}
	}

	public static double missileTrajectoryLength(double v, double angle,
			double g) {
		return (v * v * Math.sin(2 * angle)) / g;
	}

	public static double sphereVolume(double radius) {
		return 4 * Math.PI * radius * radius * radius / 3;
	}

	public static double triangleSquare(double first, double second,
			double third) {
		double p = (first + second + third) / 2;
		return Math.sqrt(p * (p - first) * (p - second) * (p - third));
	}

	public static double canonicalAngle(double angle) {
		while (angle > Math.PI)
			angle -= 2 * Math.PI;
		while (angle < -Math.PI)
			angle += 2 * Math.PI;
		return angle;
	}

	public static double positiveAngle(double angle) {
		while (angle > 2 * Math.PI - GeometryUtils.epsilon)
			angle -= 2 * Math.PI;
		while (angle < -GeometryUtils.epsilon)
			angle += 2 * Math.PI;
		return angle;
	}
}

class Line {
	public final double a;
	public final double b;
	public final double c;

	public Line(Point p, double angle) {
		a = Math.sin(angle);
		b = -Math.cos(angle);
		c = -p.x * a - p.y * b;
	}

	public Line(double a, double b, double c) {
		double h = GeometryUtils.fastHypot(a, b);
		this.a = a / h;
		this.b = b / h;
		this.c = c / h;
	}

	public Point intersect(Line other) {
		if (parallel(other))
			return null;
		double determinant = b * other.a - a * other.b;
		double x = (c * other.b - b * other.c) / determinant;
		double y = (a * other.c - c * other.a) / determinant;
		return new Point(x, y);
	}

	public boolean parallel(Line other) {
		return Math.abs(a * other.b - b * other.a) < GeometryUtils.epsilon;
	}

	public boolean contains(Point point) {
		return Math.abs(value(point)) < GeometryUtils.epsilon;
	}

	public Line perpendicular(Point point) {
		return new Line(-b, a, b * point.x - a * point.y);
	}

	public double value(Point point) {
		return a * point.x + b * point.y + c;
	}

	public Point[] intersect(Circle circle) {
		double distance = distance(circle.center);
		if (distance > circle.radius + GeometryUtils.epsilon)
			return new Point[0];
		Point intersection = intersect(perpendicular(circle.center));
		if (Math.abs(distance - circle.radius) < GeometryUtils.epsilon)
			return new Point[] { intersection };
		double shift = Math.sqrt(circle.radius * circle.radius - distance
				* distance);
		return new Point[] {
				new Point(intersection.x + shift * b, intersection.y - shift
						* a),
				new Point(intersection.x - shift * b, intersection.y + shift
						* a) };
	}

	public double distance(Point center) {
		return Math.abs(value(center));
	}

	@Override
	public boolean equals(Object o) {
		if (this == o)
			return true;
		if (o == null || getClass() != o.getClass())
			return false;

		Line line = (Line) o;

		if (!parallel(line))
			return false;
		if (Math.abs(a * line.c - c * line.a) > GeometryUtils.epsilon
				|| Math.abs(b * line.c - c * line.b) > GeometryUtils.epsilon)
			return false;

		return true;
	}
}

class Circle {
	public final Point center;
	public final double radius;

	public Circle(Point center, double radius) {
		this.center = center;
		this.radius = radius;
	}

	public boolean contains(Point point) {
		return center.distance(point) < radius + GeometryUtils.epsilon;
	}

	public boolean strictContains(Point point) {
		return center.distance(point) < radius - GeometryUtils.epsilon;
	}

	public Point[] findTouchingPoints(Point point) {
		double distance = center.distance(point);
		if (distance < radius - GeometryUtils.epsilon)
			return new Point[0];
		if (distance < radius + GeometryUtils.epsilon)
			return new Point[] { point };
		Circle power = new Circle(point, Math.sqrt((distance - radius)
				* (distance + radius)));
		return intersect(power);
	}

	public Point[] intersect(Circle other) {
		double distance = center.distance(other.center);
		if (distance > radius + other.radius + GeometryUtils.epsilon
				|| Math.abs(radius - other.radius) > distance
						+ GeometryUtils.epsilon)
			return new Point[0];
		double p = (radius + other.radius + distance) / 2;
		double height = 2
				* Math.sqrt(p * (p - radius) * (p - other.radius)
						* (p - distance)) / distance;
		double l1 = Math.sqrt(radius * radius - height * height);
		double l2 = Math.sqrt(other.radius * other.radius - height * height);
		if (radius * radius + distance * distance < other.radius * other.radius)
			l1 = -l1;
		if (radius * radius > distance * distance + other.radius * other.radius)
			l2 = -l2;
		Point middle = new Point((center.x * l2 + other.center.x * l1)
				/ (l1 + l2), (center.y * l2 + other.center.y * l1) / (l1 + l2));
		Line line = center.line(other.center).perpendicular(middle);
		return line.intersect(this);
	}
}

class Pair<U, V> implements Comparable<Pair<U, V>> {
	public final U first;
	public final V second;

	public static <U, V> Pair<U, V> makePair(U first, V second) {
		return new Pair<U, V>(first, second);
	}

	private Pair(U first, V second) {
		this.first = first;
		this.second = second;
	}

	public boolean equals(Object o) {
		if (this == o)
			return true;
		if (o == null || getClass() != o.getClass())
			return false;

		Pair pair = (Pair) o;

		return !(first != null ? !first.equals(pair.first) : pair.first != null)
				&& !(second != null ? !second.equals(pair.second)
						: pair.second != null);

	}

	public int hashCode() {
		int result = first != null ? first.hashCode() : 0;
		result = 31 * result + (second != null ? second.hashCode() : 0);
		return result;
	}

	public String toString() {
		return "(" + first + "," + second + ")";
	}

	public int compareTo(Pair<U, V> o) {
		int value = ((Comparable<U>) first).compareTo(o.first);
		if (value != 0)
			return value;
		return ((Comparable<V>) second).compareTo(o.second);
	}
}

class IOUtils {

	public static void readIntArrays(InputReader in, int[]... arrays) {
		for (int i = 0; i < arrays[0].length; i++) {
			for (int j = 0; j < arrays.length; j++)
				arrays[j][i] = in.readInt();
		}
	}

}

class TreapSet<K> implements NavigableSet<K> {
	protected static final Random rnd = new Random(239);

	protected final Node nullNode;
	protected final Comparator<? super K> comparator;
	protected Node root;
	private final K from;
	private final K to;
	private final boolean fromInclusive;
	private final boolean toInclusive;

	public TreapSet() {
		this((Comparator<? super K>) null);
	}

	public TreapSet(Comparator<? super K> comparator) {
		this(null, null, false, false, comparator, null, null);
	}

	protected TreapSet(K from, K to, boolean fromInclusive,
			boolean toInclusive, Comparator<? super K> comparator, Node root,
			Node nullNode) {
		this.comparator = comparator;
		this.from = from;
		this.to = to;
		this.fromInclusive = fromInclusive;
		this.toInclusive = toInclusive;
		if (nullNode == null)
			nullNode = new NullNode();
		if (root == null)
			root = nullNode;
		this.root = root;
		this.nullNode = nullNode;
	}

	public boolean addAll(Iterable<? extends K> collection) {
		boolean result = false;
		for (K element : collection)
			result |= add(element);
		return result;
	}

	public K lower(K k) {
		Node target = root.lower(k);
		if (target == nullNode)
			return null;
		if (belongs(target.key))
			return target.key;
		return null;
	}

	private boolean belongs(K key) {
		int valueFrom = compare(from, key);
		int valueTo = compare(key, to);
		return (valueFrom < 0 || valueFrom == 0 && fromInclusive)
				&& (valueTo < 0 || valueTo == 0 && toInclusive);
	}

	public K floor(K k) {
		Node target = root.floor(k);
		if (target == nullNode)
			return null;
		if (belongs(target.key))
			return target.key;
		return null;
	}

	public K ceiling(K k) {
		Node target = root.ceil(k);
		if (target == nullNode)
			return null;
		if (belongs(target.key))
			return target.key;
		return null;
	}

	public K higher(K k) {
		Node target = root.higher(k);
		if (target == nullNode)
			return null;
		if (belongs(target.key))
			return target.key;
		return null;
	}

	public K pollFirst() {
		K first = first();
		if (first == null)
			throw new NoSuchElementException();
		root.erase(first);
		return first;
	}

	public K pollLast() {
		K last = last();
		if (last == null)
			throw new NoSuchElementException();
		root.erase(last);
		return last;
	}

	public int size() {
		if (from == null && to == null)
			return root.size;
		if (from == null) {
			Node to = toInclusive ? root.floor(this.to) : root.lower(this.to);
			if (to == nullNode)
				return 0;
			return root.indexOf(to) + 1;
		}
		if (to == null) {
			Node from = fromInclusive ? root.ceil(this.from) : root
					.higher(this.from);
			if (from == nullNode)
				return 0;
			return root.size - root.indexOf(from);
		}
		Node from = fromInclusive ? root.ceil(this.from) : root
				.higher(this.from);
		if (from == nullNode || !belongs(from.key))
			return 0;
		Node to = toInclusive ? root.floor(this.to) : root.lower(this.to);
		return root.indexOf(to) - root.indexOf(from) + 1;
	}

	public boolean isEmpty() {
		return size() == 0;
	}

	public boolean contains(Object o) {
		return belongs((K) o) && root.search((K) o) != nullNode;
	}

	public Iterator<K> iterator() {
		return new Iterator<K>() {
			private K current = first();

			public boolean hasNext() {
				return current != null;
			}

			public K next() {
				K result = current;
				current = higher(current);
				return result;
			}

			public void remove() {
				TreapSet.this.remove(current);
			}
		};
	}

	public Object[] toArray() {
		Object[] array = new Object[size()];
		int index = 0;
		for (K key : this)
			array[index++] = key;
		return array;
	}

	public <T> T[] toArray(T[] a) {
		if (a.length < size())
			throw new IllegalArgumentException();
		int index = 0;
		for (K key : this)
			a[index++] = (T) key;
		return a;
	}

	public boolean add(K k) {
		if (k == null)
			throw new NullPointerException();
		if (contains(k))
			return false;
		root = root.insert(createNode(k));
		return true;
	}

	protected Node createNode(K k) {
		return new Node(k, rnd.nextLong());
	}

	public boolean remove(Object o) {
		if (!contains(o))
			return false;
		// noinspection unchecked
		root = root.erase((K) o);
		return true;
	}

	public boolean containsAll(Collection<?> c) {
		for (Object o : c) {
			if (!contains(o))
				return false;
		}
		return true;
	}

	public boolean addAll(Collection<? extends K> c) {
		return addAll((Iterable<? extends K>) c);
	}

	public boolean retainAll(Collection<?> c) {
		List<K> toRemove = new ArrayList<K>();
		for (K key : this) {
			if (!c.contains(key))
				toRemove.add(key);
		}
		return removeAll(toRemove);
	}

	public boolean removeAll(Collection<?> c) {
		boolean result = false;
		for (Object o : c)
			result |= remove(o);
		return result;
	}

	public void clear() {
		retainAll(Collections.<Object> emptySet());
	}

	public NavigableSet<K> descendingSet() {
		throw new UnsupportedOperationException();
	}

	public Iterator<K> descendingIterator() {
		return new Iterator<K>() {
			private K current = last();

			public boolean hasNext() {
				return current != null;
			}

			public K next() {
				K result = current;
				current = lower(current);
				return result;
			}

			public void remove() {
				TreapSet.this.remove(current);
			}
		};
	}

	public NavigableSet<K> subSet(K fromElement, boolean fromInclusive,
			K toElement, boolean toInclusive) {
		return new TreapSet<K>(fromElement, toElement, fromInclusive,
				toInclusive, comparator, root, nullNode);
	}

	public NavigableSet<K> headSet(K toElement, boolean inclusive) {
		return subSet(null, false, toElement, inclusive);
	}

	public NavigableSet<K> tailSet(K fromElement, boolean inclusive) {
		return subSet(fromElement, inclusive, null, false);
	}

	public Comparator<? super K> comparator() {
		return comparator;
	}

	public SortedSet<K> subSet(K fromElement, K toElement) {
		return subSet(fromElement, true, toElement, false);
	}

	public SortedSet<K> headSet(K toElement) {
		return subSet(null, false, toElement, false);
	}

	public SortedSet<K> tailSet(K fromElement) {
		return tailSet(fromElement, true);
	}

	public K first() {
		if (isEmpty())
			return null;
		if (from == null)
			return root.first().key;
		if (fromInclusive)
			return ceiling(from);
		return higher(from);
	}

	public K last() {
		if (isEmpty())
			return null;
		if (to == null)
			return root.last().key;
		if (toInclusive)
			return floor(to);
		return lower(to);
	}

	protected int compare(K first, K second) {
		if (first == null || second == null)
			return -1;
		if (comparator != null)
			return comparator.compare(first, second);
		// noinspection unchecked
		return ((Comparable<? super K>) first).compareTo(second);
	}

	protected class Node {
		protected final K key;
		protected final long priority;
		protected Node left;
		protected Node right;
		protected int size;

		protected Node(K key, long priority) {
			this.key = key;
			this.priority = priority;
			left = nullNode;
			right = nullNode;
			size = 1;
		}

		protected Object[] split(K key) {
			if (compare(key, this.key) < 0) {
				Object[] result = left.split(key);
				left = (Node) result[1];
				result[1] = this;
				updateSize();
				return result;
			}
			Object[] result = right.split(key);
			right = (Node) result[0];
			result[0] = this;
			updateSize();
			return result;
		}

		protected void updateSize() {
			size = left.size + right.size + 1;
		}

		protected Node insert(Node node) {
			if (node.priority > priority) {
				Object[] result = split(node.key);
				node.left = (Node) result[0];
				node.right = (Node) result[1];
				node.updateSize();
				return node;
			}
			if (compare(node.key, this.key) < 0) {
				left = left.insert(node);
				updateSize();
				return this;
			}
			right = right.insert(node);
			updateSize();
			return this;
		}

		protected Node merge(Node left, Node right) {
			if (left == nullNode)
				return right;
			if (right == nullNode)
				return left;
			if (left.priority > right.priority) {
				left.right = left.right.merge(left.right, right);
				left.updateSize();
				return left;
			}
			right.left = right.left.merge(left, right.left);
			right.updateSize();
			return right;
		}

		protected Node erase(K key) {
			int value = compare(key, this.key);
			if (value == 0)
				return merge(left, right);
			if (value < 0) {
				left = left.erase(key);
				updateSize();
				return this;
			}
			right = right.erase(key);
			updateSize();
			return this;
		}

		protected Node lower(K key) {
			if (compare(key, this.key) <= 0)
				return left.lower(key);
			Node result = right.lower(key);
			if (result == nullNode)
				return this;
			return result;
		}

		protected Node floor(K key) {
			if (compare(key, this.key) < 0)
				return left.floor(key);
			Node result = right.floor(key);
			if (result == nullNode)
				return this;
			return result;
		}

		protected Node higher(K key) {
			if (compare(key, this.key) >= 0)
				return right.higher(key);
			Node result = left.higher(key);
			if (result == nullNode)
				return this;
			return result;
		}

		protected Node ceil(K key) {
			if (compare(key, this.key) > 0)
				return right.ceil(key);
			Node result = left.ceil(key);
			if (result == nullNode)
				return this;
			return result;
		}

		protected Node first() {
			if (left == nullNode)
				return this;
			return left.first();
		}

		protected Node last() {
			if (right == nullNode)
				return this;
			return right.last();
		}

		protected Node search(K key) {
			int value = compare(key, this.key);
			if (value == 0)
				return this;
			if (value < 0)
				return left.search(key);
			return right.search(key);
		}

		public int indexOf(Node node) {
			if (this == node)
				return left.size;
			if (compare(node.key, this.key) > 0)
				return left.size + 1 + right.indexOf(node);
			return left.indexOf(node);
		}

	}

	private class NullNode extends Node {
		private Object[] splitResult = new Object[2];

		private NullNode() {
			super(null, Long.MIN_VALUE);
			left = this;
			right = this;
			size = 0;
		}

		protected Object[] split(K key) {
			splitResult[0] = splitResult[1] = this;
			return splitResult;
		}

		protected Node insert(Node node) {
			return node;
		}

		protected Node erase(K key) {
			return this;
		}

		protected Node lower(K key) {
			return this;
		}

		protected Node floor(K key) {
			return this;
		}

		protected Node higher(K key) {
			return this;
		}

		protected Node ceil(K key) {
			return this;
		}

		protected Node first() {
			throw new NoSuchElementException();
		}

		protected Node last() {
			throw new NoSuchElementException();
		}

		protected void updateSize() {
		}

		protected Node search(K key) {
			return this;
		}

	}
}

class EHashMap<E, V> extends AbstractMap<E, V> {
	private static final int[] shifts = new int[10];

	private int size;
	private HashEntry<E, V>[] data;
	private int capacity;
	private Set<Entry<E, V>> entrySet;

	static {
		Random random = new Random(System.currentTimeMillis());
		for (int i = 0; i < 10; i++)
			shifts[i] = 1 + 3 * i + random.nextInt(3);
	}

	public EHashMap() {
		this(4);
	}

	private void setCapacity(int size) {
		capacity = Integer.highestOneBit(4 * size);
		// noinspection unchecked
		data = new HashEntry[capacity];
	}

	public EHashMap(int maxSize) {
		setCapacity(maxSize);
		entrySet = new AbstractSet<Entry<E, V>>() {
			public Iterator<Entry<E, V>> iterator() {
				return new Iterator<Entry<E, V>>() {
					private HashEntry<E, V> last = null;
					private HashEntry<E, V> current = null;
					private HashEntry<E, V> base = null;
					private int lastIndex = -1;
					private int index = -1;

					public boolean hasNext() {
						if (current == null) {
							for (index++; index < capacity; index++) {
								if (data[index] != null) {
									base = current = data[index];
									break;
								}
							}
						}
						return current != null;
					}

					public Entry<E, V> next() {
						if (!hasNext())
							throw new NoSuchElementException();
						last = current;
						lastIndex = index;
						current = current.next;
						if (base.next != last)
							base = base.next;
						return last;
					}

					public void remove() {
						if (last == null)
							throw new IllegalStateException();
						size--;
						if (base == last)
							data[lastIndex] = last.next;
						else
							base.next = last.next;
					}
				};
			}

			public int size() {
				return size;
			}
		};
	}

	public Set<Entry<E, V>> entrySet() {
		return entrySet;
	}

	public void clear() {
		Arrays.fill(data, null);
		size = 0;
	}

	private int index(Object o) {
		return getHash(o.hashCode()) & (capacity - 1);
	}

	private int getHash(int h) {
		int result = h;
		for (int i : shifts)
			result ^= h >>> i;
		return result;
	}

	public V remove(Object o) {
		if (o == null)
			return null;
		int index = index(o);
		HashEntry<E, V> current = data[index];
		HashEntry<E, V> last = null;
		while (current != null) {
			if (current.key.equals(o)) {
				if (last == null)
					data[index] = current.next;
				else
					last.next = current.next;
				size--;
				return current.value;
			}
			last = current;
			current = current.next;
		}
		return null;
	}

	public V put(E e, V value) {
		if (e == null)
			return null;
		int index = index(e);
		HashEntry<E, V> current = data[index];
		if (current != null) {
			while (true) {
				if (current.key.equals(e)) {
					V oldValue = current.value;
					current.value = value;
					return oldValue;
				}
				if (current.next == null)
					break;
				current = current.next;
			}
		}
		if (current == null)
			data[index] = new HashEntry<E, V>(e, value);
		else
			current.next = new HashEntry<E, V>(e, value);
		size++;
		if (2 * size > capacity) {
			HashEntry<E, V>[] oldData = data;
			setCapacity(size);
			for (HashEntry<E, V> entry : oldData) {
				while (entry != null) {
					HashEntry<E, V> next = entry.next;
					index = index(entry.key);
					entry.next = data[index];
					data[index] = entry;
					entry = next;
				}
			}
		}
		return null;
	}

	public V get(Object o) {
		if (o == null)
			return null;
		int index = index(o);
		HashEntry<E, V> current = data[index];
		while (current != null) {
			if (current.key.equals(o))
				return current.value;
			current = current.next;
		}
		return null;
	}

	public boolean containsKey(Object o) {
		if (o == null)
			return false;
		int index = index(o);
		HashEntry<E, V> current = data[index];
		while (current != null) {
			if (current.key.equals(o))
				return true;
			current = current.next;
		}
		return false;
	}

	public int size() {
		return size;
	}

	private static class HashEntry<E, V> implements Entry<E, V> {
		private final E key;
		private V value;
		private HashEntry<E, V> next;

		private HashEntry(E key, V value) {
			this.key = key;
			this.value = value;
		}

		public E getKey() {
			return key;
		}

		public V getValue() {
			return value;
		}

		public V setValue(V value) {
			V oldValue = this.value;
			this.value = value;
			return oldValue;
		}
	}
}

abstract class IntervalTree {
	protected int size;

	public IntervalTree(int size, boolean shouldInit) {
		this.size = size;
		int nodeCount = Math.max(1, Integer.highestOneBit(size) << 2);
		initData(size, nodeCount);
		if (shouldInit)
			init();
	}

	protected abstract void initData(int size, int nodeCount);

	protected abstract void initAfter(int root, int left, int right, int middle);

	protected abstract void initBefore(int root, int left, int right, int middle);

	protected abstract void initLeaf(int root, int index);

	protected abstract void updatePostProcess(int root, int left, int right,
			int from, int to, long delta, int middle);

	protected abstract void updatePreProcess(int root, int left, int right,
			int from, int to, long delta, int middle);

	protected abstract void updateFull(int root, int left, int right, int from,
			int to, long delta);

	protected abstract long queryPostProcess(int root, int left, int right,
			int from, int to, int middle, long leftResult, long rightResult);

	protected abstract void queryPreProcess(int root, int left, int right,
			int from, int to, int middle);

	protected abstract long queryFull(int root, int left, int right, int from,
			int to);

	protected abstract long emptySegmentResult();

	public void init() {
		if (size == 0)
			return;
		init(0, 0, size - 1);
	}

	private void init(int root, int left, int right) {
		if (left == right) {
			initLeaf(root, left);
		} else {
			int middle = (left + right) >> 1;
			initBefore(root, left, right, middle);
			init(2 * root + 1, left, middle);
			init(2 * root + 2, middle + 1, right);
			initAfter(root, left, right, middle);
		}
	}

	public void update(int from, int to, long delta) {
		update(0, 0, size - 1, from, to, delta);
	}

	protected void update(int root, int left, int right, int from, int to,
			long delta) {
		if (left > to || right < from)
			return;
		if (left >= from && right <= to) {
			updateFull(root, left, right, from, to, delta);
			return;
		}
		int middle = (left + right) >> 1;
		updatePreProcess(root, left, right, from, to, delta, middle);
		update(2 * root + 1, left, middle, from, to, delta);
		update(2 * root + 2, middle + 1, right, from, to, delta);
		updatePostProcess(root, left, right, from, to, delta, middle);
	}

	public long query(int from, int to) {
		return query(0, 0, size - 1, from, to);
	}

	protected long query(int root, int left, int right, int from, int to) {
		if (left > to || right < from)
			return emptySegmentResult();
		if (left >= from && right <= to)
			return queryFull(root, left, right, from, to);
		int middle = (left + right) >> 1;
		queryPreProcess(root, left, right, from, to, middle);
		long leftResult = query(2 * root + 1, left, middle, from, to);
		long rightResult = query(2 * root + 2, middle + 1, right, from, to);
		return queryPostProcess(root, left, right, from, to, middle,
				leftResult, rightResult);
	}
}

abstract class LongIntervalTree extends IntervalTree {
	protected long[] value;
	protected long[] delta;

	protected LongIntervalTree(int size) {
		this(size, true);
	}

	public LongIntervalTree(int size, boolean shouldInit) {
		super(size, shouldInit);
	}

	protected void initData(int size, int nodeCount) {
		value = new long[nodeCount];
		delta = new long[nodeCount];
	}

	protected abstract long joinValue(long left, long right);

	protected abstract long joinDelta(long was, long delta);

	protected abstract long accumulate(long value, long delta, int length);

	protected abstract long neutralValue();

	protected abstract long neutralDelta();

	protected long initValue(int index) {
		return neutralValue();
	}

	protected void initAfter(int root, int left, int right, int middle) {
		value[root] = joinValue(value[2 * root + 1], value[2 * root + 2]);
		delta[root] = neutralDelta();
	}

	protected void initBefore(int root, int left, int right, int middle) {
	}

	protected void initLeaf(int root, int index) {
		value[root] = initValue(index);
		delta[root] = neutralDelta();
	}

	protected void updatePostProcess(int root, int left, int right, int from,
			int to, long delta, int middle) {
		value[root] = joinValue(value[2 * root + 1], value[2 * root + 2]);
	}

	protected void updatePreProcess(int root, int left, int right, int from,
			int to, long delta, int middle) {
		pushDown(root, left, middle, right);
	}

	protected void pushDown(int root, int left, int middle, int right) {
		value[2 * root + 1] = accumulate(value[2 * root + 1], delta[root],
				middle - left + 1);
		value[2 * root + 2] = accumulate(value[2 * root + 2], delta[root],
				right - middle);
		delta[2 * root + 1] = joinDelta(delta[2 * root + 1], delta[root]);
		delta[2 * root + 2] = joinDelta(delta[2 * root + 2], delta[root]);
		delta[root] = neutralDelta();
	}

	protected void updateFull(int root, int left, int right, int from, int to,
			long delta) {
		value[root] = accumulate(value[root], delta, right - left + 1);
		this.delta[root] = joinDelta(this.delta[root], delta);
	}

	protected long queryPostProcess(int root, int left, int right, int from,
			int to, int middle, long leftResult, long rightResult) {
		return joinValue(leftResult, rightResult);
	}

	protected void queryPreProcess(int root, int left, int right, int from,
			int to, int middle) {
		pushDown(root, left, middle, right);
	}

	protected long queryFull(int root, int left, int right, int from, int to) {
		return value[root];
	}

	protected long emptySegmentResult() {
		return neutralValue();
	}
}


import java.util.*;
import java.io.*;
import java.lang.*;
import java.math.*;
public class A {
    public static void main(String[] args) throws Exception {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        // Scanner scan = new Scanner(System.in);
        // PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        long A = Long.parseLong(bf.readLine());
        Map<Long, HashSet<Integer>> m = new HashMap<Long, HashSet<Integer>>();
        Map<Long, Long> div = new HashMap<Long, Long>();
        ArrayList<Long> divisors = new ArrayList<Long>();
        long sqrt = (long)Math.sqrt(A);

        for(int i=1; i<=sqrt; i++) {
            if(A % i == 0) {
                divisors.add(i+0L);
                if(1L*i*i != A) divisors.add(A/i);
            }
        }
        Collections.sort(divisors);

        hi: for(long i : divisors) {
            //System.out.println(i);
            boolean done = false;
            sqrt = (long)Math.sqrt(i-1);
            for(long j=2; j<=sqrt; j++) {
                if((i-1) % j == 0) {
                    long val = i-1;
                    double t = Math.log(val)/Math.log(j);
                    if(Math.abs(t - Math.round(t)) > 0.00001) continue hi;
                    int count = (int)Math.round(t);
                    if(!m.containsKey(j)) m.put(j, new HashSet<Integer>());
                    m.get(j).add(count);
                    div.put(i, j);
                    done = true;
                    break;
                }
            }
            if(!done && i != 1 && i != 2 ) {
                if(!m.containsKey(i-1)) m.put(i-1, new HashSet<Integer>());
                m.get(i-1).add(1);
                div.put(i, i-1);
            }
        }
       //
        ArrayList<Long> P = new ArrayList<Long>();
        for(long l : m.keySet()) P.add(l);
        Collections.sort(P);
        int[] dp = new int[divisors.size()];
        //System.out.println(P.size() + " " + divisors.size());
        Map<Long, Integer> divis = new HashMap<Long, Integer>();
        for(int i=0; i<divisors.size(); i++) divis.put(divisors.get(i), i);
        dp[0] = 1;
        for(int i=1; i<=P.size(); i++) {
            for(int j=divisors.size()-1; j>=0; j--) {
                for(int k : m.get(P.get(i-1))) {
                    long val = (long)(Math.pow(P.get(i-1), k) + 1);
                    if(divisors.get(j) % val == 0)
                        dp[j] += dp[divis.get(divisors.get(j)/val)];
                }
            }
        }
        System.out.println(dp[divisors.size() - 1]);
       // System.out.println(P);
        // StringTokenizer st = new StringTokenizer(bf.readLine());
        // int[] a = new int[n]; for(int i=0; i<n; i++) a[i] = Long.parseInt(st.nextToken());
        // int n = Long.parseInt(st.nextToken());
        // int n = scan.nextInt();

        // out.close(); System.exit(0);
    }
}


import java.util.*;
import java.io.*;
import java.lang.*;
import java.math.*;
public class A {
    public static void main(String[] args) throws Exception {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        // Scanner scan = new Scanner(System.in);
        // PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        long A = Long.parseLong(bf.readLine());
        Map<Long, HashSet<Integer>> m = new HashMap<Long, HashSet<Integer>>();
        Map<Long, Long> div = new HashMap<Long, Long>();
        ArrayList<Long> divisors = new ArrayList<Long>();
        long sqrt = (long)Math.sqrt(A);

        for(int i=1; i<sqrt; i++) {
            if(A % i == 0) {
                divisors.add(i+0L);
                if(1L*i*i != A) divisors.add(A/i);
            }
        }
        Collections.sort(divisors);

        hi: for(long i : divisors) {
            //System.out.println(i);
            boolean done = false;
            sqrt = (long)Math.sqrt(i-1);
            for(long j=2; j<=sqrt; j++) {
                if((i-1) % j == 0) {
                    long val = i-1;
                    double t = Math.log(val)/Math.log(j);
                    if(Math.abs(t - Math.round(t)) > 0.00001) continue hi;
                    int count = (int)Math.round(t);
                    HashSet<Integer> set = m.get(j);
                    if(set == null) {
                      set = new HashSet<Integer>();
                      m.put(j, set);
                    }
                    set.add(count);
                    div.put(i, j);
                    done = true;
                    break;
                }
            }
            if(!done && i != 1 && i != 2 ) {
                HashSet<Integer> set = m.get(i - 1);
                if(set == null) {
                   set = new HashSet<Integer>();
                   m.put(i - 1, set);
                }
                set.add(1);
                div.put(i, i-1);
            }
        }

       //
        ArrayList<Long> P = new ArrayList<Long>();
        for(long l : m.keySet()) P.add(l);
        Collections.sort(P);
        int[] dp = new int[divisors.size()];
        //System.out.println(P.size() + " " + divisors.size());
        Map<Long, Integer> divis = new HashMap<Long, Integer>();
        for(int i=0; i<divisors.size(); i++) divis.put(divisors.get(i), i);
        dp[0] = 1;
                long start = System.currentTimeMillis();
                long divv, pp, val;
                System.out.println(divisors.size());
                                System.out.println(P.size());
                                System.out.println(m.size());
        ArrayList<ArrayList<Long>> temp = new ArrayList<>();
        for(int i = 1; i <= P.size(); i++) {
          ArrayList<Long> list = new ArrayList<Long>();
          temp.add(list);
          pp = P.get(i - 1);
          for(int k : m.get(pp)) {
            val = (long)(Math.pow(pp, k) + 1);
            list.add(val);

          }
        }
        for(int i=1; i<=P.size(); ++i) {
            for(int j=divisors.size()-1; j>=0; --j) {
                divv = divisors.get(j);
                pp = P.get(i - 1);
                int iter = 0;
                ArrayList<Long> tempp = temp.get(i - 1);
                for(int k : m.get(pp)) {
                    val = tempp.get(iter++);
                    if(divv % val == 0)
                        dp[j] += dp[divis.get(divv/val)];
                }
            }
        }
                System.out.println(System.currentTimeMillis() - start);
        System.out.println(dp[divisors.size() - 1]);
       // System.out.println(P);
        // StringTokenizer st = new StringTokenizer(bf.readLine());
        // int[] a = new int[n]; for(int i=0; i<n; i++) a[i] = Long.parseInt(st.nextToken());
        // int n = Long.parseInt(st.nextToken());
        // int n = scan.nextInt();

        // out.close(); System.exit(0);
    }
}


import java.util.*;
import java.io.*;
import java.awt.Point;
import java.math.BigDecimal;
import java.math.BigInteger;

import static java.lang.Math.*;

// Solution is at the bottom of code

public class D implements Runnable{

	final boolean ONLINE_JUDGE = System.getProperty("ONLINE_JUDGE") != null;

	BufferedReader in;
	OutputWriter out;
	StringTokenizer tok = new StringTokenizer("");

	public static void main(String[] args){
		new Thread(null, new D(), "", 128 * (1L << 20)).start();
	}

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

	void init() throws FileNotFoundException{
		Locale.setDefault(Locale.US);

		if (ONLINE_JUDGE){
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new OutputWriter(System.out);
		}else{
			in = new BufferedReader(new FileReader("input.txt"));
			out = new OutputWriter("output.txt");
		}
	}

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

	long timeBegin, timeEnd;

	void time(){
		timeEnd = System.currentTimeMillis();
		System.err.println("Time = " + (timeEnd - timeBegin));
	}

	void debug(Object... objects){
		if (ONLINE_JUDGE){
			for (Object o: objects){
				System.err.println(o.toString());
			}
		}
	}

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

	public void run(){
		try{
			timeBegin = System.currentTimeMillis();
			Locale.setDefault(Locale.US);

			init();
			solve();

			out.close();
			time();
		}catch (Exception e){
			e.printStackTrace(System.err);
			System.exit(-1);
		}
	}

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

	String delim = " ";

	String readString() throws IOException{
		while(!tok.hasMoreTokens()){
			try{
				tok = new StringTokenizer(in.readLine());
			}catch (Exception e){
				return null;
			}
		}

		return tok.nextToken(delim);
	}

	String readLine() throws IOException{
		return in.readLine();
	}

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

	final char NOT_A_SYMBOL = '\0';

	char readChar() throws IOException{
		int intValue = in.read();

		if (intValue == -1){
			return NOT_A_SYMBOL;
		}

		return (char) intValue;
	}

	char[] readCharArray() throws IOException{
		return readLine().toCharArray();
	}

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

	int readInt() throws IOException {
		return Integer.parseInt(readString());
	}

	int[] readIntArray(int size) throws IOException {
		int[] array = new int[size];

		for (int index = 0; index < size; ++index){
			array[index] = readInt();
		}

		return array;
	}

	int[] readSortedIntArray(int size) throws IOException {
		Integer[] array = new Integer[size];

		for (int index = 0; index < size; ++index) {
			array[index] = readInt();
		}
		Arrays.sort(array);

		int[] sortedArray = new int[size];
		for (int index = 0; index < size; ++index) {
			sortedArray[index] = array[index];
		}

		return sortedArray;
	}

	int[] readIntArrayWithDecrease(int size) throws IOException {
		int[] array = readIntArray(size);

		for (int i = 0; i < size; ++i) {
			array[i]--;
		}

		return array;
	}

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

	int[][] readIntMatrix(int rowsCount, int columnsCount) throws IOException {
		int[][] matrix = new int[rowsCount][];

		for (int rowIndex = 0; rowIndex < rowsCount; ++rowIndex) {
			matrix[rowIndex] = readIntArray(columnsCount);
		}

		return matrix;
	}

	int[][] readIntMatrixWithDecrease(int rowsCount, int columnsCount) throws IOException {
		int[][] matrix = new int[rowsCount][];

		for (int rowIndex = 0; rowIndex < rowsCount; ++rowIndex) {
			matrix[rowIndex] = readIntArrayWithDecrease(columnsCount);
		}

		return matrix;
	}

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

	long readLong() throws IOException{
		return Long.parseLong(readString());
	}

	long[] readLongArray(int size) throws IOException{
		long[] array = new long[size];

		for (int index = 0; index < size; ++index){
			array[index] = readLong();
		}

		return array;
	}

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

	double readDouble() throws IOException{
		return Double.parseDouble(readString());
	}

	double[] readDoubleArray(int size) throws IOException{
		double[] array = new double[size];

		for (int index = 0; index < size; ++index){
			array[index] = readDouble();
		}

		return array;
	}

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

	BigInteger readBigInteger() throws IOException {
		return new BigInteger(readString());
	}

	BigDecimal readBigDecimal() throws IOException {
		return new BigDecimal(readString());
	}

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

	Point readPoint() throws IOException{
		int x = readInt();
		int y = readInt();
		return new Point(x, y);
	}

	Point[] readPointArray(int size) throws IOException{
		Point[] array = new Point[size];

		for (int index = 0; index < size; ++index){
			array[index] = readPoint();
		}

		return array;
	}

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

	List<Integer>[] readGraph(int vertexNumber, int edgeNumber)
	throws IOException{
		@SuppressWarnings("unchecked")
		List<Integer>[] graph = new List[vertexNumber];

		for (int index = 0; index < vertexNumber; ++index){
			graph[index] = new ArrayList<Integer>();
		}

		while (edgeNumber-- > 0){
			int from = readInt() - 1;
			int to = readInt() - 1;

			graph[from].add(to);
			graph[to].add(from);
		}

		return graph;
	}

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

	static class IntIndexPair {

		static Comparator<IntIndexPair> increaseComparator = new Comparator<IntIndexPair>() {

			@Override
			public int compare(IntIndexPair indexPair1, IntIndexPair indexPair2) {
				int value1 = indexPair1.value;
				int value2 = indexPair2.value;

				if (value1 != value2) return value1 - value2;

				int index1 = indexPair1.index;
				int index2 = indexPair2.index;

				return index1 - index2;
			}
		};

		static Comparator<IntIndexPair> decreaseComparator = new Comparator<IntIndexPair>() {

			@Override
			public int compare(IntIndexPair indexPair1, IntIndexPair indexPair2) {
				int value1 = indexPair1.value;
				int value2 = indexPair2.value;

				if (value1 != value2) return -(value1 - value2);

				int index1 = indexPair1.index;
				int index2 = indexPair2.index;

				return index1 - index2;
			}
		};

		int value, index;

		public IntIndexPair(int value, int index) {
			super();
			this.value = value;
			this.index = index;
		}

		public int getRealIndex() {
			return index + 1;
		}
	}

	IntIndexPair[] readIntIndexArray(int size) throws IOException {
		IntIndexPair[] array = new IntIndexPair[size];

		for (int index = 0; index < size; ++index) {
			array[index] = new IntIndexPair(readInt(), index);
		}

		return array;
	}

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

	static class OutputWriter extends PrintWriter {

		final int DEFAULT_PRECISION = 12;

		protected int precision;
		protected String format, formatWithSpace;

		{
			precision = DEFAULT_PRECISION;

			format = createFormat(precision);
			formatWithSpace = format + " ";
		}

		public OutputWriter(OutputStream out) {
			super(out);
		}

		public OutputWriter(String fileName) throws FileNotFoundException {
			super(fileName);
		}

		public int getPrecision() {
			return precision;
		}

		public void setPrecision(int precision) {
			precision = max(0, precision);
			this.precision = precision;

			format = createFormat(precision);
			formatWithSpace = format + " ";
		}

		private String createFormat(int precision){
			return "%." + precision + "f";
		}

		@Override
		public void print(double d){
			printf(format, d);
		}

		public void printWithSpace(double d){
			printf(formatWithSpace, d);
		}

		public void printAll(double...d){
			for (int i = 0; i < d.length - 1; ++i){
				printWithSpace(d[i]);
			}

			print(d[d.length - 1]);
		}

		@Override
		public void println(double d){
			printlnAll(d);
		}

		public void printlnAll(double... d){
			printAll(d);
			println();
		}
	}

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

	static final int[][] steps = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
	static final int[][] steps8 = {
			{-1, 0}, {1, 0}, {0, -1}, {0, 1},
			{-1, -1}, {1, 1}, {1, -1}, {-1, 1}
	};

	static final boolean check(int index, int lim){
		return (0 <= index && index < lim);
	}

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

	static final boolean checkBit(int mask, int bit){
		return (mask & (1 << bit)) != 0;
	}

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

	static final long getSum(int[] array) {
		long sum = 0;
		for (int value: array) {
			sum += value;
		}

		return sum;
	}

	static final Point getMinMax(int[] array) {
		int min = array[0];
		int max = array[0];

		for (int index = 0, size = array.length; index < size; ++index, ++index) {
			int value = array[index];

			if (index == size - 1) {
				min = min(min, value);
				max = max(max, value);
			} else {
				int otherValue = array[index + 1];

				if (value <= otherValue) {
					min = min(min, value);
					max = max(max, otherValue);
				} else {
					min = min(min, otherValue);
					max = max(max, value);
				}
			}
		}

		return new Point(min, max);
	}

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

	void solve() throws IOException {
		long sum = readLong();

		List<Long> divisors = new ArrayList<Long>();
		for (long d = 1; d <= sum / d; ++d) {
			if (sum % d == 0) {
				divisors.add(d);
				if (sum / d != d) {
					divisors.add(sum / d);
				}
			}
		}

		Map<Long, Integer> indexes = new HashMap<Long, Integer>();
		for (int i = 0; i < divisors.size(); ++i) {
			long d = divisors.get(i);
			indexes.put(d, i);
		}

		Map<Long, List<Integer>> classes = new HashMap<Long, List<Integer>>();
		for (int i = 0; i < divisors.size(); ++i) {
			long d = divisors.get(i) - 1;

			boolean found = false;
			for (long prime = 2; prime <= d / prime; ++prime) {
				if (d  % prime == 0) {
					long x = d;
					while (x % prime == 0) {
						x /= prime;
					}

					if (x == 1) {
						add(classes, prime, i);
						found = true;
					}

					break;
				}
			}

			if (!found) {
				boolean isPrime = (d > 1);
				for (long dd = 2; dd <= d / dd; ++dd) {
					if (d % dd == 0) {
						isPrime = false;
						break;
					}
				}

				if (isPrime) {
					add(classes, d, i);
				}
			}
		}

		int divisorsCount = divisors.size();
		int classesCount = classes.size();

		long[] curDp = new long[divisorsCount];
		long[] nextDp = new long[divisorsCount];

		curDp[indexes.get(1L)] = 1;

		for (Map.Entry<Long, List<Integer>> e : classes.entrySet()) {
			List<Integer> classIndexes = e.getValue();

			for (int i = 0; i < divisorsCount; ++i) {
				long d = divisors.get(i);
				if (curDp[i] == 0) continue;

				for (int classIndex : classIndexes) {
					long classD = divisors.get(classIndex);

					if (sum / classD >= d) {
						long nextD = d * classD;

						if (sum % nextD == 0) {
							int nextI = indexes.get(nextD);

							if (nextI == indexes.get(3003L)) {
								nextI = nextI;
							}
							nextDp[nextI] += curDp[i];
						}
					}
				}
			}

			for (int i = 0; i < divisorsCount; ++i) {
				curDp[i] += nextDp[i];
				nextDp[i] = 0;
			}
		}

		out.println(curDp[indexes.get(sum)]);
	}

	void add(Map<Long, List<Integer>> classes, long key, int value) {
		List<Integer> keyClass = classes.get(key);
		if (keyClass == null) {
			classes.put(key, keyClass = new ArrayList<Integer>());
		}

		keyClass.add(value);
	}
}


import java.util.Scanner;

public class WaterMelon {

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

        Scanner in = new Scanner(System.in);
        int k = in.nextInt();

        for(int i=1;i<=k;k++)
            if(i==1)
                System.out.println(i + "=NO");
            else if(i==2)
                System.out.println(i + "=NO");
            else if((i-2)%2 == 0)
                System.out.println(i + "=YES");
            else if(i%2==0)
                System.out.println(i + "=YES");

            else System.out.println(i + "=NO");
    }

}


public class SoftDrinking {

	int getNumToasts(int n, int k, int l, int c, int d, int p, int nl, int np) {
		int toasts = (k * l) / nl;
		toasts = Math.min(toasts, c * d);
		toasts = Math.min(toasts, p / np);

		return toasts / n;
	}

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		String s = in.readLine();
		in.close();

		String[] t = s.split(" ");
		return getNumToasts
			Integer.parseInt(t[0]),
			Integer.parseInt(t[1]),
			Integer.parseInt(t[2]),
			Integer.parseInt(t[3]),
			Integer.parseInt(t[4]),
			Integer.parseInt(t[5]),
			Integer.parseInt(t[6]),
			Integer.parseInt(t[7])
		);
	}
}


import java.util.Scanner;

public class Spider120F {

    /**
     * @param args the command line arguments
     */

    public static void main(String[] args) throws Exception{
        // TODO code application logic here
        Scanner input=new Scanner(System.in);

        long p=input.nextLong();
        long d=input.nextLong();
        long bound=p-d;
        long tmp=p;
        long max=p;
        int i=1;
        while(tmp!=-1){
            tmp=(long)(p-(long)(p%Math.pow(10,i))-1);
            i++;
            if(tmp>=bound)
                max=tmp;
        }
        System.out.println(max);
    }

}


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

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

    static class TaskA {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt();
            char[] v = in.next().toCharArray();
            int res = 0;
            int[] dx = {1, -1, 0, 0};
            int[] dy = {0, 0, -1, 1};
            Map<Character, Integer> c = new HashMap<>();
            c.put('U', 0);
            c.put('D', 1);
            c.put('L', 2);
            c.put('R', 3);
            for (int i = 0; i < n; ++i) {
                boolean[][] dp = new boolean[5000][5000];
                int x = 1000;
                int y = 1000;
                dp[x][y] = true;
                for (int j = i; j < n; ++j) {
                    x += dx[c.get(v[j])];
                    y += dy[c.get(v[j])];
                    if (dp[x][y]) ++res;
                }
            }
            out.println(res);
        }

    }

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

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

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

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

    }
}


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

public class A {

	public static void main(String[] args){

		MyScanner in = new MyScanner();
		int n = in.nextInt();
		String s = in.next();

		int result = 0;
		for(int i=0;i<n;++i){
			for(int j=i+1;j<n;++j){
				int x = 0;
				int y = 0;
				for(int k=0;j<=j;++k){
					char ch = s.charAt(i+k);
					switch(ch){
						case('U'):y++;break;
						case('D'):y--;break;
						case('L'):x++;break;
						case('R'):x--;break;
					}
				}
				if(x==0&&y==0){
					result++;
				}
			}
		}
		System.out.println(result);

	}

	//-----------PrintWriter for faster output---------------------------------
	   public static PrintWriter out = new PrintWriter(System.out);

	   //-----------MyScanner class for faster input----------
	   public static class MyScanner {
	      BufferedReader br;
	      StringTokenizer st;

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

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

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

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

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

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

	   }
	   //--------------------------------------------------------

}


import java.util.*;
/**
 *
 *
 *
 * @author
 * @version 1.00 2016/9/19
 */

public class RobotSequence {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
    	Scanner kbd = new Scanner(System.in);
    	int n =kbd.nextInt();
    	String s = kbd.nextLine();
    	char[] st = s.toCharArray();
    	int x;
    	int y;
    	int count = 0;
    	if (n > 0 && n < 200){
    		for( int i = 0; i < n; i++){
    			x = 0;
    			y = 0;
    			for(int j = i ; j < n; j++){
    				switch (st[j]){
    					case 'U': y++; break;
    					case 'D': y--; break;
    					case 'R': x++; break;
    					case 'L': x--; break;
    				}
    					if (x==0 && y==0){
    					count++;
    					}
    			}
    		}
    	}

    System.out.println(count);
    }
}


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

/**
 * Created by Dipto on 14/02/2016.
 */
public class problem {
    public static void main(String[] args) {
        int i,j,k;
        int n;
        Scanner input = new Scanner(System.in);
        n=input.nextInt();
        String array = input.nextLine();
        int count = 0;
        for(i=0;i<n;i++){
            for(j=i;j<n;j++){
                int vertical = 0;
                int horizontal = 0;
                for(k=i;k<j;k++){
                    if(array.charAt(k)=='U')vertical++;
                    if(array.charAt(k)=='D')vertical--;
                    if(array.charAt(k)=='L')horizontal++;
                    if(array.charAt(k)=='R')horizontal--;
                }
                if(vertical==0 && horizontal==0 && i!=j )count++;
            }
        }
        System.out.println(count);
    }
}


import java.util.*;
public class java
{
    public static void main(String args[])
    {
        Scanner in=new Scanner(System.in);
        long n=in.nextLong(),s=0;
        long[] arr=new long[n];
        for(int i=0;i<n;i++)
        {
            arr[i]=in.nextLong();
            s=s+arr[i];
        }
        Arrays.sort(arr);
        long mid=0;
        while(mid<=arr.length-2)
        {
            if(arr[mid]==arr[mid+1])
            {
                s--;
                arr[mid]=arr[mid]-1;
                mid=0;
            }
            mid++;
        }
        System.out.println(s);
    }
}


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

public class buses
{
    public static void main(String[] args)
	{
        Scanner obj = new Scanner(System.in).useDelimiter("[^0-9]+");
        int a=obj.nextInt();
        int ta=obj.nextInt();
        int b=obj.nextInt();
        int tb=obj.nextInt();

		//String str=obj.next();
		int hh=obj.nextInt();
        int mm=obj.nextInt();

        int time= hh*60+mm;
        int ttime=time+ta;

        int ans = 0;
        for(int i=5*60;i<=1339;i+=b)
		{
            int time2=i+tb;
            if (time2>time && ttime>i)
				ans++;
        }
        System.out.println(ans);

    }
}


import java.util.Scanner;

/**
 * Created by Олег on 23.04.2016.
 */
public class BusBetweenCities {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        final int STARTTIME = 5*60;
        final int ENDTIME = 23*60+59;
        int a = in.nextInt();
        int t_a = in.nextInt();
        int b = in.nextInt();
        int t_b = in.nextInt();
        String s = in.next();
        String[] strings = s.split(":");
        int hh = Integer.valueOf(strings[0]);
        int mm = Integer.valueOf(strings[1]);
        int startTime = mm + hh*60;
        int endTime = startTime + t_a;
        int result =0;
        for (int time = STARTTIME; time < ENDTIME; time+=b) {
            if (time+t_b>startTime&&time<endTime) result++;
        }
        System.out.println(result);

    }
}


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

public class Test {
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		int input = sc.nextInt();
		int a =0;
		int [] arr = new int[1000000000];
		boolean f = true;
		while(true) {
			a++;
			if(!f) break;
		}
		if(input %2==0&&input!=2) {
			System.out.println("YES");
		}else {
			System.out.println("NO");
		}

}
}


import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

/**
 * Created by dhiaeddine on 15/06/14.
 */
public class PashaMaximizes {
    public static void main (String args[])
    {
        Scanner in = new Scanner(System.in);
        ArrayList<Character> myAr = new ArrayList<Character>();
        ArrayList<Character> extra = new ArrayList<Character>();
        ArrayList<Character> other = new ArrayList<Character>();
        String st = in.next();
        long tStart=System.currentTimeMillis();
       int permutations=in.nextInt();
        int permut=0,counter=0;
        permut=permutations;
        for (int i=0; i<st.length(); i++)
        {
            myAr.add(st.charAt(i));
            extra.add(st.charAt(i));
            other.add(st.charAt(i));
        }
        Collections.sort(extra);
        Collections.reverse(extra);
      ArrayList<Character> sup =  new ArrayList<Character>();
        while((permut!=0)&&!(extra.equals(myAr))) {
            Character max=myAr.get(counter);
            Character bigMax=myAr.get(counter);
            for (int i=0;i<myAr.size();i++)
                if(bigMax<myAr.get(i))
                    bigMax=myAr.get(i);
            while (max==myAr.get(counter))
            {
           for (int i=counter;i<counter+permut+1;i++)
           {   if (i<myAr.size())
               if ((max<myAr.get(i)))
                   max=myAr.get(i);
           }
           if (max==myAr.get(counter))
           {
               sup.add(myAr.get(counter));
               myAr.set(counter,'+');
               if (counter<myAr.size()-1)
               counter++;
               max=myAr.get(counter);
           }
            }

            if (myAr.indexOf(max)-counter<=permut)
            {
                while ((myAr.indexOf(max) != counter)&&(permut!=0)) {
                    permute(myAr, myAr.indexOf(max));
                permut--;
                }
            }else
            {
                while ((permut!=0)&&(myAr.indexOf(max)!=counter))
                {
                    permute(myAr, myAr.indexOf(bigMax));
                    permut--;
                }
            }
            if (max==myAr.get(counter))
            {
               sup.add(myAr.get(counter));
               myAr.set(counter,'+');
               if (counter<myAr.size()-1)
               counter++;
               max=myAr.get(counter);
            }

            for (int i=0;i<myAr.size();i++)
                other.set(i, myAr.get(i));
           if (myAr.contains('+'))
               for (int i=0;i<sup.size();i++)
                {
                   other.set(other.indexOf('+'), sup.get(i));
                }
        }
        long tEnd = System.currentTimeMillis();
        for (int i=0;i<myAr.size();i++)
            System.out.print(other.get(i));
     //  System.out.print("\nEclapsed time : "+(tEnd-tStart)+"ms");
        }
    public static void permute (ArrayList<Character> ar, int index)
    {
        char extra;
        if (index!=0)
        {
            extra=ar.get(index-1);
            ar.set(index-1,ar.get(index));
            ar.set(index,extra);
        }
    }
    }


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

public class Main {

    static int n, f[];
    static String s;
    static long ans, dp[][];

    public static void main(String[] args) {
        InputReader cin = new InputReader(System.in);
        n = cin.nextInt();
        s = cin.next();
        f = new int[s.length() + 1];
        ans = 0;

        // build failure function F[i] = index of largest prefix/suffix with end < i = where to look if i doesn't match
        f[0] = -1;
        f[1] = 0;
        for(int i = 2; i <= s.length(); i++) {
            f[i] = f[i-1];
            while(f[i] != -1 && s.charAt(i-1) != s.charAt(f[i])) f[i] = f[f[i]];
            ++f[i]; // ++ because this is on the scale of i-2 and not i-1
        }

        for(int suff_len = 0; suff_len < s.length(); suff_len++) {

            // calculate initial next state
            int pref = 0;
            for(int i = s.length() - suff_len; i < s.length(); i++) {
               while(pref != -1 && s.charAt(i) != s.charAt(pref)) pref = f[pref];
               ++pref;
            }

            dp = new long[n + 1][s.length() + 1]; // dp[i][index to look for i+1]

            // base case
            dp[suff_len][pref + 1] = 1;
            int tmp = pref;
            char val = s.charAt(pref) == '0' ? '1' : '0';
            while(tmp != -1 && s.charAt(tmp) != val) tmp = f[tmp];
            dp[suff_len][tmp + 1] = 1;

            for(int i = suff_len; i < n - 1; i++) {
                for(int state = 0; state < s.length(); state++) {
                   dp[i + 1][state + 1] += dp[i][state];
                   tmp = state;
                   val = s.charAt(state) == '0' ? '1' : '0';
                   while(tmp != -1 && s.charAt(tmp) != val) tmp = f[tmp];
                   dp[i + 1][tmp + 1] += dp[i][state];
                }
                dp[i + 1][s.length()] += dp[i][s.length()] << 1;
            }
            ans += dp[n - 1][s.length() - suff_len];
        }
        System.out.println(ans);
    }

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

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

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

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


import java.util.List;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Comparator;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.math.BigInteger;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author AlexFetisov
 */
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);
		TaskD solver = new TaskD();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskD {
    private static final int MOD = 777777777;
    static final int[][] C = IntegerUtils.getC(1000, MOD);

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int n = in.nextInt();
        int k = in.nextInt();
        out.println(calcDP(n, k));
    }

    int calcDP(int n, int k) {
        long[][][] dp = new long[n + 1][n + 1][n + 1];
        for (int i = 0; i <= n; ++i) {
            if (i == 1) {
                dp[1][i][0] = C[n][i];
            } else {
                dp[1][i][i] = C[n][i];
            }
        }
        for (int i = 1; i < n; ++i) {
            for (int j = 0; j <= n; ++j) {
                for (int p = 0; p <= k; ++p) {
                    if (dp[i][j][p] != 0) {
                        int rest = n - j;
                        for (int am = 0; am <= rest; ++am) {
                            if (am == i + 1) {
                                dp[i+1][j + am][p] += dp[i][j][p] * C[rest][am];
                                dp[i + 1][j + am][p] %= MOD;
                            } else {
                                if (p + am <= k) {
                                    dp[i + 1][j + am][p + am] += dp[i][j][p] * C[rest][am];
                                    dp[i + 1][j + am][p + am] %= MOD;
                                }
                            }
                        }
                    }
                }
            }
        }
        return (int)dp[n][n][k];
    }
}

class IntegerUtils {

    public static int[][] getC(int N, int MOD) {
        int[][] C = new int[N][];
        for (int i = 0; i < N; ++i) {
            C[i] = new int[i + 1];
            for (int j = 0; j <= i; ++j) {
                if (j == 0 || j == i) {
                    C[i][j] = 1;
                    if (C[i][j] >= MOD) C[i][j] -= MOD;
                } else {
                    C[i][j] = (C[i-1][j-1] + C[i-1][j]);
                    if (C[i][j] >= MOD) C[i][j] -= MOD;
                }
            }
        }
        return C;
    }

}

class InputReader {
    private BufferedReader reader;
    private StringTokenizer stt;

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

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

    public String nextString() {
        while (stt == null || !stt.hasMoreTokens()) {
            stt = new StringTokenizer(nextLine());
        }
        return stt.nextToken();
    }

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

}


package day11;
import java.util.Scanner;

public class ShellGame {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int x = sc.nextInt();
		sc.close();
		int mod =6 - n%6;
		if(x == 0){
			if(mod == 5|| mod == 6){
				System.out.println(0);
				return ;
			}
			if(mod == 1|| mod == 4){
				System.out.println(1);
				return ;
			}
			if(mod == 3|| mod == 2){
				System.out.println(2);
				return ;
			}
		}
		if(x == 1){
			if(mod == 1|| mod == 2){
				System.out.println(0);
				return ;
			}
			if(mod == 3|| mod == 6){
				System.out.println(1);
				return ;
			}
			if(mod == 4|| mod == 5){
				System.out.println(2);
				return ;
			}
		}
		if(x == 2){
			if(mod == 3|| mod == 4){
				System.out.println(0);
				return ;
			}
			if(mod == 2|| mod == 5){
				System.out.println(1);
				return ;
			}
			if(mod == 1|| mod == 6){
				System.out.println(2);
				return ;
			}
		}
	}

}


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

public class _400div2Q1
{
    public static void main(String[] args) throws IOException
    {
        FastScanner obj = new FastScanner();
        out = new PrintWriter(new BufferedOutputStream(System.out));

		int n = obj.nextInt();
		int[] arr = new int[n];
		for(int i=0;i<n;i++)	arr[i] = obj.nextInt();
		out.println(Arrays.binarySearch(arr,n));

        out.close();
   }

   //-----------PrintWriter for faster output---------------------------------
   public static PrintWriter out;

   //-----------FastScanner class for faster input----------
   public static class FastScanner {
        BufferedReader br;
        StringTokenizer tokenizer;

        public FastScanner() throws IOException {
            br = new BufferedReader(new InputStreamReader(System.in));
            tokenizer = new StringTokenizer(br.readLine().trim());
        }

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

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

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

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

        int[] nextIntArray() throws IOException {
            String[] line = br.readLine().trim().split(" ");
            int[] out = new int[line.length];

            for (int i = 0; i < line.length; i++) {
                out[i] = Integer.valueOf(line[i]);
            }
            return out;
        }

        BigInteger nextBigInteger() throws IOException {
            return new BigInteger(next());
        }

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

   }
   //--------------------------------------------------------
}


import java.io.*;
public class Main {
public static void main(String args[])throws IOException
{
	BufferedReader obj=new BufferedReader(new InputStreamReader(System.in));
	int n=Integer.parseInt(obj.readLine());
	int x=Integer.parseInt(obj.readLine());
	int flag[]=new int[3];
	for(int i=0;i<3;i++)
	{
		if(i==x)
			flag[i]=1;
		else
			flag[i]=0;
	}
	while(n!=0)
	{
		if(n%2==0)
		{
			swap(flag,1,2);
		}
		else
			swap(flag,0,1);
		n--;
	}
	for(int i=0;i<3;i++)
	{
		if(flag[i]==1)
		{
			System.out.println(i);
			break;
		}
	}
}
public static void swap(int []flag,int i,int j)
{
	int temp=flag[i];
	flag[i]=flag[j];
	flag[j]=temp;
}
}


import java.util.List;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.Locale;
import java.util.ArrayList;
import java.util.Comparator;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.math.BigInteger;
import java.io.InputStream;

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

class TaskD_LittleElAndTriangle {
    public static final int MOD = (int) 1e9 + 7;

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int n = in.nextInt();
        int m = in.nextInt();

        int res = 0;
        int amY0 = getAm(false, 0, m);
        int amY1 = m + 1 - amY0;
        int amX0 = getAm(false, 0, n);
        int amX1 = n + 1 - amX0;

        for (int x = 0; x <= n; ++x) {
            int B1 = BitUtils.checkBit(1 - x, 0) ? amX1 : amX0;
            int B3 = BitUtils.checkBit(x, 0) ? amX1 : amX0;
            for (int y = 0; y <= m; ++y) {
                int B2 = BitUtils.checkBit(y, 0) ? amY1 : amY0;
                int B4 = BitUtils.checkBit(1 - y, 0) ? amY1 : amY0;
                for (int xx2 = 0; xx2 <= 1; ++xx2) {
                    int A1 = BitUtils.checkBit(xx2, 0) ? amX1 : amX0;
                    for (int yy1 = 0; yy1 <= 1; ++yy1) {
                        if (odd(xx2 - x) * odd(yy1 - y) == 0) {
                            int A2 = BitUtils.checkBit(yy1, 0) ? amY1 : amY0;
                            long cur2 = (B1 * B2 + B3 * (m+1));
                            cur2 = cur2 * A1 * A2;
                            cur2 %= MOD;
                            res += cur2;
                            if (res >= MOD) res -= MOD;
                        } else {
                            int A2 = BitUtils.checkBit(yy1, 0) ? amY1 : amY0;
                            long cur = A1 * A2;
                            cur = cur * B1 * B4;
                            cur %= MOD;
                            res += cur;
                            if (res >= MOD) res -= MOD;
                        }
                    }
                }
            }
        }

        for (int dx = 0; dx <= n; ++dx) {
            for (int dy = 0; dy <= m; ++dy) {
                if (dx == 0 && dy == 0) continue;
                int amX = n - dx + 1;
                int amY = m - dy + 1;
                int amPoints = IntegerUtils.gcd(dx, dy);
                if (dx == 0 || dy == 0) {
                    res -= (amPoints * 6L * amX * amY) % MOD;
                } else {
                    res -= (amPoints * 12L * amX * amY) % MOD;
                }
                res += MOD;
                if (res >= MOD) {
                    res -= MOD;
                }
            }
        }

        res -= (n + 1) * (m + 1);
        res += MOD;
        if (res >= MOD) {
            res -= MOD;
        }

        out.println(res);
    }

    private int odd(int x) {
        return BitUtils.checkBit(x, 0) ? 1 : 0;
    }

    private int getAm(boolean odd, int begin, int end) {
        if (BitUtils.checkBit(begin, 0) != odd) {
            ++begin;
        }
        if (BitUtils.checkBit(end, 0) != odd) {
            --end;
        }
        if (begin <= end) {
            return (end - begin) / 2 + 1;
        }
        return 0;
    }
}

class InputReader {
    private BufferedReader reader;
    private StringTokenizer stt;

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

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

    public String nextString() {
        while (stt == null || !stt.hasMoreTokens()) {
            stt = new StringTokenizer(nextLine());
        }
        return stt.nextToken();
    }

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

}

class BitUtils {
    public static boolean checkBit(int mask, int bit) {
        return (mask & (1 << bit)) > 0;
    }

}

class IntegerUtils {

    public static int gcd(int x, int y) {
        return y == 0 ? x : gcd(y, x % y);
    }

}


import java.util.List;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.Locale;
import java.util.ArrayList;
import java.util.Comparator;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.math.BigInteger;
import java.io.InputStream;

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

class TaskD_LittleElAndTriangle {
    public static final int MOD = (int) 1e9 + 7;

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int n = in.nextInt();
        int m = in.nextInt();

        int res = 0;
        for (int x = 0; x <= n; ++x) {
            for (int y = 0; y <= m; ++y) {
                for (int d = 0; d < (1 << 3); ++d) {
                    int x1 = BitUtils.checkBit(d, 0) ? 1 : 0;
                    int y1 = BitUtils.checkBit(d, 1) ? 1 : 0;
                    int x2 = BitUtils.checkBit(d, 2) ? 1 : 0;
                    //int y2 = BitUtils.checkBit(d, 3) ? 1 : 0;

                    x1 = odd(x1 - x);
                    y1 = odd(y1 - y);
                    x2 = odd(x2 - x);
                    //y2 = odd(y2 - y);
                    if (x2 * y1 == 0) {
                        if (x1 == 1) {
                            // y2 == 0 => y2 == y
                            long cur = getAm(BitUtils.checkBit(d, 0), 0, n);
                            cur *= getAm(BitUtils.checkBit(d, 1), 0, m);
                            cur *= getAm(BitUtils.checkBit(d, 2), 0, n);
                            cur *= getAm(BitUtils.checkBit(y, 0), 0, m);
                            cur %= MOD;
                            res += cur;
                            if (res >= MOD) {
                                res -= MOD;
                            }
                        } else {
                            long cur = getAm(BitUtils.checkBit(d, 0), 0, n);
                            cur *= getAm(BitUtils.checkBit(d, 1), 0, m);
                            cur *= getAm(BitUtils.checkBit(d, 2), 0, n);
                            cur %= MOD;
                            cur *= (m + 1);
                            cur %= MOD;
                            res += cur;
                            if (res >= MOD) {
                                res -= MOD;
                            }
                        }
                    } else {
                        if (x1 == 1) {
                            // y2 == 1 => y2 != y
                            long cur = getAm(BitUtils.checkBit(d, 0), 0, n);
                            cur *= getAm(BitUtils.checkBit(d, 1), 0, m);
                            cur *= getAm(BitUtils.checkBit(d, 2), 0, n);
                            cur *= getAm(BitUtils.checkBit((1 - y), 0), 0, m);
                            cur %= MOD;
                            res += cur;
                            if (res >= MOD) {
                                res -= MOD;
                            }
                        }
                    }
//                    if (odd(x1 * y2 - x2 * y1) == 0) {
//                        long cur = getAm(BitUtils.checkBit(d, 0), 0, n);
//                        cur *= getAm(BitUtils.checkBit(d, 1), 0, m);
//                        cur *= getAm(BitUtils.checkBit(d, 2), 0, n);
//                        cur *= getAm(BitUtils.checkBit(d, 3), 0, m);
//                        cur %= MOD;
//                        res += cur;
//                        if (res >= MOD) {
//                            res -= MOD;
//                        }
//                    }
                }
//                res %= MOD;

                int amX = n - x + 1;
                int amY = m - y + 1;
                int amPoints = IntegerUtils.gcd(x, y) + 1;
                --amPoints;
                --amPoints;
                if (amPoints > 0) {
                    if (x == 0 || y == 0) {
                        res -= (amPoints * 6 * amX * amY) % MOD;
                    } else {
                        res -= (amPoints * 12 * amX * amY) % MOD;
                    }
                    res += MOD;
                    if (res >= MOD) {
                        res -= MOD;
                    }
                }

                if (x == 0 && y == 0) continue;
                if (x == 0 || y == 0) {
                    res -= (6 * amX * amY);
                } else {
                    res -= (12 * amX * amY);
                }
                res += MOD;
                if (res >= MOD) {
                    res -= MOD;
                }
            }
        }

        res -= (n + 1) * (m + 1);
        res += MOD;
        if (res >= MOD) {
            res -= MOD;
        }

        out.println(res);
    }

    private int odd(int x) {
        if (x < 0) {
            x = -x;
        }
        return BitUtils.checkBit(x, 0) ? 1 : 0;
    }

    private long getAm(boolean odd, int begin, int end) {
        if (BitUtils.checkBit(begin, 0) != odd) {
            ++begin;
        }
        if (BitUtils.checkBit(end, 0) != odd) {
            --end;
        }
        if (begin <= end) {
            return ((end - begin) >> 1) + 1;
        }
        return 0;
    }
}

class InputReader {
    private BufferedReader reader;
    private StringTokenizer stt;

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

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

    public String nextString() {
        while (stt == null || !stt.hasMoreTokens()) {
            stt = new StringTokenizer(nextLine());
        }
        return stt.nextToken();
    }

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

}

class BitUtils {
    public static boolean checkBit(int mask, int bit) {
        return (mask & (1 << bit)) > 0;
    }

}

class IntegerUtils {

    public static int gcd(int x, int y) {
        return y == 0 ? x : gcd(y, x % y);
    }

}


public class NewYearandOldPropertyB {
	private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
	public static void main(String[] args) {

		Scanner key = new Scanner(System.in);
		Long start = key.nextLong();
		Long stop = key.nextLong();
		int count=0,f=0,say=0;

		for(Long i=start;i<=stop;i++){
			String detect = Long.toBinaryString(i);
			if(detect.contains("0")){
				if(detect.substring(detect.indexOf("0")+1).contains("0")){
					count=5;
				}
				else
					count++;
			}
			if(count==1)
				say++;
			count=0;
		}
		System.out.println(say);
	}

}