#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <cstring>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <unordered_set>
#include <unordered_map>
#include <array>
#include <cassert>
#include <bitset>
using namespace std;
using LL = long long;
using LD = long double;

const LD PI = acos(-1);


#include <vector>
using namespace std;


//Base class for Segment Trees
template <class T>
class segtree_base
{
protected:
	size_t width;
	vector<T> vec;
	T def;
	virtual T query_raw(int l_, int r_, int a_, int b_, int k_) = 0;
public:
	segtree_base(size_t size_, T def_ = T()) : def(def_)
	{
		width = 1;
		while (width < size_)width *= 2;
		vec.resize(width * 2 - 1, def);
	}
	//Ask a query in ranges [left,right)
	T query(int left, int right)
	{
		return query_raw(left, right, 0, width, 0);
	}
	//Get the number of child nodes
	size_t treeWidth()
	{
		return width;
	}
	virtual ~segtree_base() {}
};

#include <algorithm>
//Range Minimum Tree
template <class T, class Comp>
class rmq_tree : public segtree_base<T>
{
public:
	rmq_tree(size_t size_) : segtree_base<T>(size_, std::numeric_limits<T>::min())
	{}

	//Do [] <= base
	void init(const vector<T>&base)
	{
		for (int i = 0; i < min(this->width, base.size()); i++) this->vec[i + this->width - 1] = base[i];
		for (int i = this->width - 2; i >= 0; i--) this->vec[i] = std::min(this->vec[i * 2 + 1], this->vec[i * 2 + 2], Comp());
	}

	//Make [index] <= val;
	void update(int index, T val)
	{
		auto &vec = this->vec;
		index += (this->width - 1);
		vec[index] = val;
		while (index > 0)
		{
			index = (index - 1) / 2;
			vec[index] = std::min(vec[index * 2 + 1], vec[index * 2 + 2], Comp());
		}
	}
private:
	T query_raw(int l_, int r_, int a_, int b_, int k_)override
	{
		const auto &vec = this->vec;
		if (l_ <= a_ && b_ <= r_)
		{
			return vec[k_];
		}
		if (b_ <= l_ || r_ <= a_)
		{
			return this->def;
		}
		int m = (a_ + b_) / 2;
		return std::min(
			query_raw(l_, r_, a_, m, k_ + k_ + 1),
			query_raw(l_, r_, m, b_, k_ + k_ + 2), Comp());
	}
};

//Functors for Segment Trees
template <class T>
struct my_less : std::less<T>
{
	static constexpr T defval = std::numeric_limits<T>::max();
};
template <class T>
struct my_greater : std::greater<T>
{
	static constexpr T defval = std::numeric_limits<T>::min();
};

LL xs, ys, xe, ye;
LL N;
struct P
{
	LL x, y;
	int ind;
	P(LL x_, LL y_, int ind_) :x(x_), y(y_), ind(ind_)
	{}
};
vector<P>xP, yP;

int main(void)
{
	cout.precision(15);
	cin >> xs >> ys >> xe >> ye;
	bool xrev = xs > xe;
	bool yrev = ys > ye;
	if (xrev)
	{
		xs = -xs; xe = -xe;
	}
	if (yrev)
	{
		ys = -ys; ye = -ye;
	}
	cin >> N;
	int j = 0;
	for (LL i = 0; i < N; ++i)
	{
		LL X, Y; cin >> X >> Y;
		if (xrev)X = -X;
		if (yrev)Y = -Y;
		if (xs <= X && X <= xe && ys <= Y && Y <= ye)
		{
			xP.push_back({ X,Y,j });
			yP.push_back({ X,Y,j });
			++j;
		}
	}
	N = j;
	sort(xP.begin(), xP.end(), [](const P& p1, const P&p2)
	{
		if (p1.x == p2.x)return p1.y < p2.y; return p1.x < p2.x;
	});
	sort(yP.begin(), yP.end(), [](const P& p1, const P&p2)
	{
		if (p1.y == p2.y)return p1.x < p2.x; return p1.y < p2.y;
	});
	//first:position second:index
	vector<pair<LL, int>>xS(N), yS(N);
	map<LL, int>xdic, ydic;
	int ohx = 0, ohy = 0;
	for (auto xx : xP)
	{
		xdic[xx.x] = ohx;
		++ohx;
	}
	for (auto yy : yP)
	{
		ydic[yy.y] = ohy;
		++ohy;
	}
	for (auto xx : xP)
	{
		xS[ydic[xx.y]] = { xdic[xx.x],xx.ind };
	}
	for (auto yy : yP)
	{
		yS[xdic[yy.x]] = { ydic[yy.y],yy.ind };
	}
	if (ys == ye)
	{
		if (ydic.count(ys) && xs <= yP[ydic[ys]].x && yP[ydic[ys]].x <= xe)
		{
			LD ans = (xe - xs) * 100. - 20 + 10 * PI;
			cout << ans << endl;
		}
		else
		{
			LD ans = (xe - xs) * 100.;
			cout << ans << endl;
		}
	}
	else if (xs == xe)
	{
		if (xdic.count(xs) && ys <= xP[xdic[xs]].y && xP[xdic[xs]].y <= ye)
		{
			LD ans = (ye - ys) * 100. - 20 + 10 * PI;
			cout << ans << endl;
		}
		else
		{
			LD ans = (ye - ys) * 100.;
			cout << ans << endl;
		}
	}
	else
	{
		rmq_tree<int, greater<int>>seg(N + 2);
		/*
		xP.push_back({ xs - 1,ys - 1,N + 0 });
		xP.push_back({ xe + 1,ye + 1,N + 1 });
		yP.push_back({ xs - 1,ys - 1,N + 0 });
		yP.push_back({ xe + 1,ye + 1,N + 1 });
		N += 2;

		sort(xP.begin(), xP.end(), [](const P& p1, const P&p2)
		{
			if (p1.x == p2.x)return p1.y < p2.y; return p1.x < p2.x;
		});
		sort(yP.begin(), yP.end(), [](const P& p1, const P&p2)
		{
			if (p1.y == p2.y)return p1.x < p2.x; return p1.y < p2.y;
		});
		*/
		seg.update(0, 0);
		for (int i = 0; i < N; ++i)
		{
			int p = xdic[yP[i].x];
			//[0,p+1)のmax+1を更新
			assert(p <= N && 0 <= p);
			int val = seg.query(0, p + 1);
			assert(val <= i && 0 <= val);
			seg.update(p + 1, val + 1);
		}
		int pos = seg.query(0, N + 2);
		LD ans = (abs(ye - ys) + abs(xe - xs)) * 100.;
		ans -= (20. * pos);
		ans += (5. * PI * pos);
		//コーナーケース
		//xについて
		bool xflag = pos == N;
		for (LL xi = xs; xi <= xe; ++xi)
		{
			if (!xdic.count(xi))
			{
				xflag = false;
				break;
			}
		}
		if (xflag)
		{
			ans += 5 * PI;
		}
		bool yflag = pos == N;
		for (LL yi = ys; yi <= ye; ++yi)
		{
			if (!ydic.count(yi))
			{
				yflag = false;
				break;
			}
		}
		if (yflag)
		{
			ans += 5 * PI;
		}
		cout << ans << endl;
	}
	return 0;
}


Measured memory_bytes: 45428