// Arup Guha
// 5/24/2021
// Solution to 2020 January USACO Gold Problem: Springboards

import java.util.*;
import java.io.*;

public class springboards {

	public static int end;
	public static int n;
	public static board[] boards;
	
	final public static String FILE = "boards.in";

	public static void main(String[] args) throws Exception {
		
		BufferedReader stdin = new BufferedReader(new FileReader(FILE));
		StringTokenizer tok = new StringTokenizer(stdin.readLine());
		
		end = Integer.parseInt(tok.nextToken());
		n = Integer.parseInt(tok.nextToken());
		boards = new board[2*n];
		TreeSet<Integer> ySet = new TreeSet<Integer>();
		
		// Read in the spring boards. Store ends separately.
		for (int i=0; i<n; i++) {
			tok = new StringTokenizer(stdin.readLine());
			int x1 = Integer.parseInt(tok.nextToken());
			int y1 = Integer.parseInt(tok.nextToken());
			int x2 = Integer.parseInt(tok.nextToken());
			int y2 = Integer.parseInt(tok.nextToken());
			boards[2*i] = new board(x1, y1, true, 0, i);
			boards[2*i+1] = new board(x2, y2, false, x2-x1+y2-y1, i);
			ySet.add(y1); ySet.add(y2);
		}
		
		// Handle mapping y's - so segtree is small enough.
		int idx = 0;
		int[] yList = new int[ySet.size()];
		HashMap<Integer,Integer> yMap = new HashMap<Integer,Integer>();
		while (ySet.size() > 0) {
			yList[idx] = ySet.pollFirst();
			yMap.put(yList[idx], idx++);
		}
		
		// Coordinate compress.
		for (int i=0; i<2*n; i++) boards[i].y = yMap.get(boards[i].y);
		
		// Sort by x.
		Arrays.sort(boards);
		
		// dp[i] will store max savings for end at springboard i, original index.
		int[] dp = new int[n];
		
		// This will store max savings to get to the beginning of springboard i (original index)
		int[] origSave = new int[n];
		
		// To make the DP fast.
		IntTree mySegTree = new IntTree(0, yMap.size()+10);
		
		// Go in sorted order.
		for (int i=0; i<2*n; i++) {
			
			// Just get best savings before here.
			if (boards[i].start) {
				origSave[boards[i].idx] = mySegTree.query(0, boards[i].y);
			}
			
			// End point, always take the fast pass here.
			else {
				dp[boards[i].idx] = origSave[boards[i].idx] + boards[i].value;
				
				// This one has finished, if it helps our best outcome, update the seg tree.
				int cur = mySegTree.query(boards[i].y, boards[i].y);
				if (dp[boards[i].idx] > cur)
					mySegTree.change(boards[i].y, boards[i].y, dp[boards[i].idx]-cur);
			}
		}
		
		// Get max savings.
		int max = 0;
		for (int i=0; i<n; i++)
			max = Math.max(max, dp[i]);
		
		// Best answer is all walking minus max springboards.
		PrintWriter out = new PrintWriter(new FileWriter("boards.out"));
		out.println(2*end-max);
		out.close();
		stdin.close();
	}
}

// Manages either end of a springboard.
class board implements Comparable<board> {

	public int x;
	public int y;
	public boolean start;
	public int value;
	public int idx;
	
	public board(int myx, int myy, boolean flag, int myv, int myidx) {
		x = myx;
		y = myy;
		start = flag;
		value = myv;
		idx = myidx;
	}
	
	public int compareTo(board other) {
		if (x != other.x) return x - other.x;
		if (y != other.y) return y - other.y;
		if (start && !other.start) return 1;
		if (!start && other.start) return -1;
		return 0;
	}
}

/*** Max seg tree ***/
class IntTree {

	// Stores range for this node.
	public int low;
	public int high;

	// Stores aggregate data for this node.
	public int delta;
	public int value;

	// Pointers to children.
	public IntTree left;
	public IntTree right;

	// Creates an interval tree from myLow to myHigh, inclusive.
	public IntTree(int myLow, int myHigh) {

		low = myLow;
		high = myHigh;
		delta = 0;
		value = 0;

		// Lowest level.
		if (low == high) {
			left = null;
			right = null;
		}

		// Must create more nodes.
		else {
			int mid = (low+high)/2;
			left = new IntTree(low, mid);
			right = new IntTree(mid+1, high);
		}
	}

	// Propagates a change down to child nodes.
	public void prop() {

		// Recursive case, push down.
		if (left != null) {
			left.delta += delta;	
			right.delta += delta;	
			delta = 0;
		}

		// I put this in, seems to make sense.
		else {
			value += delta; 
			delta = 0;
		}
	}

	// Pre-condition: delta is 0.
	public void update() {
		if (left != null) {
			if (left.value+left.delta >= right.value+right.delta) {
				value = left.value+left.delta;
			}
			else {
				value = right.value+right.delta;
			}
		}
	}

	// Changes the values in the range [start, end] by "adding" extra.
	public void change(int start, int end, int extra) {

		// Out of range.
		if (high < start || end < low) return;

		// Push down delta.
		prop();

		// Whole range must be updated.
		if (start <= low && high <= end) {
			delta += extra;		
			update();
			return;
		}

		// Portions of children have to be changed instead.
		left.change(start, end, extra);
		right.change(start, end, extra);
		update();
	}

	public int query(int start, int end) {

		// Out of range.
		if (high < start || end < low) return 0;

		// Whole range must be returned;
		if (start <= low && high <= end) {
			return value + delta;
		}

		// Get answers from both potions.
		prop();
		int leftSide = left.query(start, end);
		int rightSide = right.query(start, end);
		update();
		return Math.max(leftSide, rightSide);
	}
}