/*
 * Copyright (c) 2004 Kamo Hiroyasu
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/*
 *  A solution to "Area of Polygons"
 *   Author: Kamo Hiroyasu <wd@ics.nara-wu.ac.jp>
 */

#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define INPUT_FILE	"area.txt"

struct vertex {
	int		x, y;
};

struct edge {
	struct vertex	v[2];
};

struct trapezoid {
	double		y[2][2];
};

void
vertices_to_edges(const struct vertex *vs, size_t nv, struct edge *es)
{
	size_t		i;
	const struct vertex  *v0, *v1;

	for (i = 0; i < nv; i ++) {
		v0 = &vs[i];
		v1 = &vs[(i + 1) % nv];
		if (v0->x < v1->x) {
			es[i].v[0] = *v0;
			es[i].v[1] = *v1;
		} else {
			es[i].v[0] = *v1;
			es[i].v[1] = *v0;
		}
	}
}

static int
compare_double(const void *p, const void *q)
{
	double		x, y;

	x = *(const double *)p;
	y = *(const double *)q;
	if (x > y) return 1;
	if (x < y) return -1;
	return 0;
}

void
edges_to_y_intersepts(const struct edge *es, size_t nv, int x, int dir,
		      double *ys, size_t *ny)
{
	size_t		i;
	size_t		n;
	int		x0, y0, x1, y1;

	n = 0;
	for (i = 0; i < nv; i ++) {
		x0 = es[i].v[0].x;
		x1 = es[i].v[1].x;
		if (dir > 0 ? x0 <= x && x < x1 : x0 < x && x <= x1) {
			y0 = es[i].v[0].y;
			y1 = es[i].v[1].y;
			ys[n] = (double)y0 +
				(double)(y1 - y0) * (double)(x - x0) /
				(double)(x1 - x0);
			n ++;
		}
	}
	qsort(ys, n, sizeof(double), compare_double);
	*ny = n;
}

void
edges_to_trapezoids(const struct edge *es, size_t nv, int x,
		    struct trapezoid *tzs, size_t *ntz)
{
	size_t		n;
	double		ys[2][nv];
	size_t		nys[2];
	size_t		i;

	edges_to_y_intersepts(es, nv, x, 1, ys[0], &nys[0]);
	edges_to_y_intersepts(es, nv, x + 1, -1, ys[1], &nys[1]);
	assert(nys[0] == nys[1]);
	n = nys[0] / 2;
	for (i = 0; i < n; i ++) {
		memcpy(tzs[i].y[0], &ys[0][i * 2], 2 * sizeof(double));
		memcpy(tzs[i].y[1], &ys[1][i * 2], 2 * sizeof(double));
	}
	*ntz = n;
}

void
x_projection(const struct vertex *vs, size_t nv, int *x0, int *x1)
{
	int		x_min, x_max;
	size_t		i;

	x_min = x_max = vs[0].x;
	for (i = 1; i < nv; i ++) {
		if (vs[i].x < x_min) {
			x_min = vs[i].x;
		} else if (vs[i].x > x_max) {
			x_max = vs[i].x;
		}
	}
	*x0 = x_min;
	*x1 = x_max;
}

void
y_projection(const struct trapezoid *tz, int *y0, int *y1)
{
	double		y_min, y_max, y;

	y_min = y_max = tz->y[0][0];
	y = tz->y[0][1];
	if (y < y_min) {
		y_min = y;
	} else if (y > y_max) {
		y_max = y;
	}
	y = tz->y[1][0];
	if (y < y_min) {
		y_min = y;
	} else if (y > y_max) {
		y_max = y;
	}
	y = tz->y[1][1];
	if (y < y_min) {
		y_min = y;
	} else if (y > y_max) {
		y_max = y;
	}
	*y0 = (int)floor(y_min);
	*y1 = (int)ceil(y_max);
}

int
area_of_polygon(const struct vertex *vs, size_t nv)
{
	int		a = 0;
	struct edge	es[nv];
	struct trapezoid  tzs[nv];
	size_t		ntz;
	int		x_min, x_max;
	int		x;
	size_t		i;

	vertices_to_edges(vs, nv, es);
	x_projection(vs, nv, &x_min, &x_max);
	for (x = x_min; x <= x_max; x ++) {
		edges_to_trapezoids(es, nv, x, tzs, &ntz);
		if (ntz > 0) {
			int		y0, y1, y1_prev;

			y_projection(&tzs[0], &y0, &y1);
			a += y1 - y0;
			for (i = 1; i < ntz; i ++) {
				y1_prev = y1;
				y_projection(&tzs[i], &y0, &y1);
				if (y1_prev > y0) {
					y0 = y1_prev;
				}
				a += y1 - y0;
			}
		}
	}
	return a;
}

main(int argc, char *argv[])
{
	const char	*path = INPUT_FILE;
	unsigned int	nvertices;
	struct vertex	*vertices;
	unsigned int	i;

	switch (argc) {
	case 2:
		path = argv[1];
	case 1:
		break;
	default:
		exit(1);
	}
	if (freopen(path, "r", stdin) == NULL) {
		perror(path);
		exit(1);
	}

	while (scanf("%u", &nvertices) == 1 && nvertices > 0) {
		struct vertex	vertices[nvertices];
		for (i = 0; i < nvertices; i ++) {
			scanf("%d%d", &vertices[i].x, &vertices[i].y);
		}
		printf("%d\n", area_of_polygon(vertices, (size_t)nvertices));
	}
	return 0;
}
