// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

#pragma GCC optimize("Ofast")

typedef long long lint;

typedef unsigned int uint;

typedef pair<int, int> pii;

typedef pair<lint, lint> pll;

typedef unsigned long long ulint;

#define endl '\n'

#define fst first

#define sed second

#define pb push_back

#define mp make_pair

#define rint register int

#define newline putchar('\n')

#define leave_space putchar(' ')

#define all(x) (x).begin(), (x).end()

#define reveal(x) cerr << #x << " = " << (x) << endl

#define rep(it, f, e) for (rint it = (f); it <= (e); ++it)

#define per(it, f, e) for (rint it = (f); it >= (e); --it)

const lint INF = 1e18;

const int MAXN = 1e5 + 5;

int a[MAXN], b[MAXN], n, k;

struct Segment_tree {

	#define lson tree[root].ls

	#define rson tree[root].rs

	#define stdl (tree[root].sl)

	#define stdr (tree[root].sr)

	#define mid ((stdl + stdr) >> 1)

	struct Node {

		int sl, sr, ls, rs;

		lint val, rval, cover;

		Node () : ls(-1), rs(-1), cover(-1) {} 

	};

	vector<Node> tree;

	inline int new_Node(int l, int r) {

		static int root = 0;

		tree.pb(Node());

		stdl = l, stdr = r;

		tree[root].val = 0;

		tree[root].rval = l;

		return root++;

	}

	inline void update(int root) {

		if (~tree[root].cover) {

			tree[root].val = tree[root].cover;

			tree[root].rval = stdl + tree[root].cover;

		} else {

			tree[root].val = min(tree[lson].val, tree[rson].val);

			tree[root].rval = min(tree[lson].rval, tree[rson].rval);

		}

	}

	inline void pushdown(int root) {

		int L = lson, R = rson;

		if (lson == -1) L = new_Node(stdl, mid);

		if (rson == -1) R = new_Node(mid + 1, stdr);

		lson = L, rson = R;

		/*

			lson = new_Node(stdl, mid); ? RE

		*/

		if (~tree[root].cover) {

			tree[lson].cover = tree[rson].cover = tree[root].cover;

			update(lson), update(rson), tree[root].cover = -1;

		}

	}

	inline void replace(int root, int l, int r, lint p) {

		if (l <= stdl && stdr <= r) {

			tree[root].cover = p;

			update(root);

			return;

		}

		pushdown(root);

		if (l <= mid) replace(lson, l, r, p);

		if (r >= mid + 1) replace(rson, l, r, p);

		update(root);

	}

	inline lint query(int root, int l, int r) {

		if (l <= stdl && stdr <= r) {

			return tree[root].rval;

		}

		pushdown(root);

		lint ret = INF;

		if (l <= mid) ret = min(ret, query(lson, l, r));

		if (r >= mid + 1) ret = min(ret, query(rson, l, r));

		return ret;

	}

	#undef lson

	#undef rson

	#undef stdl

	#undef stdr

	#undef mid

	/*lint tree[10086];

	inline void new_Node(int l, int r) {

		rep (i, l, r) {

			tree[i] = i;

		}

	}

	inline void replace(int root, int l, int r, lint p) {

		rep (i, l, r) { tree[i] = i + p; }

	}

	inline lint query(int root, int l, int r) {

		lint ret = INF;

		rep (i, l, r) { ret = min(ret, tree[i]); }

		return ret;

	}

	inline lint query2(int root, int l, int r) {

		lint ret = INF;

		rep (i, l, r) { ret = min(ret, tree[i] - i); }

		return ret;

	}*/

}	Tree;

inline lint getquery(lint T) {

	return min(Tree.query(0, 0, T) + k - T, Tree.query(0, T, k - 1) - T);

}

int main() {

	ios::sync_with_stdio(false);

	cin.tie(NULL), cout.tie(NULL);

	cin >> n >> k;

	Tree.new_Node(0, k - 1);

	lint ans = 0, res, T = 0;

	rep (i, 1, n) {

		cin >> a[i] >> b[i];

		ans += (a[i] <<= 1);

	}

	rep (i, 1, n) {

		if (b[i] == 1) {

			if (a[i] > k) {

				puts("-1"); return 0;

			}

			lint l = (T + 1) % k;

			lint r = (T + a[i] - 1) % k;

			lint val = getquery(T);

			if (l > r) {

				Tree.replace(0, 0, r, INF);

				Tree.replace(0, l, k - 1, INF);

			} else {

				Tree.replace(0, l, r, INF);

			}

			Tree.replace(0, T, T, val);

			T = (T + a[i]) % k;

		} else {

			T = (T + a[i]) % k;

			Tree.replace(0, T, T, getquery(T));

		}

	}

	res = Tree.tree[0].val;

	cout << (res < INF ? res + ans : -1) << endl;

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.0966517865409935x):
#include<bits/stdc++.h>

