Problem:
Score : 300 points

Problem Statement

We have N ID cards, and there are M gates.

We can pass the i-th gate if we have one of the following ID cards: the L_i-th, (L_i+1)-th, ..., and R_i-th ID cards.

How many of the ID cards allow us to pass all the gates alone?

Constraints

All values in input are integers.

1 \leq N \leq 10^5

1 \leq M \leq 10^5

1 \leq L_i \leq R_i \leq N

Input

Input is given from Standard Input in the following format:

N M
L_1 R_1
L_2 R_2
\vdots
L_M R_M

Output

Print the number of ID cards that allow us to pass all the gates alone.

Sample Input 1

4 2
1 3
2 4

Sample Output 1

2

Two ID cards allow us to pass all the gates alone, as follows:

The first ID card does not allow us to pass the second gate.

The second ID card allows us to pass all the gates.

The third ID card allows us to pass all the gates.

The fourth ID card does not allow us to pass the first gate.

Sample Input 2

10 3
3 6
5 7
6 9

Sample Output 2

1

Sample Input 3

100000 1
1 100000

Sample Output 3

100000

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Numerics;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace debug
{
    class main
    {
        static void Main(string[] args)
        {
            //問題クラスを展開
            ProgramC a = new ProgramC();
            a.main();//実行する

        }

    }

    class ProgramA
    {
        public void main()
        {
            string[] n = Console.ReadLine().Split(' ');
            string s = Console.ReadLine();

            //
            int num = int.Parse(n[1]) - 1;
            for (int i = 0; i < int.Parse(n[0]); i++)
            {
                int temp = s[i];
                if (i == num)
                {
                    temp += 32;
                    Console.Write((char)temp);
                }
                else
                {
                    Console.Write((char)temp);
                }
            }

        }
    }

    class ProgramB
    {
        public void main()
        {
            //入力
            string s = Console.ReadLine();

            //
            int flag1 = 0;
            int flag2 = 0;

            int y = (s[0] - '0') * 10 + (s[1] - '0');
            int m = (s[2] - '0') * 10 + (s[3] - '0');

            if (0 < y && y < 13)
                flag1 = 1;
            if (0 < m && m < 13)
                flag2 = 1;

            if (flag1 == 1 && flag2 == 1)
            {
                Console.WriteLine("AMBIGUOUS");
                return;
            }

            if (flag1 == 1 && flag2 == 0)
            {
                Console.WriteLine("MMYY");
                return;
            }

            if (flag1 == 0 && flag2 == 1)
            {
                Console.WriteLine("YYMM");
                return;
            }

            Console.WriteLine("NA");
            return;

        }
    }

    class ProgramC
    {
        public void main()
        {
            //入力
            string[] s = Console.ReadLine().Split(' ');
            int n = int.Parse(s[0]);
            int m = int.Parse(s[1]);

            //
            int R = 1;
            int L = n;
            for (int i = 0; i < m;i++)
            {
                string[] t = Console.ReadLine().Split(' ');
                R = Math.Max(R, int.Parse(t[0]));
                L = Math.Min(L, int.Parse(t[1]));

            }

            Console.WriteLine(Math.Max(L - R +1, 0));
        }



    }
    
    class ProgramD
    {
        public void main()
        {
            //入力
            string[] s = Console.ReadLine().Split(' ');
            int n = int.Parse(s[0]);
            int m = int.Parse(s[1]);

            string[] a = Console.ReadLine().Split(' ');

            PriorityQueue<int> q = new PriorityQueue<int>(n, false);
            List<Task> list = new List<Task>();

            for (int i = 0; i < n; i++)
                q.Enqueue(int.Parse(a[i]));

            for (int i = 0; i < m; i++)
            {
                string[] s1 = Console.ReadLine().Split(' ');
                list.Add(new Task(int.Parse(s1[0]), int.Parse(s1[1])));
            }

            var sort = list.OrderByDescending(x => x.b);
            int flag = 0;

            //お題を入れる
            foreach(var w in sort)
            {
                for(int j = 0;j < w.a;j++)
                {
                    int t = q.Dequeue();
                    if (t < w.b)
                        q.Enqueue(w.b);
                    else
                    {
                        q.Enqueue(t);
                        flag = 1;
                        break;
                    }
                }

                if (flag == 1)
                    break;
            }

            long ans = 0;
            //最後までやったあまり5を出す
            for (int i = 0; i < n; i++)
                ans += q.Dequeue();


            Console.WriteLine(ans);

        }
    }

    class Task
    {
        public int a;
        public int b;
        public Task(int a, int b)
        {
            this.a = a;
            this.b = b;
        }
    }
    /*優先度付きキュー*/
    class PriorityQueue<T> where T : IComparable<T>
    {
        public readonly T[] Array;
        public readonly bool Greater;
        public int Count { get; private set; } = 0;


        public PriorityQueue(int capacity, bool greater)
        {
            this.Array = new T[capacity];
            this.Greater = greater;
        }

        //キューを追加
        public void Enqueue(T item)
        {
            this.Array[this.Count] = item;
            this.Count += 1;//数を足す
            this.UpHeap();　//最後尾に追加したところを移動させる
        }

        public T Dequeue()
        {
            // 先頭要素を末尾にして再構成
            this.Swap(0, this.Count - 1);
            this.Count -= 1;
            this.DownHeap();

            return this.Array[this.Count];
        }

        //親と比較して入れ替えていく
        private void UpHeap()
        {
            var n = this.Count - 1;
            while (n != 0)
            {
                // 親要素の座標
                var parent = (n - 1) / 2;

                //もし親の方がちいさいなら、交換する。
                if (this.Compare(this.Array[n], this.Array[parent]) > 0)
                {
                    this.Swap(n, parent);
                    n = parent;
                }
                else
                {
                    break;
                }
            }
        }

        //子と比較して入れ替えていく
        private void DownHeap()
        {
            var parent = 0;
            while (true)//無限ループ
            {
                var child = 2 * parent + 1;
                //子供がいないなら終わり
                if (child > this.Count - 1) break;

                //子供は2つあるので大きい方を対象にする
                if (child < this.Count - 1 && this.Compare(this.Array[child], this.Array[child + 1]) < 0)
                {
                    // 左より右の子のほうが大きい値の場合、右を入れ替え対象にする
                    child += 1;
                }

                //親と子を比較して子が大きいなら入れ替える。そうでないなら成立なのでおしまい。
                if (this.Compare(this.Array[parent], this.Array[child]) < 0)
                {
                    this.Swap(parent, child);
                    parent = child;
                }
                else
                {
                    break;
                }
            }
        }

        //aとbを比較する
        private int Compare(T a, T b)
        {
            var c = a.CompareTo(b);//a-b、正のときはaが大きく、負のときはbが大きい（任意もので処理できる）
            if (!this.Greater)
            {
                c = -c;
            }
            return c;
        }

        //aとbを入れ替える
        private void Swap(int a, int b)
        {
            var tmp = this.Array[a];
            this.Array[a] = this.Array[b];
            this.Array[b] = tmp;
        }
    }

    class ProgramE
    {
        static void main()
        {

            //入力
            string[] t = Console.ReadLine().Split(' ');
            int n = int.Parse(t[0]);
            int k = int.Parse(t[1]);

            int[] ans = new int[n];
            int count = 0;


            UnionFind tree = new UnionFind();//UnionFindクラスを設定
            tree.par = new int[n];
            tree.temp = new int[n];
            tree.reset(n);

            //木でくっつける
            for (int i = 0; i < k; i++)
            {
                string[] s = Console.ReadLine().Split(' ');
                int u = int.Parse(s[0]);
                int v = int.Parse(s[1]);
                int w = int.Parse(s[2]);
                tree.unite(u - 1, v - 1);
            }

            //それぞれの要素数ごとに数を分類
            for (int i = 0; i < n; i++)
                ans[tree.size(i) - 1]++;

            //要素数がiのものがある分を(i+1)で割れば、分類した木の数が出る
            for (int i = 0; i < n; i++)
                count += ans[i] / (i + 1);


            Console.WriteLine(count);
            return;

        }
    }

    /*UnionFind法のクラス*/
    class UnionFind
    {

        public int[] par;
        public int[] temp;


        //マイナスは根を示す。
        public void reset(int n)
        {
            for (int i = 0; i < n; i++)
                par[i] = -1;
        }

        //マイナスならそれはまだ属していないので根である。そうでないならさかのぼる
        public int root(int x)
        {
            if (par[x] < 0)
                return x;
            else
                return root(par[x]);
        }

        //根の併合を行い、根には要素数を足す（マイナスの値）
        public void unite(int x, int y)
        { // xとyの木を併合
            int rx = root(x); //xの根をrx
            int ry = root(y); //yの根をry
            if (rx == ry)
                return; //xとyの根が同じ(=同じ木にある)時はそのまま
            if (par[ry] > par[rx])
            {
                int temp = ry;
                ry = rx;
                rx = temp;
            }
            par[ry] += par[rx];
            par[rx] = ry; //xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
        }

        // 2つのデータx, yが属する木が同じならtrueを返す
        public bool same(int x, int y)
        {
            int rx = root(x);
            int ry = root(y);
            return rx == ry;
        }

        //根の元に入っている
        public int size(int x)
        {
            return -par[root(x)];
        }
    }


 

}