// 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.117928954878489x):
#include<bits/stdc++.h>

using namespace std;



typedef long long ll;

const int N=3e5+10;

int n,K,cnt;

int a[N],b[N],c[N<<1],l[N],r[N];

ll ans,s[N],f[N];



int read()

{

	int ret=0;char c=getchar();

	while(!isdigit(c)) c=getchar();

	while(isdigit(c)) ret=ret*10+(c^48),c=getchar();

	return ret;

}



struct Segment

{

#define ls (x<<1)

#define rs (x<<1|1)

	int col[N<<2],tar[N<<2];

	void pushdown(int x)

	{

		if(!tar[x]) return;

		col[ls]=col[rs]=tar[ls]=tar[rs]=tar[x];tar[x]=0;

	}

	void update(int x,int l,int r,int L,int R,int v)

	{

		if(L>R) return;

		if(L<=l && r<=R){col[x]=tar[x]=v;return;}

		pushdown(x);

		int mid=(l+r)>>1;

		if(L<=mid) update(ls,l,mid,L,R,v);

		if(R>mid) update(rs,mid+1,r,L,R,v);

	}

	int querycol(int x,int l,int r,int p)

	{

		if(l==r) return col[x];

		pushdown(x);

		int mid=(l+r)>>1;

		if(p<=mid) return querycol(ls,l,mid,p);

		else return querycol(rs,mid+1,r,p);

	}

	ll query(int x)

	{

		int pos=querycol(1,1,cnt,x);

		return pos?f[pos]+(c[l[pos]]-c[x]+K)%K:0;

	}

#undef ls

#undef rs

}tr;



int main()

{

#ifdef Durant_Lee

	freopen("AGC011F.in","r",stdin);

	freopen("AGC011F.out","w",stdout);

#endif

	n=read();K=read();

	for(int i=1;i<=n;++i)

	{

		a[i]=read();b[i]=read();s[i]=s[i-1]+a[i];

		if(b[i]&1) l[i]=(K-s[i-1]*2%K)%K,r[i]=(K-s[i]*2%K)%K;

		else l[i]=0,r[i]=K-1;

		if(b[i]&1 && a[i]*2>K){puts("-1");return 0;}

		c[++cnt]=l[i];c[++cnt]=r[i];

	}

	sort(c+1,c+cnt+1);cnt=unique(c+1,c+cnt+1)-c-1;

	for(int i=1;i<=n;++i) l[i]=lower_bound(c+1,c+cnt+1,l[i])-c,r[i]=lower_bound(c+1,c+cnt+1,r[i])-c;

	for(int i=n;i;--i)

	{

		f[i]=tr.query(l[i]);

		if(l[i]>r[i]) tr.update(1,1,cnt,r[i]+1,l[i]-1,i);

		else tr.update(1,1,cnt,1,l[i]-1,i),tr.update(1,1,cnt,r[i]+1,cnt,i);

	}

	ans=f[1];

	for(int i=cnt;i;--i) ans=min(ans,tr.query(i));

	printf("%lld\n",ans+2*s[n]);

	return 0;

}