using namespace std;

//14719021122270100109

typedef long long ll;

typedef pair<int,int> pi;

typedef vector<int> vi;

typedef unsigned long long ull;

typedef long double ldb;



#define f first

#define s second

#define all(x) (x).begin(), (x).end()

#define pb push_back

#define mp make_pair

#define forn(i, n) for(register int i=0; i<n; i++)

#define Forn(i, n) for(register int i=1; i<=n; i++)

#define foreach(it, a) for(__typeof((a).begin()) it=(a).begin(); it!=(a).end(); it++)

#define Foreach(it, a) for(__typeof((a).rbegin()) it=(a).rbegin(); it!=(a).rend(); it++)

#define mid l+r>>1

#define lid (id<<1|1)

#define rid ((id<<1)+2)

#define lson lid, l, mid

#define rson rid, mid, r



inline int in()

{

    char c=getchar();

    int neg=1, x=0;

    while(!isdigit(c)) (c=='-')?neg=-1, c=getchar():c=getchar();

    while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48), c=getchar();

    return neg*x;

}

inline int lcm(int a, int b){return a*b/__gcd(a, b);}



const int MAX_T=(8e5+5);

const int MAX=1e5+5;



map<ll,int> MP;

int N, ptr, a[MAX], tp[MAX];

ll K, A[MAX], dp[MAX], L[MAX], R[MAX];



inline void re()

{

    puts("-1");

    exit(0);

}



class Seg_Tree

{

    private:

    int dat[MAX_T];

    inline void pushdown(int id)

    {

        if(!dat[id]) return;

        dat[lid]=dat[rid]=dat[id];

        dat[id]=0;

    }

    public:

    inline int get(int id, int l, int r, int a, int b)

    {

        if(r<=a||b<=l) return 0;

//        cout<<l<<" "<<r<<" "<<p<<"<< "<<dat[id]<<endl;

        if(a<=l&&r<=b) return dat[id];

        pushdown(id);

        return max(get(lson, a, b), get(rson, a, b));

    }

    inline void update(int id, int l, int r, int a, int b, int v)

    {

        if(r<=a||b<=l) return;

        if(a<=l&&r<=b)

        {

//            cout<<l<<" "<<r<<" "<<v<<"EE"<<endl;

            dat[id]=v;

            return;

        }

        pushdown(id);

        update(lson, a, b, v);

        update(rson, a, b, v);

    }

}S;



inline ll query(int x, ll v)

{

    int id=S.get(0, 0, ptr, x, x+1);

//    cout<<" "<<x<<" "<<id<<endl;

    if(!id) return 0;

//    cout<<"id="<<id<<endl;

//    cout<<dp[id]<<" "<<L[id]<<" "<<v<<endl;

//    cout<<"dp"<<dp[id]<<" "<<L[id]<<" "<<L[x]<<endl;

    return (dp[id]+(L[id]-v+K)%K);

}



int main()

{

    N=in(), K=in();

    Forn(i, N)

    {

        a[i]=in(), tp[i]=in()-1;

        A[i]=A[i-1]+a[i];

        if(tp[i]) continue;

        if(a[i]*2>K) re();

    }

    Forn(i, N)

    {

        if(!tp[i])

        {

            L[i]=(-2ll*A[i-1]%K+K)%K;

            R[i]=(-2ll*A[i]%K+K)%K;

        }

        else L[i]=0, R[i]=K-1;

        MP[L[i]]=0, MP[R[i]]=0;

    }

    foreach(it, MP) it->s=ptr++;

    

    for(int i=N; i>0; i--)

    {

        int l=MP[L[i]], r=MP[R[i]];

        dp[i]=query(l, L[i]);

//    cout<<":)"<<endl;

        if(l>r) S.update(0, 0, ptr, r+1, l, i);

        else    S.update(0, 0, ptr, 0, l, i), S.update(0, 0, ptr, r+1, ptr, i);

//        cout<<i<<" "<<dp[i]<<" m "<<l<<" "<<r<<" "<<L[i]<<" "<<R[i]<<endl;

//        cout<<i<<" "<<dp[i]<<endl;

    }

    ll ret=dp[1];

    foreach(it, MP) ret=min(ret, query(it->s, it->f));

    cout<<ret+A[N]*2ll<<endl;

    return 0;

}