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

public class convex_ab implements Runnable {

	final int MAXN = 100000;
	final int MAXC = (int)(1e9);
	
	private void solve() throws IOException {
		int n = in.nextInt();
		myAssert(3 <= n && n <= MAXN);
		Point[] pa = new Point[n];
		TreeSet<Point> hp = new TreeSet<Point>();
		for (int i = 0; i < n; ++i) {
			pa[i] = new Point(in.nextInt(), in.nextInt());
			myAssert(Math.abs(pa[i].x) <= MAXC);
			myAssert(Math.abs(pa[i].y) <= MAXC);
			myAssert(!hp.contains(pa[i]));
			hp.add(pa[i]);
		}
		
		Arrays.sort(pa);
		for (int i = n - 1; i >= 0; --i) {
			pa[i].x -= pa[0].x;
			pa[i].y -= pa[0].y;
		}
	
		Arrays.sort(pa, 1, n, cmpAng);
	
		ArrayList<Point> stack = new ArrayList<Point>();
		
		for (int i = 0; i < pa.length;) {
			Point p = pa[i];
			if (stack.size() < 2) {
				stack.add(p);
				++i;
			} else {
				Point u = stack.get(stack.size() - 2);
				Point v = stack.get(stack.size() - 1);
				long ux = v.x - u.x;
				long uy = v.y - u.y;
				long vx = p.x - v.x;
				long vy = p.y - v.y;
				if (ux * vy - uy * vx < 0) {
					stack.add(p);
					++i;
				} else {
					stack.remove(stack.size() - 1);
				}
			}
		}
		
		long s = 0;
		long ans = 0;
		for (int i = 0; i < stack.size(); ++i) {
			int j = (i + 1) % stack.size();
			s += stack.get(j).x * stack.get(i).y - stack.get(j).y * stack.get(i).x;
			ans += gcd(Math.abs(stack.get(j).x - stack.get(i).x), Math.abs(stack.get(j).y - stack.get(i).y));
		}
		s = Math.abs(s);
		out.println((s - ans) / 2 + 1);
	}
	
	long gcd(long a, long b) {
		if (a == 0) return b;
		return gcd(b % a, a);
	}
	
	Comparator<Point> cmpAng = new Comparator<Point>() {
		@Override
		public int compare(Point a, Point b) {
			long t = a.x * b.y - a.y * b.x;
			long la = a.x * a.x + a.y * a.y;
			long lb = b.x * b.x + b.y * b.y; 
			return t < 0 ? -1 : t > 0 ? 1 : la < lb ? -1 : la > lb ? 1 : 0;
		}
	};
	
	class Point implements Comparable<Point> {
		long x, y;

		public Point(int x, int y) {
			this.x = x;
			this.y = y;
		}
		
		@Override
		public int compareTo(Point o) {
			return x < o.x ? -1 : x > o.x ? 1 : y < o.y ? -1 : y > o.y ? 1 : 0;
		}
		
		@Override
		public boolean equals(Object o) {
			if (!(o instanceof Point)) return false;
			Point p = (Point) o;
			return x == p.x && y == p.y;
		}
	}
	
	void myAssert(boolean e) {
		if (!e) {
			throw new Error("Assertion failed");
		}
	}
	
	final String FILE_NAME = "convex";

	SimpleScanner in;
	PrintWriter out;

	@Override
	public void run() {
		try {
			in = new SimpleScanner(new FileReader(FILE_NAME + ".in"));
			out = new PrintWriter(FILE_NAME + ".out");
			solve();
			out.close();
		} catch (Throwable e) {
			e.printStackTrace();
			System.exit(-1);
		}
	}

	public static void main(String[] args) {
		new Thread(new convex_ab()).start();
	}

	class SimpleScanner extends BufferedReader {

		private StringTokenizer st;
		private boolean eof;

		public SimpleScanner(Reader a) {
			super(a);
		}

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

		boolean seekEof() {
			String s = next();
			if ("".equals(s) && eof)
				return true;
			st = new StringTokenizer(s + " " + st.toString());
			return false;
		}

		private String cnv(String s) {
			if (s.length() == 0)
				return "0";
			return s;
		}

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

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

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