//make sure to make new file!
import java.io.*;
import java.util.*;

public class D600{

   public static ArrayList<ArrayList<Integer>> adj;
   public static int min;
   public static int max;
   public static HashSet<Integer> seen;

   public static void main(String[] args)throws IOException{
      BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
      PrintWriter out = new PrintWriter(System.out);

      StringTokenizer st = new StringTokenizer(f.readLine());

      int n = Integer.parseInt(st.nextToken());
      int m = Integer.parseInt(st.nextToken());

      adj = new ArrayList<ArrayList<Integer>>(n+1);
      for(int k = 0; k <= n; k++) adj.add(new ArrayList<Integer>());

      for(int k = 0; k < m; k++){
         st = new StringTokenizer(f.readLine());

         int a = Integer.parseInt(st.nextToken());
         int b = Integer.parseInt(st.nextToken());

         adj.get(a).add(b);
         adj.get(b).add(a);
      }

      PriorityQueue<Pair> pairs = new PriorityQueue<Pair>();
      seen = new HashSet<Integer>();
      for(int k = 1; k <= n; k++){
         if(seen.contains(k)) continue;
         min = k;
         max = k;
         seen.add(k);
         dfs(k);
         //out.println(min + " " + max);
         pairs.add(new Pair(min,max));
      }

      int answer = 0;

      Pair first = pairs.poll();
      int curmax = first.b;
      int size = 1;
      while(!pairs.isEmpty()){
         Pair cur = pairs.poll();
         if(cur.a < curmax){
            curmax = Math.max(curmax,cur.b);
            size++;
         } else {
            curmax = cur.b;
            answer += size-1;
            size = 1;
         }
      }
      answer += size-1;

      out.println(answer);

      out.close();
   }

   public static void dfs(int v){
      max = Math.max(max,v);
      min = Math.min(min,v);

      for(int nei : adj.get(v)){
         if(seen.contains(nei)) continue;
         seen.add(nei);
         dfs(nei);
      }
   }

   public static class Pair implements Comparable<Pair>{
      int a;
      int b;
      public Pair(int c, int d){
         a = c;
         b = d;
      }
      public int compareTo(Pair p){
         return a-p.a;
      }
   }

}


//make sure to make new file!
import java.io.*;
import java.util.*;

public class D600{

   public static ArrayList<ArrayList<Integer>> adj;
   public static int min;
   public static int max;
   public static HashSet<Integer> seen;

   public static void main(String[] args)throws IOException{
      BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
      PrintWriter out = new PrintWriter(System.out);

      StringTokenizer st = new StringTokenizer(f.readLine());

      int n = Integer.parseInt(st.nextToken());
      int m = Integer.parseInt(st.nextToken());

      adj = new ArrayList<ArrayList<Integer>>(n+1);
      for(int k = 0; k <= n; k++) adj.add(new ArrayList<Integer>());

      for(int k = 0; k < m; k++){
         st = new StringTokenizer(f.readLine());

         int a = Integer.parseInt(st.nextToken());
         int b = Integer.parseInt(st.nextToken());

         adj.get(a).add(b);
         adj.get(b).add(a);
      }

      PriorityQueue<Pair> pairs = new PriorityQueue<Pair>();
      seen = new HashSet<Integer>();
      for(int k = 1; k <= n; k++){
         if(seen.contains(k)) continue;
         min = k;
         max = k;
         seen.add(k);
         dfs(k);
         //out.println(min + " " + max);
         pairs.add(new Pair(min,max));
      }

      int answer = 0;

      Pair first = pairs.poll();
      int curmax = first.b;
      int size = 1;
      while(!pairs.isEmpty()){
         Pair cur = pairs.poll();
         if(cur.a < curmax){
            curmax = Math.max(curmax,cur.b);
            size++;
         } else {
            curmax = cur.b;
            answer += size-1;
            size = 1;
         }
      }

      out.println(answer);

      out.close();
   }

   public static void dfs(int v){
      max = Math.max(max,v);
      min = Math.min(min,v);

      for(int nei : adj.get(v)){
         if(seen.contains(nei)) continue;
         seen.add(nei);
         dfs(nei);
      }
   }

   public static class Pair implements Comparable<Pair>{
      int a;
      int b;
      public Pair(int c, int d){
         a = c;
         b = d;
      }
      public int compareTo(Pair p){
         return a-p.a;
      }
   }

}


