/**************************************************************** 
 * Description: 
主要思路总结：
离散化：通过将区间的左右端点离散化来减少后续处理的复杂度。
区间排序：根据区间的长度进行排序，以便于在滑动窗口中优先选择较短的区间。
线段树：使用线段树来维护区间的状态，确保能够快速查询和更新当前选中的区间数目。
双指针滑动窗口：通过双指针 l 和 r 来表示当前的区间范围，动态调整选择的区间数量，并在满足条件时计算花费。
复杂度分析：
这段代码的时间复杂度主要取决于排序（O(n log n)）和线段树的操作，因此总体复杂度为 O(n log n)。
 * Author: Alex Li
 * Date: 2024-08-12 13:13:24
 * LastEditTime: 2024-08-12 13:38:41
****************************************************************/
#include <iostream>
#include <algorithm>
#define mid (l+r>>1)  // 中间点，用于线段树的区间分割
using namespace std;

int n, m, ans = 2100000000;  // n为区间个数，m为需要选择的区间数量，ans用于存储最小花费
int l, r, ad[4000001], ma[4000001], p[4000001];
struct qj {
    int l, r;  // 表示区间的左右端点
} a[500001];

bool operator<(qj a, qj b) {
    return (a.r - a.l) < (b.r - b.l);  // 定义区间的比较方式，按照区间长度从小到大排序
}

inline int sum(int l, int r) {
    return p[a[r].r] - p[a[r].l] - p[a[l].r] + p[a[l].l];
    // 计算区间 [l, r] 中区间的长度差值，确保该区间的花费
}

void add(int now, int l, int r, int x, int y, int z) {
    if (l == x && r == y) {
        ad[now] += z;  // 懒标记更新
        ma[now] += z;  // 最大值更新
        return;
    }
    if (x <= mid) add(now * 2, l, mid, x, min(mid, y), z);
    if (y > mid) add(now * 2 + 1, mid + 1, r, max(x, mid + 1), y, z);
    ma[now] = max(ma[now * 2], ma[now * 2 + 1]) + ad[now];
    // 递归更新线段树，维护区间的最大值
}

int main() {
    cin >> n >> m;  // 读取n和m的值
    for (int i = 1; i <= n; i++) {
        cin >> a[i].l >> a[i].r;  // 读取每个区间的左右端点
        p[i * 2 - 1] = a[i].l;  // 将左端点存入数组p
        p[i * 2] = a[i].r;  // 将右端点存入数组p
    }

    int N = 2 * n;  // 端点的总数
    sort(p + 1, p + N + 1);  // 对端点进行排序
    N = unique(p + 1, p + N + 1) - p - 1;  // 对端点去重并计算有效端点数

    sort(a + 1, a + n + 1);  // 按区间长度对区间进行排序

    for (int i = 1; i <= n; i++) {
        // 将区间的左右端点离散化为索引值
        a[i].l = lower_bound(p + 1, p + N + 1, a[i].l) - p;
        a[i].r = lower_bound(p + 1, p + N + 1, a[i].r) - p;
    }

    for (l = 1, r = 0; l <= n; add(1, 1, N, a[l].l, a[l].r, -1), l++) {
        // 初始化左指针l，从1开始，右指针r初始化为0
        // 线段树的add函数负责动态维护当前区间选择状态

        while (r < n && ma[1] < m) {
            ++r;
            add(1, 1, N, a[r].l, a[r].r, 1);
        }
        // 移动右指针r，直到线段树根节点ma[1]的值达到m，表示选择了m个区间

        if (r == n && ma[1] < m) break;
        // 如果遍历完所有区间仍然无法满足选择m个区间的条件，则退出循环

        ans = min(ans, sum(l, r));
        // 更新最小花费，选取左右指针所包含区间的花费最小值
    }

    cout << ((ans == 2100000000) ? -1 : ans) << endl;
    // 输出结果，如果没有找到合法方案，输出-1，否则输出最小花费

    return 0;

    
}
