#include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 100001

ll start[NUM],tail[NUM];
ll cut_pos[NUM];
ll ruiseki_odd[NUM],ruiseki_even[NUM];

int main(){

	int N,M;
	scanf("%d %d",&N,&M);

	for(int i = 0; i < N; i++){
		scanf("%lld %lld",&start[i],&tail[i]);
	}
	for(int i = 0; i < M; i++){
		scanf("%lld",&cut_pos[i]);
	}
	sort(cut_pos,cut_pos+M);

	//偶奇に分けた累積和テーブルを作成
	for(int i = 0; i < M; i++){
		ruiseki_odd[i] = 0;
		ruiseki_even[i] = 0;
	}
	//ruiseki_odd[i:奇数] = cut_pos[i:奇数]-cut_pos[i-1]の累積和
	for(int i = 1; i < M; i += 2){
		ruiseki_odd[i] = cut_pos[i]-cut_pos[i-1];
		if(i > 1){
			ruiseki_odd[i] += ruiseki_odd[i-2];
		}
	}
	//ruiseki_even[i:偶数] = cut_pos[i:偶数]-cut_pos[i-1]の累積和
	for(int i = 2; i < M; i += 2){
		ruiseki_even[i] = cut_pos[i]-cut_pos[i-1];
		ruiseki_even[i] += ruiseki_even[i-2];
	}

	ll ans = 0;
	int left,right,m;
	int max_index,min_index;

	for(int i = 0; i < N; i++){

		if(start[i] > tail[i]){

			if(cut_pos[0] >= start[i] || cut_pos[M-1] <= tail[i]){ //糸が分断されない場合
				ans += start[i]-tail[i];
				continue;
			}
			//start[i]以下の、最大の切断点を探す
			left = 0,right = M-1,m = (left+right)/2;
			while(left <= right){
				if(cut_pos[m] <= start[i]){
					max_index = m;
					left = m+1;
				}else{
					right = m-1;
				}
				m = (left+right)/2;
			}
			//tail[i]以上の、最小の切断点を探す
			left = 0,right = M-1, m = (left+right)/2;
			while(left <= right){
				if(cut_pos[m] >= tail[i]){
					min_index = m;
					right = m-1;
				}else{
					left = m+1;
				}
				m = (left+right)/2;
			}
			if(min_index > max_index){ //切断区間内にstartとtailが挟まっている場合
				ans += start[i]-tail[i];
				continue;
			}

			ans += start[i]-cut_pos[max_index]; //一番使い魔側の区間を足す

			if(max_index%2 == 0){ //最初の切れ目が偶数の場合:ruiseki_odd

				if(min_index%2 == 0){ //tailが無効区間

					ans += ruiseki_odd[max(0,max_index-1)]-ruiseki_odd[max(0,min_index-1)];

				}else{ //tailが有効区間

					ans += ruiseki_odd[max(0,max_index-1)]-ruiseki_odd[min_index]+cut_pos[min_index]-tail[i];
				}

			}else{ //max_index%2 == 1

				if(min_index%2 == 1){ //tailが無効区間

					ans += ruiseki_even[max(0,max_index-1)]-ruiseki_even[max(0,min_index-1)];

				}else{ //tailが有効区間

					ans += ruiseki_even[max(0,max_index-1)]-ruiseki_even[min_index];
					if(min_index > 0){
						ans += cut_pos[min_index]-tail[i];
					}else if(min_index != max_index && min_index == 0 && tail[i] < cut_pos[0]){
						ans += cut_pos[0]-tail[i];
					}
				}
			}

		}else{ //start[i] < tail[i]

			if(cut_pos[0] >= tail[i] || cut_pos[M-1] <= start[i]){
				ans += tail[i]-start[i];
				continue;
			}
			//start[i]以上の、最小の切断点を探す
			left = 0,right = M-1,m = (left+right)/2;
			while(left <= right){
				if(cut_pos[m] >= start[i]){
					min_index = m;
					right = m-1;
				}else{
					left = m+1;
				}
				m = (left+right)/2;
			}
			//tail[i]以下の、最大の切断点を探す
			left = 0,right = M-1,m = (left+right)/2;
			while(left <= right){
				if(cut_pos[m] <= tail[i]){
					max_index = m;
					left = m+1;
				}else{
					right = m-1;
				}
				m = (left+right)/2;
			}

			if(min_index > max_index){ //切断区間内にstartとtailが挟まっている場合
				ans += tail[i]-start[i];
				continue;
			}

			ans += cut_pos[min_index]-start[i];

			if(min_index%2 == 1){ //最初の切れ目が奇数の場合;ruiseki_odd

				if(max_index%2 == 1){ //tailが無効区間

					ans += ruiseki_odd[max_index]-ruiseki_odd[min_index];
				}else{
					ans += ruiseki_odd[max(0,max_index-1)]-ruiseki_odd[min_index]+tail[i]-cut_pos[max_index];
				}

			}else{ //min_index%2 == 0:最初の切れ間が偶数:ruiseki_even

				if(max_index%2 == 0){ //tailが無効区間

					ans += ruiseki_even[max_index]-ruiseki_even[min_index];
				}else{
					ans += ruiseki_even[max(0,max_index-1)]-ruiseki_even[min_index]+tail[i]-cut_pos[max_index];				}
			}
		}
	}

	printf("%lld\n",ans);

	return 0;
}



Measured memory_bytes: 7180