// Main Code at the Bottom
import java.util.*;
import java.lang.*;
import java.io.*;
import java.math.BigInteger;
public class Main {
	//Fast IO class
    static class FastReader {
        BufferedReader br;
        StringTokenizer st;
        public FastReader() {
        	boolean env=System.getProperty("ONLINE_JUDGE") != null;
        	if(!env) {
        		try {
					br=new BufferedReader(new FileReader("src\\input.txt"));
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				}
        	}
        	else br = new BufferedReader(new InputStreamReader(System.in));
        }
        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                }
                catch (IOException  e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }
        int nextInt() {
            return Integer.parseInt(next());
        }
        long nextLong() {
            return Long.parseLong(next());
        }
        double nextDouble() {
            return Double.parseDouble(next());
        }
        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
    static long MOD=1000000000+7;
    //Euclidean Algorithm
    static long gcd(long A,long B){
    	return (B==0)?A:gcd(B,A%B);
    }
    //Modular Exponentiation
    static long fastExpo(long x,long n){
        if(n==0) return 1;
        if((n&1)==0) return fastExpo((x*x)%MOD,n/2)%MOD;
        return ((x%MOD)*fastExpo((x*x)%MOD,(n-1)/2))%MOD;
    }
    //Modular Inverse
    static long inverse(long x) {
    	return fastExpo(x,MOD-2);
    }
    //Prime Number Algorithm
    static boolean isPrime(long n){
        if(n<=1) return false;
        if(n<=3) return true;
        if(n%2==0 || n%3==0) return false;
        for(int i=5;i*i<=n;i+=6) if(n%i==0 || n%(i+2)==0) return false;
        return true;
    }
    //Reverse an array
    static void reverse(char arr[],int l,int r){
    	while(l<r) {
    		char tmp=arr[l];
    		arr[l++]=arr[r];
    		arr[r--]=tmp;
    	}
    }
    //Print array
    static void print1d(int arr[]) {
    	out.println(Arrays.toString(arr));
    }
    static void print2d(int arr[][]) {
    	for(int a[]: arr) out.println(Arrays.toString(a));
    }
    // Pair
    static class pair{
    	int x,y;
    	pair(int a,int b){
    		this.x=a;
    		this.y=b;
    	}
    	public boolean equals(Object obj) {
    		if(obj == null || obj.getClass()!= this.getClass()) return false;
            pair p = (pair) obj;
            return (this.x==p.x && this.y==p.y);
        }
    	public int hashCode() {
            return Objects.hash(x,y);
        }
    }
    static FastReader sc=new FastReader();
    static PrintWriter out=new PrintWriter(System.out);
    //Main function(The main code starts from here
    static int parent[];
    static void init(int n) {
    	parent=new int[n];
    	for(int i=0;i<n;i++) parent[i]=i;
    }
    static int find(int x) {
    	if(parent[x]==x) return x;
    	return parent[x]=find(parent[x]);
    }
    static void union(int a,int b) {
    	a=find(a);
    	b=find(b);
    	if(a==b) return;
    	if(a>b) parent[b]=a;
    	else parent[a]=b;
    }
    public static void main (String[] args) throws java.lang.Exception {
    	int test=1;
    	//test=sc.nextInt();
    	while(test-->0){
    		int n=sc.nextInt(),m=sc.nextInt();
    		init(n);
    		for(int i=0;i<m;i++) union(sc.nextInt()-1,sc.nextInt()-1);
    		int ans=0;
    		for(int i=0;i<n;i++) {
    			int max=find(i);
    			for(int j=i;j<=max;j++) {
    				if(find(i)!=find(j)) {
    					ans++;
    					union(i,j);
    					max=find(i);
    				}
    			}
    			i=max;
    		}
    		out.println(ans);
    	}
        out.flush();
        out.close();
    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.util.Comparator;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Washoum
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        inputClass in = new inputClass(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        DHarmoniousGraph solver = new DHarmoniousGraph();
        solver.solve(1, in, out);
        out.close();
    }

    static class DHarmoniousGraph {
        static int min;
        static int max;
        static DHarmoniousGraph.Node[] graph;
        static boolean[] visited;

        static void dfs(int a) {
            visited[a] = true;
            min = Math.min(min, a);
            max = Math.max(max, a);
            for (int i : graph[a].edges) {
                if (!visited[i]) {
                    dfs(i);
                }
            }
        }

        public void solve(int testNumber, inputClass sc, PrintWriter out) {
            int n = sc.nextInt();
            graph = new DHarmoniousGraph.Node[n];
            for (int i = 0; i < n; i++) {
                graph[i] = new DHarmoniousGraph.Node();
                graph[i].edges = new ArrayList<>();
            }
            int m = sc.nextInt();
            for (int i = 0; i < m; i++) {
                int x = sc.nextInt() - 1;
                int y = sc.nextInt() - 1;
                graph[x].edges.add(y);
                graph[y].edges.add(x);
            }
            visited = new boolean[n];
            ArrayList<DHarmoniousGraph.Pair> inter = new ArrayList<>();
            for (int i = 0; i < n; i++) {
                if (!visited[i]) {
                    min = Integer.MAX_VALUE;
                    max = -1;
                    dfs(i);
                    inter.add(new DHarmoniousGraph.Pair(min, max));
                }
            }
            inter.sort(Comparator.comparingInt(a -> a.x));
            int ans = 0;
            int last = inter.get(0).y;
            for (int i = 1; i < inter.size(); i++) {
                if (inter.get(i).x < last) {
                    ans++;
                }
                last = Math.max(inter.get(i).y, last);
            }
            out.println(ans);
        }

        static class Pair {
            int x;
            int y;

            public Pair(int x, int y) {
                this.x = x;
                this.y = y;
            }

        }

        static class Node {
            ArrayList<Integer> edges;

        }

    }

    static class inputClass {
        BufferedReader br;
        StringTokenizer st;

        public inputClass(InputStream in) {

            br = new BufferedReader(new InputStreamReader(in));
        }

        public String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.StringTokenizer;

public class Solution {
	static class FastReader
	{
		BufferedReader br;
		StringTokenizer st;

		public FastReader()
		{
			br = new BufferedReader(new
					InputStreamReader(System.in));
		}

		String next()
		{
			while (st == null || !st.hasMoreElements())
			{
				try
				{
					st = new StringTokenizer(br.readLine());
				}
				catch (IOException e)
				{
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt()
		{
			return Integer.parseInt(next());
		}

		long nextLong()
		{
			return Long.parseLong(next());
		}

		double nextDouble()
		{
			return Double.parseDouble(next());
		}

		String nextLine()
		{
			String str = "";
			try
			{
				str = br.readLine();
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
			return str;
		}
	}
	static LinkedList<Integer> adj[];
	static boolean vis[];
	public static void main(String[] args)
	{
		FastReader in=new FastReader();
		int n = in.nextInt();
		int m = in.nextInt();
		adj = new LinkedList[n];
		vis = new boolean [n];
		for(int i= 0;i<n;i++)
			adj[i] = new LinkedList<>();
		for(int i = 0;i<m;i++)
		{
			int u = in.nextInt();
			int v = in.nextInt();
			u--;
			v--;
			adj[u].add(v);
			adj[v].add(u);
		}
		ArrayList<Pair<Integer, Integer>> comp = new ArrayList<>();
		for(int i = 0;i<n;i++)
		{
			if(!vis[i])
			{
				int a[] = new int[1];
				int b[] = new int[1];
				a[0] = i;
				b[0] = i;
				dfs(i,a,b);
//				System.out.println(a[0]+" "+b[0]);
				comp.add(new Pair<Integer, Integer>(a[0],b[0]));
			}
		}

		int rep = 0;
		int currend = -1;
		for(Pair<Integer, Integer> p : comp)
		{
			if(p.first<=currend)
			{
				rep++;
			}
			currend = Math.max(p.second, currend);
		}
		System.out.println(rep);
	}
	private static void dfs(int i,int[] a, int[] b)
	{
		vis[i] = true;
		a[0] = Math.min(a[0], i);
		b[0] = Math.max(b[0], i);
		for(int neigh : adj[i])
		{
			if(!vis[neigh])
			{
				dfs(neigh,a,b);
			}
		}
	}
}
class Pair<T,V>
{
	T first; V second;
	Pair(T a, V b)
	{
		first = a;
		second = b;
	}
}


import java.util.*;
import java.io.*;
import java.math.BigInteger;

public class tr0 {
	static PrintWriter out;
	static StringBuilder sb;
	static final double EPS = 1e-9;
	static long mod = (int) 1e9 + 7;
	static int inf = (int) 1e9 + 2;
	static long[] fac, a;
	static int[] si;
	static ArrayList<Integer> primes;
	static ArrayList<Integer>[] ad;
	static ArrayList<pair>[] d;
	static edge[] ed;
	static int[][] vis;
	static int[] l, ch;
	static int[] occ;
	static Queue<Integer>[] can;
	static String s;
	static long[][] memo;
	static int n;

	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);
		out = new PrintWriter(System.out);
		int n=sc.nextInt();
		int m=sc.nextInt();
		unionfind uf=new unionfind(n+1);
		for(int i=0;i<m;i++)
			uf.combine(sc.nextInt(), sc.nextInt());
		for(int i=0;i<n+1;i++)
			uf.findSet(i);
		int ans=0;
		int st=1;
		for(int i=1;i<=n;i++) {
			if(uf.max[i]==i) {
				st=i;
				continue;
			}
			int max=uf.max[i];
			for(int j=i;j<max;j++) {
				if(uf.combine(i, j))
					continue;
				max=Math.max(max, uf.max[j]);
				ans++;
			}
			i=max;
		}
		out.print(ans);
		out.flush();
	}

	static class qu implements Comparable<qu> {
		int id, val;

		qu(int i, int v) {
			id = i;
			val = v;
		}

		public String toString() {
			return id + " " + val;
		}

		public int compareTo(qu o) {
			return id - o.id;
		}
	}

	static class seg implements Comparable<seg> {
		int a;
		int b;

		seg(int s, int e) {
			a = s;
			b = e;
		}

		public String toString() {
			return a + " " + b;
		}

		public int compareTo(seg o) {
			// if(a==o.a)
			return o.b - b;
			// return
		}
	}

	static class pair {
		int to;
		int number;

		pair(int t, int n) {
			number = n;
			to = t;
		}

		public String toString() {
			return to + " " + number;
		}
	}

	static double modPow(double a, int e)

	{
		double res = 1;
		while (e > 0) {
			if ((e & 1) == 1)
				res = (res * a);
			a = (a * a);
			e >>= 1;
		}
		return res;
	}

	static boolean[] in;

	/*
	 * static void mst() { Arrays.sort(ed); UnionFind uf=new UnionFind(n); for(int
	 * i=0;i<m;i++) { edge w=ed[i]; if(!uf.union(w.from, w.to)) continue;
	 * in[i]=true; } }
	 */
	static class edge implements Comparable<edge> {
		int from;
		int to;
		int number;

		edge(int f, int t, int n) {
			from = f;
			to = t;
			number = n;
		}

		public String toString() {
			return from + " " + to + " " + number;
		}

		public int compareTo(edge f) {
			return f.number - number;
		}
	}

	static long power(int i) {
		// if(i==0)
		// return 1;
		long a = 1;
		for (int k = 0; k < i; k++)
			a *= i;
		return a;
	}

	static void seive(int N) {
		si = new int[N];
		primes = new ArrayList<>();
		si[1] = 1;
		for (int i = 2; i < N; i++) {
			if (si[i] == 0) {
				si[i] = i;
				primes.add(i);
			}
			for (int j = 0; j < primes.size() && primes.get(j) <= si[i] && (i * primes.get(j)) < N; j++)
				si[primes.get(j) * i] = primes.get(j);

		}
	}

	static long fac(int n) {
		if (n == 0)
			return fac[n] = 1;
		if (n == 1)
			return fac[n] = 1;
		long ans = 1;
		for (int i = 1; i <= n; i++)
			fac[i] = ans = (i % mod * ans % mod) % mod;
		return ans % mod;
	}

	static long gcd(long a, long b) {

		if (b == 0)
			return a;
		return gcd(b, a % b);
	}

	static class unionfind {
		int[] p;
		int[] size;
		int []max;
        int num;
		unionfind(int n) {
			p = new int[n];
			size = new int[n];
             max=new int [n];
			for (int i = 0; i < n; i++) {
				p[i] = i;
				max[i]=i;
			}
			Arrays.fill(size, 1);
			num=0;
		}

		int findSet(int v) {
			if (v == p[v])
				return v;

			max[v]=Math.max(max[v], max[p[v]]);

			p[v] = findSet(p[v]);

			max[v]=Math.max(max[v], max[p[v]]);

			return p[v];
		}

		boolean sameSet(int a, int b) {
			a = findSet(a);
			b = findSet(b);
			if (a == b)
				return true;
			return false;
		}

		int max() {
			int max = 0;
			for (int i = 0; i < size.length; i++)
				if (size[i] > max)
					max = size[i];
			return max;
		}

		boolean combine(int a, int b) {
			a = findSet(a);
			b = findSet(b);
			if (a == b)
				return true;
			if (size[a] > size[b]) {
				p[b] = a;
				max[a]=Math.max(max[a], max[b]);
				size[a] += size[b];

			} else {
				p[a] = b;
				max[b]=Math.max(max[a], max[b]);
				size[b] += size[a];
			}
			return false;
		}
	}

	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream system) {
			br = new BufferedReader(new InputStreamReader(system));
		}

		public Scanner(String file) throws Exception {
			br = new BufferedReader(new FileReader(file));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public double nextDouble() throws IOException {
			return Double.parseDouble(next());
		}

		public char nextChar() throws IOException {
			return next().charAt(0);
		}

		public Long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public boolean ready() throws IOException {
			return br.ready();
		}

		public void waitForInput() throws InterruptedException {
			Thread.sleep(3000);
		}
	}
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.AbstractMap;
import java.util.TreeMap;
import java.io.BufferedWriter;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Say My Name
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        DHarmoniousGraph solver = new DHarmoniousGraph();
        solver.solve(1, in, out);
        out.close();
    }

    static class DHarmoniousGraph {
        public void solve(int testNumber, InputReader c, OutputWriter w) {
            int n = c.readInt(), m = c.readInt();
            UnionFind dsu = new UnionFind(n);
            for (int i = 0; i < m; i++) {
                int u = c.readInt() - 1, v = c.readInt() - 1;
                dsu.unify(u, v);
            }

            TreeMap<Integer, Integer> tm = new TreeMap<>();
            int res = 0;
            for (int i = 0; i < n; i++) {
                int y = dsu.find(i);
                if (!tm.containsKey(y)) {
                    if (!tm.isEmpty()) {
                        res++;
                    }
                    if (dsu.componentSize(y) > 1) {
                        tm.put(y, dsu.componentSize(y) - 1);
                    }
                } else {
                    if (tm.get(y) == 1) {
                        tm.remove(y);
                    } else {
                        tm.replace(y, tm.get(y) - 1);
                    }
                }
            }

            w.printLine(res);
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int readInt() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void close() {
            writer.close();
        }

        public void printLine(int i) {
            writer.println(i);
        }

    }

    static class UnionFind {
        private int size;
        private int[] sz;
        private int[] id;
        private int numComponents;

        public UnionFind(int size) {

            if (size <= 0) {
                throw new IllegalArgumentException("Size <= 0 is not allowed");
            }

            this.size = numComponents = size;
            sz = new int[size];
            id = new int[size];

            for (int i = 0; i < size; i++) {
                id[i] = i;
                sz[i] = 1;
            }
        }

        public int find(int p) {

            int root = p;
            while (root != id[root]) {
                root = id[root];
            }

            while (p != root) {
                int next = id[p];
                id[p] = root;
                p = next;
            }

            return root;
        }

        public int componentSize(int p) {
            return sz[find(p)];
        }

        public void unify(int p, int q) {

            int root1 = find(p);
            int root2 = find(q);

            if (root1 == root2) {
                return;
            }

            if (sz[root1] < sz[root2]) {
                sz[root2] += sz[root1];
                id[root1] = root2;
            } else {
                sz[root1] += sz[root2];
                id[root2] = root1;
            }
            numComponents--;
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.Collections;
import java.util.ArrayList;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Say My Name
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        DHarmoniousGraph solver = new DHarmoniousGraph();
        solver.solve(1, in, out);
        out.close();
    }

    static class DHarmoniousGraph {
        public void solve(int testNumber, InputReader c, OutputWriter w) {
            int n = c.readInt(), m = c.readInt();
            ArrayList<Integer>[] adj = new ArrayList[n];
            for (int i = 0; i < n; i++) {
                adj[i] = new ArrayList<>();
            }
            UnionFind dsu = new UnionFind(n);
            for (int i = 0; i < m; i++) {
                int u = c.readInt() - 1, v = c.readInt() - 1;
                dsu.unify(u, v);
            }

            int res = 0;
            for (int i = 0; i < n; i++) {
                adj[dsu.find(i)].add(i);
            }
            for (int i = 0; i < n; i++) {
                Collections.sort(adj[i]);
                int t = adj[i].size();
                for (int j = 1; j < t; j++) {
                    if (adj[i].get(j) != adj[i].get(0) + j) {
                        if (dsu.find(adj[i].get(0) + j) == dsu.find(adj[i].get(0))) {
                            continue;
                        }
                        res++;
                        int y = dsu.find(adj[i].get(0) + j);
                        for (int k : adj[y]) {
                            adj[i].add(k);
                            dsu.unify(k, adj[i].get(0));
                        }
                        adj[y] = new ArrayList<>();
                    }
                }
            }
            w.printLine(res);
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int readInt() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void close() {
            writer.close();
        }

        public void printLine(int i) {
            writer.println(i);
        }

    }

    static class UnionFind {
        private int size;
        private int[] sz;
        private int[] id;
        private int numComponents;

        public UnionFind(int size) {

            if (size <= 0) {
                throw new IllegalArgumentException("Size <= 0 is not allowed");
            }

            this.size = numComponents = size;
            sz = new int[size];
            id = new int[size];

            for (int i = 0; i < size; i++) {
                id[i] = i;
                sz[i] = 1;
            }
        }

        public int find(int p) {

            int root = p;
            while (root != id[root]) {
                root = id[root];
            }

            while (p != root) {
                int next = id[p];
                id[p] = root;
                p = next;
            }

            return root;
        }

        public void unify(int p, int q) {

            int root1 = find(p);
            int root2 = find(q);

            if (root1 == root2) {
                return;
            }

            if (sz[root1] < sz[root2]) {
                sz[root2] += sz[root1];
                id[root1] = root2;
            } else {
                sz[root1] += sz[root2];
                id[root2] = root1;
            }
            numComponents--;
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.Collections;
import java.util.ArrayList;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Say My Name
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        DHarmoniousGraph solver = new DHarmoniousGraph();
        solver.solve(1, in, out);
        out.close();
    }

    static class DHarmoniousGraph {
        public void solve(int testNumber, InputReader c, OutputWriter w) {
            int n = c.readInt(), m = c.readInt();
            ArrayList<Integer>[] adj = new ArrayList[n];
            for (int i = 0; i < n; i++) {
                adj[i] = new ArrayList<>();
            }
            UnionFind dsu = new UnionFind(n);
            for (int i = 0; i < m; i++) {
                int u = c.readInt() - 1, v = c.readInt() - 1;
                dsu.unify(u, v);
            }

            int res = 0;
            for (int i = 0; i < n; i++) {
                adj[dsu.find(i)].add(i);
            }
            for (int i = 0; i < n; i++) {
                Collections.sort(adj[i]);
                for (int j = 1; j < adj[i].size(); j++) {
                    if (adj[i].get(j) != adj[i].get(0) + j) {
                        if (dsu.find(adj[i].get(0) + j) == dsu.find(adj[i].get(0))) {
                            continue;
                        }
                        res++;
                        int y = dsu.find(adj[i].get(0) + j);
                        for (int k : adj[y]) {
                            adj[i].add(k);
                            dsu.unify(k, adj[i].get(0));
                        }
                        adj[y] = new ArrayList<>();
                    }
                }
            }
            w.printLine(res);
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int readInt() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void close() {
            writer.close();
        }

        public void printLine(int i) {
            writer.println(i);
        }

    }

    static class UnionFind {
        private int size;
        private int[] sz;
        private int[] id;
        private int numComponents;

        public UnionFind(int size) {

            if (size <= 0) {
                throw new IllegalArgumentException("Size <= 0 is not allowed");
            }

            this.size = numComponents = size;
            sz = new int[size];
            id = new int[size];

            for (int i = 0; i < size; i++) {
                id[i] = i;
                sz[i] = 1;
            }
        }

        public int find(int p) {

            int root = p;
            while (root != id[root]) {
                root = id[root];
            }

            while (p != root) {
                int next = id[p];
                id[p] = root;
                p = next;
            }

            return root;
        }

        public void unify(int p, int q) {

            int root1 = find(p);
            int root2 = find(q);

            if (root1 == root2) {
                return;
            }

            if (sz[root1] < sz[root2]) {
                sz[root2] += sz[root1];
                id[root1] = root2;
            } else {
                sz[root1] += sz[root2];
                id[root2] = root1;
            }
            numComponents--;
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.Collections;
import java.util.ArrayList;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Say My Name
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        DHarmoniousGraph solver = new DHarmoniousGraph();
        solver.solve(1, in, out);
        out.close();
    }

    static class DHarmoniousGraph {
        public void solve(int testNumber, InputReader c, OutputWriter w) {
            int n = c.readInt(), m = c.readInt();
            ArrayList<Integer>[] adj = new ArrayList[n];
            for (int i = 0; i < n; i++) {
                adj[i] = new ArrayList<>();
            }
            UnionFind dsu = new UnionFind(n);
            for (int i = 0; i < m; i++) {
                int u = c.readInt() - 1, v = c.readInt() - 1;
                dsu.unify(u, v);
            }

            int res = 0;
            for (int i = 0; i < n; i++) {
                adj[dsu.find(i)].add(i);
            }
            for (int i = 0; i < n; i++) {
                for (int j = 1; j < adj[i].size(); j++) {
                    Collections.sort(adj[i]);
                    if (adj[i].get(j) != adj[i].get(0) + j) {
                        if (dsu.find(adj[i].get(0) + j) == dsu.find(adj[i].get(0))) {
                            continue;
                        }
                        res++;
                        int y = dsu.find(adj[i].get(0) + j);
                        for (int k : adj[y]) {
                            adj[i].add(k);
                            dsu.unify(k, adj[i].get(0));
                        }
                        adj[y] = new ArrayList<>();
                    }
                }
            }
            w.printLine(res);
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int readInt() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void close() {
            writer.close();
        }

        public void printLine(int i) {
            writer.println(i);
        }

    }

    static class UnionFind {
        private int size;
        private int[] sz;
        private int[] id;
        private int numComponents;

        public UnionFind(int size) {

            if (size <= 0) {
                throw new IllegalArgumentException("Size <= 0 is not allowed");
            }

            this.size = numComponents = size;
            sz = new int[size];
            id = new int[size];

            for (int i = 0; i < size; i++) {
                id[i] = i;
                sz[i] = 1;
            }
        }

        public int find(int p) {

            int root = p;
            while (root != id[root]) {
                root = id[root];
            }

            while (p != root) {
                int next = id[p];
                id[p] = root;
                p = next;
            }

            return root;
        }

        public void unify(int p, int q) {

            int root1 = find(p);
            int root2 = find(q);

            if (root1 == root2) {
                return;
            }

            if (sz[root1] < sz[root2]) {
                sz[root2] += sz[root1];
                id[root1] = root2;
            } else {
                sz[root1] += sz[root2];
                id[root2] = root1;
            }
            numComponents--;
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.TreeSet;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Say My Name
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        DHarmoniousGraph solver = new DHarmoniousGraph();
        solver.solve(1, in, out);
        out.close();
    }

    static class DHarmoniousGraph {
        public void solve(int testNumber, InputReader c, OutputWriter w) {
            int n = c.readInt(), m = c.readInt();
            TreeSet<Integer>[] adj = new TreeSet[n];
            for (int i = 0; i < n; i++) {
                adj[i] = new TreeSet<>();
            }
            UnionFind dsu = new UnionFind(n);
            for (int i = 0; i < m; i++) {
                int u = c.readInt() - 1, v = c.readInt() - 1;
                dsu.unify(u, v);
            }

            int res = 0;
            for (int i = 0; i < n; i++) {
                adj[dsu.find(i)].add(i);
            }
            for (int i = 0; i < n; i++) {
                int first = 0;
                if (!adj[i].isEmpty()) {
                    first = adj[i].pollFirst();
                }
                while (!adj[i].isEmpty()) {
                    int s = adj[i].pollFirst();
                    if (s != first + 1) {
                        adj[i].add(s);
                        res++;
                        int y = dsu.find(first + 1);
                        for (int k : adj[y]) {
                            adj[i].add(k);
                            dsu.unify(k, first);
                        }
                        adj[y] = new TreeSet<>();
                    } else {
                        first = s;
                    }
                }
            }
            w.printLine(res);
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int readInt() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void close() {
            writer.close();
        }

        public void printLine(int i) {
            writer.println(i);
        }

    }

    static class UnionFind {
        private int size;
        private int[] sz;
        private int[] id;
        private int numComponents;

        public UnionFind(int size) {

            if (size <= 0) {
                throw new IllegalArgumentException("Size <= 0 is not allowed");
            }

            this.size = numComponents = size;
            sz = new int[size];
            id = new int[size];

            for (int i = 0; i < size; i++) {
                id[i] = i;
                sz[i] = 1;
            }
        }

        public int find(int p) {

            int root = p;
            while (root != id[root]) {
                root = id[root];
            }

            while (p != root) {
                int next = id[p];
                id[p] = root;
                p = next;
            }

            return root;
        }

        public void unify(int p, int q) {

            int root1 = find(p);
            int root2 = find(q);

            if (root1 == root2) {
                return;
            }

            if (sz[root1] < sz[root2]) {
                sz[root2] += sz[root1];
                id[root1] = root2;
            } else {
                sz[root1] += sz[root2];
                id[root2] = root1;
            }
            numComponents--;
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Objects;
import java.util.List;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.util.Comparator;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author anand.oza
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        DHarmoniousGraph solver = new DHarmoniousGraph();
        solver.solve(1, in, out);
        out.close();
    }

    static class DHarmoniousGraph {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt(), m = in.nextInt();

            UnionFind initial = new UnionFind(n);
            for (int i = 0; i < m; i++) {
                int a = in.nextInt() - 1;
                int b = in.nextInt() - 1;
                initial.union(a, b);
            }

            List<List<Integer>> components = new ArrayList<>();
            for (int i = 0; i < n; i++) {
                components.add(new ArrayList<>());
            }
            for (int i = 0; i < n; i++) {
                components.get(initial.rep(i)).add(i);
            }

            List<Pair<Integer, Integer>> intervals = new ArrayList<>();
            for (List<Integer> c : components) {
                if (c.size() <= 1)
                    continue;
                intervals.add(Pair.of(c.get(0), c.get(c.size() - 1)));
            }
            intervals.sort(Comparator.comparingInt(i -> i.first));

            int start = -1;
            int end = -1;
            int answer = 0;

            intervals.add(Pair.of(Integer.MAX_VALUE, Integer.MAX_VALUE));
            for (Pair<Integer, Integer> i : intervals) {
                if (i.first <= end) {
                    end = Math.max(end, i.first);
                } else {
                    if (start >= 0) {
                        HashSet<Integer> distinct = new HashSet<>();
                        for (int j = start; j <= end; j++) {
                            distinct.add(initial.rep(j));
                        }
                        answer += distinct.size() - 1;
                    }
                    start = i.first;
                    end = i.second;
                }
            }

            out.println(answer);
        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }

    static class UnionFind {
        private int[] __rep;
        private int[] __size;

        public UnionFind(int n) {
            __rep = new int[n];
            __size = new int[n];
            for (int i = 0; i < n; i++) {
                __rep[i] = i;
                __size[i] = 1;
            }
        }

        public int rep(int x) {
            if (__rep[x] == x) {
                return x;
            }

            int r = rep(__rep[x]);
            __rep[x] = r;
            return r;
        }

        public int size(int x) {
            return __size[rep(x)];
        }

        public boolean union(int x, int y) {
            x = rep(x);
            y = rep(y);

            if (x == y) {
                return false;
            }

            if (size(x) < size(y)) {
                int t = x;
                x = y;
                y = t;
            }

            // now size(x) >= size(y)

            __rep[y] = x;
            __size[x] += __size[y];
            return true;
        }

    }

    static class Pair<F, S> {
        public final F first;
        public final S second;

        public Pair(F first, S second) {
            this.first = first;
            this.second = second;
        }

        public static <F, S> Pair<F, S> of(F first, S second) {
            return new Pair<>(first, second);
        }

        public boolean equals(Object o) {
            if (this == o)
                return true;
            if (o == null || getClass() != o.getClass())
                return false;
            Pair<?, ?> pair = (Pair<?, ?>) o;
            return Objects.equals(first, pair.first) && Objects.equals(second, pair.second);
        }

        public int hashCode() {
            return Objects.hash(first, second);
        }

        public String toString() {
            return "(" + first + ", " + second + ')';
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Objects;
import java.util.List;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.util.Comparator;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author anand.oza
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        DHarmoniousGraph solver = new DHarmoniousGraph();
        solver.solve(1, in, out);
        out.close();
    }

    static class DHarmoniousGraph {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt(), m = in.nextInt();

            UnionFind initial = new UnionFind(n);
            for (int i = 0; i < m; i++) {
                int a = in.nextInt() - 1;
                int b = in.nextInt() - 1;
                initial.union(a, b);
            }

            List<List<Integer>> components = new ArrayList<>();
            for (int i = 0; i < n; i++) {
                components.add(new ArrayList<>());
            }
            for (int i = 0; i < n; i++) {
                components.get(initial.rep(i)).add(i);
            }

            List<Pair<Integer, Integer>> intervals = new ArrayList<>();
            for (List<Integer> c : components) {
                if (c.size() <= 1)
                    continue;
                intervals.add(Pair.of(c.get(0), c.get(c.size() - 1)));
            }
            intervals.sort(Comparator.comparingInt(i -> i.first));

            int start = -1;
            int end = -1;
            int answer = 0;

            intervals.add(Pair.of(Integer.MAX_VALUE, Integer.MAX_VALUE));
            for (Pair<Integer, Integer> i : intervals) {
                if (i.first <= end) {
                    end = Math.max(end, i.second);
                } else {
                    if (start >= 0) {
                        HashSet<Integer> distinct = new HashSet<>();
                        for (int j = start; j <= end; j++) {
                            distinct.add(initial.rep(j));
                        }
                        answer += distinct.size() - 1;
                    }
                    start = i.first;
                    end = i.second;
                }
            }

            out.println(answer);
        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }

    static class UnionFind {
        private int[] __rep;
        private int[] __size;

        public UnionFind(int n) {
            __rep = new int[n];
            __size = new int[n];
            for (int i = 0; i < n; i++) {
                __rep[i] = i;
                __size[i] = 1;
            }
        }

        public int rep(int x) {
            if (__rep[x] == x) {
                return x;
            }

            int r = rep(__rep[x]);
            __rep[x] = r;
            return r;
        }

        public int size(int x) {
            return __size[rep(x)];
        }

        public boolean union(int x, int y) {
            x = rep(x);
            y = rep(y);

            if (x == y) {
                return false;
            }

            if (size(x) < size(y)) {
                int t = x;
                x = y;
                y = t;
            }

            // now size(x) >= size(y)

            __rep[y] = x;
            __size[x] += __size[y];
            return true;
        }

    }

    static class Pair<F, S> {
        public final F first;
        public final S second;

        public Pair(F first, S second) {
            this.first = first;
            this.second = second;
        }

        public static <F, S> Pair<F, S> of(F first, S second) {
            return new Pair<>(first, second);
        }

        public boolean equals(Object o) {
            if (this == o)
                return true;
            if (o == null || getClass() != o.getClass())
                return false;
            Pair<?, ?> pair = (Pair<?, ?>) o;
            return Objects.equals(first, pair.first) && Objects.equals(second, pair.second);
        }

        public int hashCode() {
            return Objects.hash(first, second);
        }

        public String toString() {
            return "(" + first + ", " + second + ')';
        }

    }
}


//package Main;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Scanner;

public class Main {

	static int maxn = 1000010;
	static int[] mi = new int[maxn];
	static int[] mx = new int[maxn];
	static int[] pre = new int[maxn];
	static class Point implements Comparable<Point>{
		int mi,mx;
		public Point(){}
		public Point(int mi,int mx){
			this.mi=mi;
			this.mx=mx;
		}
		public int compareTo(Point a){
			if(this.mi-a.mi!=0) return this.mi-a.mi;
			return this.mx-a.mx;
		}
	};
	static Point[] p = new Point[maxn];
	public static int find(int x) {
		if(pre[x]==x) return x;
		return pre[x]=find(pre[x]);
	}
	public static void unite(int a,int b){
		int fx=find(a);
		int fy=find(b);
		if(fx!=fy) pre[fx]=fy;
	}
	public static void main(String[] args) {
		@SuppressWarnings("resource")
		Scanner input = new Scanner(System.in);
		int n = input.nextInt();
		int m = input.nextInt();
		for(int i=1;i<=n;i++){
			pre[i]=i;
			mi[i]=n+1;
			p[i]=new Point();
		}
		for(int i=1;i<=m;i++){
			int a=input.nextInt();
			int b=input.nextInt();
			unite(a,b);
		}
		for(int i=1;i<=n;i++){
			int fi=find(i);
			mi[fi]=Math.min(mi[fi],i);
			mx[fi]=Math.max(mx[fi],i);
		}
		int cnt=0;
		for(int i=1;i<=n;i++){
			if(pre[i]==i){
				cnt++;
				p[cnt].mi=mi[i];
				p[cnt].mx=mx[i];
			}
		}
		Arrays.sort(p,1,cnt+1);
		int fi=p[1].mi,fx=p[1].mx,ans=0;
		for(int i=2;i<=cnt;i++){
			if(p[i].mi<fx){
				ans++;
				fx=Math.max(fx,p[i].mx);
			}
			else{
				fi=p[i].mi;
				fx=p[i].mx;
			}
		}
		System.out.println(ans);
	}
}


//package Main;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Scanner;

public class Main {

	static int maxn = 1000010;
	static int[] mi = new int[maxn];
	static int[] mx = new int[maxn];
	static int[] pre = new int[maxn];
	static class Point{
		int mi,mx;
		public Point(){}
		public Point(int mi,int mx){
			this.mi=mi;
			this.mx=mx;
		}
		public int compareTo(Point a){
			if(this.mi-a.mi!=0) return this.mi-a.mi;
			return this.mx-a.mx;
		}
	};
	static Point[] p = new Point[maxn];
	public static int find(int x) {
		if(pre[x]==x) return x;
		return pre[x]=find(pre[x]);
	}
	public static void unite(int a,int b){
		int fx=find(a);
		int fy=find(b);
		if(fx!=fy) pre[fx]=fy;
	}
	public static void main(String[] args) {
		@SuppressWarnings("resource")
		Scanner input = new Scanner(System.in);
		int n = input.nextInt();
		int m = input.nextInt();
		for(int i=1;i<=n;i++){
			pre[i]=i;
			mi[i]=n+1;
			p[i]=new Point();
		}
		for(int i=1;i<=m;i++){
			int a=input.nextInt();
			int b=input.nextInt();
			unite(a,b);
		}
		for(int i=1;i<=n;i++){
			int fi=find(i);
			mi[fi]=Math.min(mi[fi],i);
			mx[fi]=Math.max(mx[fi],i);
		}
		int cnt=0;
		for(int i=1;i<=n;i++){
			if(pre[i]==i){
				cnt++;
				p[cnt].mi=mi[i];
				p[cnt].mx=mx[i];
			}
		}
		int fi=p[1].mi,fx=p[1].mx,ans=0;
		for(int i=2;i<=cnt;i++){
			if(p[i].mi<fx){
				ans++;
				fx=Math.max(fx,p[i].mx);
			}
			else{
				fi=p[i].mi;
				fx=p[i].mx;
			}
		}
		System.out.println(ans);
	}
}


/*
 * Remember a 6.72 student can know more than a 10.0 student.
 * Grades don't determine intelligence, they test obedience.
 * I Never Give Up.
 * I will become Candidate Master today.
 * I will defeat Saurabh Anand.
 * Skills are Cheap,Passion is Priceless.
 */
import java.util.*;
import java.util.Map.Entry;
import java.io.*;

import static java.lang.System.out;
import static java.util.Arrays.*;
import static java.lang.Math.*;

public class ContestMain{
	private static Reader in=new Reader();
	private static StringBuilder ans=new StringBuilder();
	private static long MOD=(long)1e9+7;
	private static final int N=(int) (1e6+7); // 1e5+7
    private static ArrayList<Integer> v[]=new ArrayList[N];
	private static boolean mark[]=new boolean[N];
//    private static BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
	private static long powmod(long x,long n){
		if(n==0||x==0)
			return 1;
		else if(n%2==0)
			return(powmod((x*x)%MOD,n/2));
		else
			return (x*(powmod((x*x)%MOD,(n-1)/2)))%MOD;
	}
	private static void shuffle(long[] arr){
		for(int i=arr.length-1;i>=2;i--){
			int x=new Random().nextInt(i-1);
			long temp=arr[x];
			arr[x]=arr[i];
			arr[i]=temp;
		}
	}
	private static void shuffle(int[] arr){
		for(int i=arr.length-1;i>=2;i--){
			int x=new Random().nextInt(i-1);
			int temp=arr[x];
			arr[x]=arr[i];
			arr[i]=temp;
		}
	}
    private static long gcd(long a, long b){
        if(b==0)return a;
        return gcd(b,a%b);
    }
//    private static boolean check(int x,int y){
//        if((x>=0&&x<n)&&(y>=0&&y<m)&&mat[x][y]!='X'&&!visited[x][y])return true;
//        return false;
//    }
    public static int mod(int n,int c){
    	if(n<0)return n%c+c;
    	return n%c;
    }
//    public static boolean setCheck(long num,int pos){
//    	int c=1;
//    	int len=0;
//    	while(c<=num){
//    		if(len==pos&&(num&c)>=1){
//    			return true;
//    		}
//    		len++;
//    		c<<=1;
//    	}
//    	return false;
//    }
//    public static void setBit(int bit[],long num){
//    	long c;
//    	for(int j=0;j<64;j++){
//    		c=1L<<j;
//			if((num&c)>=1){
//				bit[j]++;
//			}
//		}
//    }
    static int minNode=200000+7,maxNode=0;
    public static void dfs(int node){
    	if(node<minNode)minNode=node;
    	if(node>maxNode)maxNode=node;
    	mark[node]=true;
    	for(int a:v[node]){
    		if(!mark[a]){
    			dfs(a);
    		}
    	}
    }
	public static void main(String[] args) throws IOException{
		int n=in.nextInt();
		int m=in.nextInt();
		for(int i=0;i<=n;i++)
			v[i]=new ArrayList();
		int x,y;
		for(int i=0;i<m;i++){
			x=in.nextInt();
			y=in.nextInt();
			v[x].add(y);
			v[y].add(x);
		}
		ArrayList<Pair> sub=new ArrayList();
		for(int i=1;i<=n;i++){
			if(!mark[i]){
				minNode=200000+7;maxNode=0;
				dfs(i);
				sub.add(new Pair(minNode,maxNode));
			}
		}
		Collections.sort(sub);
		int res=0;
		for(int i=0;i<sub.size()-1;i++){
			if(sub.get(i).r>sub.get(i+1).l){
				res++;
				sub.get(i+1).r=max(sub.get(i).r,sub.get(i+1).r);
			}
		}
		pn(res);
	}
	static class Pair<T> implements Comparable<Pair>{
		int l;
		int r;
		Pair(){
			l=0;
			r=0;
		}
		Pair(int k,int v){
			l=k;
			r=v;
		}
		@Override
		public int compareTo(Pair o){
			if(l!=o.l)return (int)(l-o.l);
			return (int)(r-o.r);
		}
		// Fenwick tree question comparator
//        @Override
//        public int compareTo(Pair o) {
//            if(o.r!=r)return (int) (r-o.r);
//            else return (int)(l-o.l);
//        }
	}
	//Reader Class
	static class Reader{
		BufferedReader br;
		StringTokenizer st;
		public Reader(){br=new BufferedReader(new InputStreamReader(System.in));}
		String next(){
			while(st==null||!st.hasMoreElements()){
				try{st=new StringTokenizer(br.readLine());
				}catch(IOException e){e.printStackTrace();}
			}
			return st.nextToken();
		}
		int nextInt(){return Integer.parseInt(next());}
		long nextLong(){return Long.parseLong(next());}
		double nextDouble(){return Double.parseDouble(next());}
		String nextLine(){
			String str="";
			try{
				str=br.readLine();
			}catch(IOException e){
				e.printStackTrace();
			}
			return str;
		}
	}
	//Printer Methods
	static void pn(Object o){out.print(o);}
	static void pln(Object o){out.println(o);}
	static void pln(){out.println();}
	static void pf(String format,Object o){out.printf(format,o);}
	//Appenders
	static void app(Object o){ans.append(o);}
}


/*
 * Remember a 6.72 student can know more than a 10.0 student.
 * Grades don't determine intelligence, they test obedience.
 * I Never Give Up.
 * I will become Candidate Master today.
 * I will defeat Saurabh Anand.
 * Skills are Cheap,Passion is Priceless.
 */
import java.util.*;
import java.util.Map.Entry;
import java.io.*;

import static java.lang.System.out;
import static java.util.Arrays.*;
import static java.lang.Math.*;

public class ContestMain{
	private static Reader in=new Reader();
	private static StringBuilder ans=new StringBuilder();
	private static long MOD=(long)1e9+7;
	private static final int N=(int) (1e6+7); // 1e5+7
    private static ArrayList<Integer> v[]=new ArrayList[N];
	private static boolean mark[]=new boolean[N];
//    private static BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
	private static long powmod(long x,long n){
		if(n==0||x==0)
			return 1;
		else if(n%2==0)
			return(powmod((x*x)%MOD,n/2));
		else
			return (x*(powmod((x*x)%MOD,(n-1)/2)))%MOD;
	}
	private static void shuffle(long[] arr){
		for(int i=arr.length-1;i>=2;i--){
			int x=new Random().nextInt(i-1);
			long temp=arr[x];
			arr[x]=arr[i];
			arr[i]=temp;
		}
	}
	private static void shuffle(int[] arr){
		for(int i=arr.length-1;i>=2;i--){
			int x=new Random().nextInt(i-1);
			int temp=arr[x];
			arr[x]=arr[i];
			arr[i]=temp;
		}
	}
    private static long gcd(long a, long b){
        if(b==0)return a;
        return gcd(b,a%b);
    }
//    private static boolean check(int x,int y){
//        if((x>=0&&x<n)&&(y>=0&&y<m)&&mat[x][y]!='X'&&!visited[x][y])return true;
//        return false;
//    }
    public static int mod(int n,int c){
    	if(n<0)return n%c+c;
    	return n%c;
    }
//    public static boolean setCheck(long num,int pos){
//    	int c=1;
//    	int len=0;
//    	while(c<=num){
//    		if(len==pos&&(num&c)>=1){
//    			return true;
//    		}
//    		len++;
//    		c<<=1;
//    	}
//    	return false;
//    }
//    public static void setBit(int bit[],long num){
//    	long c;
//    	for(int j=0;j<64;j++){
//    		c=1L<<j;
//			if((num&c)>=1){
//				bit[j]++;
//			}
//		}
//    }
    static int minNode=200000+7,maxNode=0;
    public static void dfs(int node){
    	if(node<minNode)minNode=node;
    	if(node>maxNode)maxNode=node;
    	mark[node]=true;
    	for(int a:v[node]){
    		if(!mark[a]){
    			dfs(a);
    		}
    	}
    }
	public static void main(String[] args) throws IOException{
		int n=in.nextInt();
		int m=in.nextInt();
		for(int i=0;i<=n;i++)
			v[i]=new ArrayList();
		int x,y;
		for(int i=0;i<m;i++){
			x=in.nextInt();
			y=in.nextInt();
			v[x].add(y);
			v[y].add(x);
		}
		ArrayList<Pair> sub=new ArrayList();
		for(int i=1;i<=n;i++){
			if(!mark[i]){
				minNode=200000+7;maxNode=0;
				dfs(i);
				sub.add(new Pair(minNode,maxNode));
			}
		}
		Collections.sort(sub);
		int res=0;
		for(int i=0;i<sub.size()-1;i++){
			if(sub.get(i).r>sub.get(i+1).l)res++;
		}
		pn(res);
	}
	static class Pair<T> implements Comparable<Pair>{
		int l;
		int r;
		Pair(){
			l=0;
			r=0;
		}
		Pair(int k,int v){
			l=k;
			r=v;
		}
		@Override
		public int compareTo(Pair o){
			if(l!=o.l)return (int)(l-o.l);
			return (int)(r-o.r);
		}
		// Fenwick tree question comparator
//        @Override
//        public int compareTo(Pair o) {
//            if(o.r!=r)return (int) (r-o.r);
//            else return (int)(l-o.l);
//        }
	}
	//Reader Class
	static class Reader{
		BufferedReader br;
		StringTokenizer st;
		public Reader(){br=new BufferedReader(new InputStreamReader(System.in));}
		String next(){
			while(st==null||!st.hasMoreElements()){
				try{st=new StringTokenizer(br.readLine());
				}catch(IOException e){e.printStackTrace();}
			}
			return st.nextToken();
		}
		int nextInt(){return Integer.parseInt(next());}
		long nextLong(){return Long.parseLong(next());}
		double nextDouble(){return Double.parseDouble(next());}
		String nextLine(){
			String str="";
			try{
				str=br.readLine();
			}catch(IOException e){
				e.printStackTrace();
			}
			return str;
		}
	}
	//Printer Methods
	static void pn(Object o){out.print(o);}
	static void pln(Object o){out.println(o);}
	static void pln(){out.println();}
	static void pf(String format,Object o){out.printf(format,o);}
	//Appenders
	static void app(Object o){ans.append(o);}
}


/*
 * Remember a 6.72 student can know more than a 10.0 student.
 * Grades don't determine intelligence, they test obedience.
 * I Never Give Up.
 * I will become Candidate Master today.
 * I will defeat Saurabh Anand.
 * Skills are Cheap,Passion is Priceless.
 */
import java.util.*;
import java.util.Map.Entry;
import java.io.*;

import static java.lang.System.out;
import static java.util.Arrays.*;
import static java.lang.Math.*;

public class ContestMain{
	private static Reader in=new Reader();
	private static StringBuilder ans=new StringBuilder();
	private static long MOD=(long)1e9+7;
	private static final int N=(int) (1e6+7); // 1e5+7
    private static ArrayList<Integer> v[]=new ArrayList[N];
	private static boolean mark[]=new boolean[N];
//    private static BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
	private static long powmod(long x,long n){
		if(n==0||x==0)
			return 1;
		else if(n%2==0)
			return(powmod((x*x)%MOD,n/2));
		else
			return (x*(powmod((x*x)%MOD,(n-1)/2)))%MOD;
	}
	private static void shuffle(long[] arr){
		for(int i=arr.length-1;i>=2;i--){
			int x=new Random().nextInt(i-1);
			long temp=arr[x];
			arr[x]=arr[i];
			arr[i]=temp;
		}
	}
	private static void shuffle(int[] arr){
		for(int i=arr.length-1;i>=2;i--){
			int x=new Random().nextInt(i-1);
			int temp=arr[x];
			arr[x]=arr[i];
			arr[i]=temp;
		}
	}
    private static long gcd(long a, long b){
        if(b==0)return a;
        return gcd(b,a%b);
    }
//    private static boolean check(int x,int y){
//        if((x>=0&&x<n)&&(y>=0&&y<m)&&mat[x][y]!='X'&&!visited[x][y])return true;
//        return false;
//    }
    public static int mod(int n,int c){
    	if(n<0)return n%c+c;
    	return n%c;
    }
//    public static boolean setCheck(long num,int pos){
//    	int c=1;
//    	int len=0;
//    	while(c<=num){
//    		if(len==pos&&(num&c)>=1){
//    			return true;
//    		}
//    		len++;
//    		c<<=1;
//    	}
//    	return false;
//    }
//    public static void setBit(int bit[],long num){
//    	long c;
//    	for(int j=0;j<64;j++){
//    		c=1L<<j;
//			if((num&c)>=1){
//				bit[j]++;
//			}
//		}
//    }
    static int minNode=200000+7,maxNode=0;
    public static void dfs(int node){
    	if(node<minNode)minNode=node;
    	if(node>maxNode)maxNode=node;
    	mark[node]=true;
    	for(int a:v[node]){
    		if(!mark[a]){
    			dfs(a);
    		}
    	}
    }
	public static void main(String[] args) throws IOException{
		int n=in.nextInt();
		int m=in.nextInt();
		HashSet<Integer> set=new HashSet();
		for(int i=1;i<=n;i++){
			v[i]=new ArrayList();
			set.add(i);
		}
		int x,y;
		for(int i=0;i<m;i++){
			x=in.nextInt();
			y=in.nextInt();
			v[x].add(y);
			v[y].add(x);
			if(set.contains(x))set.remove(x);
			if(set.contains(y))set.remove(y);
		}
		ArrayList<Pair> sub=new ArrayList();
		for(int i=1;i<=n;i++){
			if(!mark[i]){
				minNode=200000+7;maxNode=0;
				dfs(i);
				sub.add(new Pair(minNode,maxNode));
			}
		}
		Collections.sort(sub);
		int res=0,ind=1;
		for(int i=0;i<sub.size()-1;i++){
			if(sub.get(i).r>sub.get(i+1).l){
				for(ind=ind;ind<=sub.get(i).r;ind++){
					if(set.contains(ind)){
						res++;
						set.remove(ind);
					}
				}
				res++;
			}
		}
		pn(res);
	}
	static class Pair<T> implements Comparable<Pair>{
		int l;
		int r;
		Pair(){
			l=0;
			r=0;
		}
		Pair(int k,int v){
			l=k;
			r=v;
		}
		@Override
		public int compareTo(Pair o){
			if(l!=o.l)return (int)(l-o.l);
			return (int)(r-o.r);
		}
		// Fenwick tree question comparator
//        @Override
//        public int compareTo(Pair o) {
//            if(o.r!=r)return (int) (r-o.r);
//            else return (int)(l-o.l);
//        }
	}
	//Reader Class
	static class Reader{
		BufferedReader br;
		StringTokenizer st;
		public Reader(){br=new BufferedReader(new InputStreamReader(System.in));}
		String next(){
			while(st==null||!st.hasMoreElements()){
				try{st=new StringTokenizer(br.readLine());
				}catch(IOException e){e.printStackTrace();}
			}
			return st.nextToken();
		}
		int nextInt(){return Integer.parseInt(next());}
		long nextLong(){return Long.parseLong(next());}
		double nextDouble(){return Double.parseDouble(next());}
		String nextLine(){
			String str="";
			try{
				str=br.readLine();
			}catch(IOException e){
				e.printStackTrace();
			}
			return str;
		}
	}
	//Printer Methods
	static void pn(Object o){out.print(o);}
	static void pln(Object o){out.println(o);}
	static void pln(){out.println();}
	static void pf(String format,Object o){out.printf(format,o);}
	//Appenders
	static void app(Object o){ans.append(o);}
}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.SortedSet;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * #
 *
 * @author pttrung
 */
public class D_Round_600_Div2 {
    public static long MOD = 1000000007;
    static int[][] dp;

    public static void main(String[] args) throws FileNotFoundException {
        // PrintWriter out = new PrintWriter(new FileOutputStream(new File(
        // "output.txt")));
        PrintWriter out = new PrintWriter(System.out);
        Scanner in = new Scanner();
        int n = in.nextInt();
        int m = in.nextInt();
        ArrayList<Integer>[] map = new ArrayList[n];
        for (int i = 0; i < n; i++) {
            map[i] = new ArrayList<>();
        }
        for (int i = 0; i < m; i++) {
            int u = in.nextInt() - 1;
            int v = in.nextInt() - 1;
            map[u].add(v);
            map[v].add(u);
        }
        ArrayList<Point> list = new ArrayList<>();
        boolean[] check = new boolean[n];
        for (int i = 0; i < n; i++) {
            if (check[i]) {
                continue;
            }
            LinkedList<Integer> q = new LinkedList<>();
            q.add(i);
            int min = i;
            int max = i;
            while (!q.isEmpty()) {
                int node = q.poll();
                max = Integer.max(max, node);
                for (int j : map[node]) {
                    if (check[j]) {
                        continue;
                    }
                    check[j] = true;
                    q.add(j);
                }
            }
            //System.out.println(min + " " + max);
            list.add(new Point(min, 0));
            list.add(new Point(max, 1));
        }
        Collections.sort(list);
        int count = 0;
        int comp = 0;
        int result = 0;
        for (Point p : list) {

            if (p.y == 0) {
                count++;
                comp++;
            } else {
                count--;
            }
            if (count == 0) {
                result += Integer.max(0, comp - 1);
                comp = 0;
            }
        }
        out.println(result);

        out.close();
    }

    static int cal(int st, char need, char[] data) {
        int result = -1;
        for (int i = st; i < data.length; i++) {
            if (data[i] == need) {
                data[i] = data[st];
                data[st] = need;
                result = i;
                break;
            }
        }

        return result;
    }

    public static int[] KMP(String val) {
        int i = 0;
        int j = -1;
        int[] result = new int[val.length() + 1];
        result[0] = -1;
        while (i < val.length()) {
            while (j >= 0 && val.charAt(j) != val.charAt(i)) {
                j = result[j];
            }
            j++;
            i++;
            result[i] = j;
        }
        return result;

    }

    public static boolean nextPer(int[] data) {
        int i = data.length - 1;
        while (i > 0 && data[i] < data[i - 1]) {
            i--;
        }
        if (i == 0) {
            return false;
        }
        int j = data.length - 1;
        while (data[j] < data[i - 1]) {
            j--;
        }
        int temp = data[i - 1];
        data[i - 1] = data[j];
        data[j] = temp;
        Arrays.sort(data, i, data.length);
        return true;
    }

    public static int digit(long n) {
        int result = 0;
        while (n > 0) {
            n /= 10;
            result++;
        }
        return result;
    }

    public static double dist(long a, long b, long x, long y) {
        double val = (b - a) * (b - a) + (x - y) * (x - y);
        val = Math.sqrt(val);
        double other = x * x + a * a;
        other = Math.sqrt(other);
        return val + other;

    }

    public static class Point implements Comparable<Point> {

        int x, y;

        public Point(int start, int end) {
            this.x = start;
            this.y = end;
        }

        @Override
        public int hashCode() {
            int hash = 5;
            hash = 47 * hash + this.x;
            hash = 47 * hash + this.y;
            return hash;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Point other = (Point) obj;
            if (this.x != other.x) {
                return false;
            }
            if (this.y != other.y) {
                return false;
            }
            return true;
        }

        @Override
        public int compareTo(Point o) {

            if (x != o.x) {
                return Integer.compare(x, o.x);
            }
            return Integer.compare(y, o.y);
        }
    }

    public static class FT {

        long[] data;

        FT(int n) {
            data = new long[n];
        }

        public void update(int index, long value) {
            while (index < data.length) {
                data[index] += value;
                index += (index & (-index));
            }
        }

        public long get(int index) {
            long result = 0;
            while (index > 0) {
                result += data[index];
                index -= (index & (-index));
            }
            return result;

        }
    }

    public static long gcd(long a, long b) {
        if (b == 0) {
            return a;
        }
        return gcd(b, a % b);
    }

    public static long pow(long a, int b) {
        if (b == 0) {
            return 1;
        }
        if (b == 1) {
            return a;
        }

        long val = pow(a, b / 2);
        if (b % 2 == 0) {
            return val * val;
        } else {
            return val * (val * a);

        }
    }

    static class Scanner {

        BufferedReader br;
        StringTokenizer st;

        public Scanner() throws FileNotFoundException {
            // System.setOut(new PrintStream(new BufferedOutputStream(System.out), true));
            br = new BufferedReader(new InputStreamReader(System.in));
            //  br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("input.txt"))));
        }

        public String next() {

            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (Exception e) {
                    throw new RuntimeException();
                }
            }
            return st.nextToken();
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }

        public String nextLine() {
            st = null;
            try {
                return br.readLine();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }

        public boolean endLine() {
            try {
                String next = br.readLine();
                while (next != null && next.trim().isEmpty()) {
                    next = br.readLine();
                }
                if (next == null) {
                    return true;
                }
                st = new StringTokenizer(next);
                return st.hasMoreTokens();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }
    }
}


import java.awt.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Abc {
    static ArrayList<Integer> adj[];
    static boolean vis[];
    static int l,r;
    public static void main(String[] args) throws IOException {
        FastReader sc = new FastReader();
        int n=sc.nextInt(),m=sc.nextInt();
        adj=new ArrayList[n];
        vis=new boolean[n];
        for (int i=0;i<n;i++)adj[i]=new ArrayList<>();
        for (int i=0;i<m;i++){
            int a=sc.nextInt()-1,b=sc.nextInt()-1;
            adj[a].add(b);adj[b].add(a);
        }
        int b=-1;boolean flag=false;int cnt=0;
        for (int i=0;i<n;i++){
            if (!vis[i]){
                l=Integer.MAX_VALUE;
                r=Integer.MIN_VALUE;
                dfs(i);
                if (flag){
                    if (l<=b)cnt++;
                }
                b=Math.max(r,b);
                flag=true;

            }
        }
        System.out.println(cnt);
    }
    static void dfs(int v){
        if (vis[v])return;
        vis[v]=true;
        l=Math.min(l,v);
        r=Math.max(r,v);
        for (int u:adj[v]){
            dfs(u);
        }
    }

    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        public FastReader() {
            br = new BufferedReader(new
                    InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
}


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
import java.util.StringTokenizer;
import java.util.*;
import java.io.*;
public class codeforces
{
   static class Student{
       int x,y;
        Student(int x,int y){
            this.x=x;
            this.y=y;
        }
    }
    /*static int prime[];
    static void sieveOfEratosthenes(int n)
    {
        // Create a boolean array "prime[0..n]" and initialize
        // all entries it as true. A value in prime[i] will
        // finally be false if i is Not a prime, else true.
        int pos=0;
        prime= new int[n+1];
        for(int p = 2; p*p <=n; p++)
        {
            // If prime[p] is not changed, then it is a prime
            if(prime[p] == 0)
            {
                // Update all multiples of p
                prime[p]=p;
                for(int i = p*p; i <= n; i += p)
                    prime[i] = p;
            }
        }
    }*/
static    class Sortbyroll implements Comparator<Student>
{
    // Used for sorting in ascending order of
    // roll number
    public int compare(Student c, Student b)
    {
        return c.x-b.x;
    }
}
    static class FastReader
    {
        BufferedReader br;
        StringTokenizer st;

        public FastReader()
        {
            br = new BufferedReader(new
                     InputStreamReader(System.in));
        }

        String next()
        {
            while (st == null || !st.hasMoreElements())
            {
                try
                {
                    st = new StringTokenizer(br.readLine());
                }
                catch (IOException  e)
                {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt()
        {
            return Integer.parseInt(next());
        }

        long nextLong()
        {
            return Long.parseLong(next());
        }

        double nextDouble()
        {
            return Double.parseDouble(next());
        }

        String nextLine()
        {
            String str = "";
            try
            {
                str = br.readLine();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            return str;
        }
    }
    static class Edge{
        int a,b;
        Edge(int a,int b){
            this.a=a;
            this.b=b;
        }
    }
    static int parent[];
    static int rank[];
    public static void main(String[] args){
        //long sum=0;
        FastReader sc=new FastReader();
        int n,m,min,max,ans=0,x,y,i,j;
        n=sc.nextInt();
        m=sc.nextInt();
        HashMap<Integer,Integer>map=new HashMap<>();
        ArrayList<ArrayList<Integer>>adj=new ArrayList<>();
        for(i=0;i<=n;i++)
            adj.add(new ArrayList<>());
        for(i=0;i<m;i++){
            x=sc.nextInt();
            y=sc.nextInt();
            adj.get(x).add(y);
            adj.get(y).add(x);
            map.put(x,1);
            map.put(y,1);
        }
        int bo[]=new int[n+1];
        ArrayList<Student>arr=new ArrayList<>();
        for(i=1;i<=n;i++){
            if(bo[i]==0&&map.containsKey(i)){
                Queue<Integer>q=new LinkedList<>();
                min=Integer.MAX_VALUE;
                max=Integer.MIN_VALUE;
                q.add(i);
                bo[i]=1;
                while(!q.isEmpty()){
                    min=Math.min(min,q.peek());
                    max=Math.max(max,q.peek());
                    for(j=0;j<adj.get(q.peek()).size();j++){
                        if(bo[adj.get(q.peek()).get(j)]==0){
                            q.add(adj.get(q.peek()).get(j));
                            bo[adj.get(q.peek()).get(j)]=1;
                        }
                    }
                    q.poll();
                }
                arr.add(new Student(min,max));
            }
        }
        Collections.sort(arr,new Sortbyroll());
        Stack<Student>s=new Stack<>();
        s.push(arr.get(0));
        Student temp;
        for(i=1;i<arr.size();i++){
            if(s.peek().y>arr.get(i).x){
                temp=s.pop();
                s.push(new Student(temp.x,s.peek().y));
                ++ans;
            }
            else{
                s.push(new Student(arr.get(i).x,arr.get(i).y));
            }
        }
        while(!s.isEmpty()){
            for(i=s.peek().x;i<=s.peek().y;i++){
                if(!map.containsKey(i))
                    ++ans;
            }
            //System.out.println(s.peek().x+" "+s.peek().y);
            s.pop();
        }
        System.out.println(ans);
    }
 /*static long power(long x, long y, long p)
{
    long res = 1;      // Initialize result

    x = x % p;  // Update x if it is more than or
                // equal to p

    while (y > 0)
    {
        // If y is odd, multiply x with result
        if ((y & (long)1)%2!=0)
            res = (res*x) % p;

        // y must be even now
        y = y>>1; // y = y/2
        x = (x*x) % p;
    }
    return res%p;
} */
   static int find(int x)
    {
        // Finds the representative of the set
        // that x is an element of
        while(parent[x]!=x)
        {
            // if x is not the parent of itself
            // Then x is not the representative of
            // his set,
            x=parent[x];

            // so we recursively call Find on its parent
            // and move i's node directly under the
            // representative of this set
        }

        return x;
    }
    static void union(int x, int y)
    {
        // Find representatives of two sets
        int xRoot = find(x), yRoot = find(y);

        // Elements are in the same set, no need
        // to unite anything.
        if (xRoot == yRoot)
            return;

         // If x's rank is less than y's rank
        if (rank[xRoot] < rank[yRoot])

            // Then move x under y  so that depth
            // of tree remains less
            parent[xRoot] = yRoot;

        // Else if y's rank is less than x's rank
        else if (rank[yRoot] < rank[xRoot])

            // Then move y under x so that depth of
            // tree remains less
            parent[yRoot] = xRoot;

        else // if ranks are the same
        {
            // Then move y under x (doesn't matter
            // which one goes where)
            parent[yRoot] = xRoot;

            // And increment the the result tree's
            // rank by 1
            rank[xRoot] = rank[xRoot] + 1;
        }
    }
    static long gcd(long a, long b)
    {
        if (a == 0)
            return b;
        return gcd(b % a, a);
    }
}