// Arup Guha
// 5/26/2016
// Solution to 2016 February USACO Gold Problem: Fenced In

import java.util.*;
import java.io.*;

public class fencedin {

	public static void main(String[] args) throws Exception {

		// Read in data.
		Scanner stdin = new Scanner(new File("fencedin.in"));
		int maxN = stdin.nextInt();
		int maxM = stdin.nextInt();
		int n = stdin.nextInt();
		int m = stdin.nextInt();

		// Read in the list of x values and sort.
		int[] nList = new int[n+2];
		for (int i=0; i<n; i++) nList[i] = stdin.nextInt();
		nList[n] = 0;
		nList[n+1] = maxN;
		Arrays.sort(nList);
		
		// Same for y values.
		int[] mList = new int[m+2];
		for (int i=0; i<m; i++) mList[i] = stdin.nextInt();
		mList[m] = 0;
		mList[m+1] = maxM;
		Arrays.sort(mList);

		// Sort by fence lengths.
		item[] allRC = new item[n+m+2];
		for (int i=0; i<=n; i++)
			allRC[i] = new item(i, nList[i+1]-nList[i]);
		for (int i=0; i<=m; i++)
			allRC[n+1+i] = new item(n+1+i, mList[i+1]-mList[i]);
		Arrays.sort(allRC);

		dset dj = new dset(n*(m+1)+m*(n+1));
		long res = 0;
		int added = 0;
		int index = 0;

		// Run modified Kruskal's.
		while (added < (n+1)*(m+1)-1) {

			// Consider all of these edges next.
			item next = allRC[index];

			
			// Try all edges from this row.
			if (next.ID <= n) {
				int nVal = next.ID;
				for (int i=0; i<m; i++) {
					boolean merge = dj.union(nVal*(m+1)+i, nVal*(m+1)+i+1);
					if (merge) {
						res = res + next.value;
						added++;
					}
				}
			}

			// Or this column.
			else {
				int mVal = next.ID - n - 1;
				for (int i=0; i<n; i++) {
					boolean merge = dj.union(i*(m+1)+mVal, (i+1)*(m+1)+mVal);
					if (merge) {
						res = res + next.value;
						added++;
					}
				}

			}	
			index++;
		
		}

		// Write result.
		PrintWriter out = new PrintWriter(new FileWriter("fencedin.out"));
		out.println(res);
		out.close();
		stdin.close();
	}
}

class item implements Comparable<item> {

	public int ID;
	public int value;

	public item(int myID, int myVal) {
		ID = myID;
		value = myVal;
	}

	public int compareTo(item other) {
		return this.value - other.value;
	}
}

class edge implements Comparable<edge> {

	public int v1;
	public int v2;
	public int w;

	public edge(int myv1, int myv2, int myw) {
		v1 = myv1;
		v2 = myv2;
		w = myw;
	}

	public int compareTo(edge other) {
		return this.w - other.w;
	}
}

//  Just used for the Disjoint set class.
class pair {
	public int parent;
	public int height;
	
	public pair(int a, int b) {
		parent = a;
		height = b;
	}
}

// Disjoint Set with path compression.
class dset {
	
	private pair[] parents;
	
	public dset(int n) {
		parents = new pair[n];
		for (int i=0; i<n; i++)
			parents[i] = new pair(i,0);
	}
	
	public int find(int child) {
		if (parents[child].parent == child) return child;
		int par = find(parents[child].parent);
		parents[child].parent = par;
		parents[child].height = 1;
		return par;
	}
	
	public boolean union(int c1, int c2) {
		int root1 = find(c1);
		int root2 = find(c2);
		
		// Nothing to union.
		if (root1 == root2)
			return false;
			
		// Root 1 stays parent.
		if (parents[root1].height > parents[root2].height) {
			parents[root2].parent = root1;
		}
		
		// Tie case get assigned to root 1 also.
		else if (parents[root1].height == parents[root2].height) {
			parents[root2].parent = root1;
			parents[root1].height++;
		}
		
		// Must use root 2 here.
		else {
			parents[root1].parent = root2;
		}
		
		return true;
	}
}