#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define N 10000010
#define K 300000
#define ll long long
#pragma GCC optimize(2)
#pragma GCC optimize(3)
using namespace std;
ll n,m,i,j,k[K],q,id,mul,lp[N],rp[N],f[N],x,num,data[N],top,p,mn;
vector<ll> a[K],c[K];
struct node{
	ll height,cost;
}g[N];
int search(ll p){
	ll mid,k=0,l=1,r=top;
	while (l<=r){
		mid=(l+r)/2;
		if (data[mid]>=p){
			k=data[mid];
			r=mid-1;
		}
		else
			l=mid+1;
	}
	return k;
}
int main(){
	//freopen("shark.in","r",stdin);
	//freopen("shark.out","w",stdout);
	scanf("%lld%lld",&n,&m);
	for (i=1;i<=n;i++){
		scanf("%lld",&k[i]);
		a[i].push_back(0);
		c[i].push_back(0);
		for (j=1;j<=k[i];j++){
			scanf("%lld",&x);
			a[i].push_back(x);
		}
		for (j=1;j<=k[i];j++){
			scanf("%lld",&x);
			c[i].push_back(x);
		}
	}
	scanf("%lld",&q);
	while (q--){
		scanf("%lld%lld",&id,&mul);
		for (i=num+1;i<=num+k[id];i++)
			g[i].height=a[id][i-num];
		for (i=num+1;i<=num+k[id];i++)
			g[i].cost=c[id][i-num]*mul;
		num+=k[id];
	}
	for (i=1;i<=num;i++)
		lp[i]=rp[i]=i;
	top=1;
	data[1]=1;
	for (i=2;i<=num;i++){
		while (top&&g[i].height>i-data[top])
			lp[i]=lp[data[top]],top--;
		data[++top]=i;
	}
	top=1;
	data[1]=num;
	for (i=num-1;i>=1;i--){
		while (top&&g[i].height>data[top]-i)
			rp[i]=rp[data[top]],top--;
		data[++top]=i;
	}
	top=1;
	data[1]=1;
	for (i=0;i<=num;i++)
		f[i]=1e18;
	f[1]=g[1].cost;
	f[rp[1]]=g[1].cost;
	f[rp[2]]=min(f[rp[2]],g[1].cost+g[2].cost);
	mn=1e18;
	mn=0;
	for (i=2;i<=num;i++){
		if (lp[i]==lp[i-1]&&mn){
			p=mn;
			if (f[i-1]<f[p])
				p=i-1,mn=i-1;
		}
		else{
			if (lp[i]<lp[i-1])
				p=0,mn=0;
			else{
				p=search(lp[i]-1);
				mn=p;
			}
		}
		if (p)
			f[i]=min(f[i],g[i].cost+f[p]);
		f[i]=min(f[i],g[i].cost+f[i-1]);
		if (lp[i]<=1)
			f[i]=min(f[i],g[i].cost);
		while (top&&f[i]<=f[data[top]])
			top--;
		data[++top]=i;
		f[rp[i+1]]=min(f[rp[i+1]],f[i]+g[i+1].cost);
	}
	printf("%lld\n",f[num]);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define N 10000010
#define K 300000
#define ll long long
using namespace std;
ll n,m,i,j,k[K],q,id,mul,lp[N],rp[N],f[N],x,num,data[N],top,p;
vector<ll> a[K],c[K];
struct node{
	ll height,cost;
}g[N];
int search(ll p){
	ll mid,k=0,l=1,r=top;
	while (l<=r){
		mid=(l+r)/2;
		if (data[mid]>=p){
			k=data[mid];
			r=mid-1;
		}
		else
			l=mid+1;
	}
	return k;
}
int main(){
	//freopen("shark.in","r",stdin);
	//freopen("shark.out","w",stdout);
	scanf("%lld%lld",&n,&m);
	for (i=1;i<=n;i++){
		scanf("%lld",&k[i]);
		a[i].push_back(0);
		c[i].push_back(0);
		for (j=1;j<=k[i];j++){
			scanf("%lld",&x);
			a[i].push_back(x);
		}
		for (j=1;j<=k[i];j++){
			scanf("%lld",&x);
			c[i].push_back(x);
		}
	}
	scanf("%lld",&q);
	while (q--){
		scanf("%lld%lld",&id,&mul);
		for (i=num+1;i<=num+k[id];i++)
			g[i].height=a[id][i-num];
		for (i=num+1;i<=num+k[id];i++)
			g[i].cost=c[id][i-num]*mul;
		num+=k[id];
	}
	for (i=1;i<=num;i++)
		lp[i]=rp[i]=i;
	top=1;
	data[1]=1;
	for (i=2;i<=num;i++){
		while (top&&g[i].height>i-data[top])
			lp[i]=lp[data[top]],top--;
		data[++top]=i;
	}
	top=1;
	data[1]=num;
	for (i=num-1;i>=1;i--){
		while (top&&g[i].height>data[top]-i)
			rp[i]=rp[data[top]],top--;
		data[++top]=i;
	}
	top=1;
	data[1]=1;
	for (i=0;i<=num;i++)
		f[i]=1e18;
	f[1]=g[1].cost;
	f[rp[1]]=g[1].cost;
	f[rp[2]]=min(f[rp[2]],g[1].cost+g[2].cost);
	for (i=2;i<=num;i++){
		f[rp[i+1]]=min(f[rp[i+1]],f[i]+g[i+1].cost);
		p=search(lp[i]-1);
		if (p)
			f[i]=min(f[i],g[i].cost+f[p]);
		f[i]=min(f[i],g[i].cost+f[i-1]);
		while (top&&f[i]<=f[data[top]])
			top--;
		data[++top]=i;
	}
	printf("%lld\n",f[num]);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define N 10000010
#define K 300000
#define ll long long
#pragma GCC optimize(2)
#pragma GCC optimize(3)
using namespace std;
ll n,m,i,j,k[K],q,id,mul,lp[N],rp[N],f[N],x,num,data[N],top,p,mn;
vector<ll> a[K],c[K];
struct node{
	ll height,cost;
}g[N];
int search(ll p){
	ll mid,k=0,l=1,r=top;
	while (l<=r){
		mid=(l+r)/2;
		if (data[mid]>=p){
			k=data[mid];
			r=mid-1;
		}
		else
			l=mid+1;
	}
	return k;
}
int main(){
	//freopen("shark.in","r",stdin);
	//freopen("shark.out","w",stdout);
	scanf("%lld%lld",&n,&m);
	for (i=1;i<=n;i++){
		scanf("%lld",&k[i]);
		a[i].push_back(0);
		c[i].push_back(0);
		for (j=1;j<=k[i];j++){
			scanf("%lld",&x);
			a[i].push_back(x);
		}
		for (j=1;j<=k[i];j++){
			scanf("%lld",&x);
			c[i].push_back(x);
		}
	}
	scanf("%lld",&q);
	while (q--){
		scanf("%lld%lld",&id,&mul);
		for (i=num+1;i<=num+k[id];i++)
			g[i].height=a[id][i-num];
		for (i=num+1;i<=num+k[id];i++)
			g[i].cost=c[id][i-num]*mul;
		num+=k[id];
	}
	for (i=1;i<=num;i++)
		lp[i]=rp[i]=i;
	top=1;
	data[1]=1;
	for (i=2;i<=num;i++){
		while (top&&g[i].height>i-data[top])
			lp[i]=lp[data[top]],top--;
		data[++top]=i;
	}
	top=1;
	data[1]=num;
	for (i=num-1;i>=1;i--){
		while (top&&g[i].height>data[top]-i)
			rp[i]=rp[data[top]],top--;
		data[++top]=i;
	}
	top=1;
	data[1]=1;
	for (i=0;i<=num;i++)
		f[i]=1e18;
	f[1]=g[1].cost;
	f[rp[1]]=g[1].cost;
	f[rp[2]]=min(f[rp[2]],g[1].cost+g[2].cost);
	mn=1e18;
	mn=0;
	for (i=2;i<=num;i++){
		if (lp[i]==lp[i+1])
			p=mn;
		else{
			p=search(lp[i]-1);
			mn=p;
		}
		if (p)
			f[i]=min(f[i],g[i].cost+f[p]);
		f[i]=min(f[i],g[i].cost+f[i-1]);
		if (lp[i]<=1)
			f[i]=min(f[i],g[i].cost);
		while (top&&f[i]<=f[data[top]])
			top--;
		data[++top]=i;
		f[rp[i+1]]=min(f[rp[i+1]],f[i]+g[i+1].cost);
	}
	printf("%lld\n",f[num]);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define N 10000010
#define K 300000
#define ll long long
using namespace std;
ll n,m,i,j,k[K],q,id,mul,lp[N],rp[N],f[N],x,num,data[N],top,p;
vector<ll> a[K],c[K];
struct node{
	ll height,cost;
}g[N];
int search(ll p){
	ll mid,k=0,l=1,r=top;
	while (l<=r){
		mid=(l+r)/2;
		if (data[mid]>=p){
			k=data[mid];
			r=mid-1;
		}
		else
			l=mid+1;
	}
	return k;
}
int main(){
	//freopen("shark.in","r",stdin);
	//freopen("shark.out","w",stdout);
	scanf("%lld%lld",&n,&m);
	for (i=1;i<=n;i++){
		scanf("%lld",&k[i]);
		a[i].push_back(0);
		c[i].push_back(0);
		for (j=1;j<=k[i];j++){
			scanf("%lld",&x);
			a[i].push_back(x);
		}
		for (j=1;j<=k[i];j++){
			scanf("%lld",&x);
			c[i].push_back(x);
		}
	}
	scanf("%lld",&q);
	while (q--){
		scanf("%lld%lld",&id,&mul);
		for (i=num+1;i<=num+k[id];i++)
			g[i].height=a[id][i-num];
		for (i=num+1;i<=num+k[id];i++)
			g[i].cost=c[id][i-num]*mul;
		num+=k[id];
	}
	for (i=1;i<=num;i++)
		lp[i]=rp[i]=i;
	top=1;
	data[1]=1;
	for (i=2;i<=num;i++){
		while (top&&g[i].height>i-data[top])
			lp[i]=lp[data[top]],top--;
		data[++top]=i;
	}
	top=1;
	data[1]=num;
	for (i=num-1;i>=1;i--){
		while (top&&g[i].height>data[top]-i)
			rp[i]=rp[data[top]],top--;
		data[++top]=i;
	}
	top=1;
	data[1]=1;
	for (i=0;i<=num;i++)
		f[i]=1e18;
	f[1]=g[1].cost;
	f[rp[1]]=g[1].cost;
	f[rp[2]]=min(f[rp[2]],g[1].cost+g[2].cost);
	for (i=2;i<=num;i++){
		p=search(lp[i]-1);
		if (p)
			f[i]=min(f[i],g[i].cost+f[p]);
		f[i]=min(f[i],g[i].cost+f[i-1]);
		if (lp[i]<=1)
			f[i]=min(f[i],g[i].cost);
		while (top&&f[i]<=f[data[top]])
			top--;
		data[++top]=i;
		f[rp[i+1]]=min(f[rp[i+1]],f[i]+g[i+1].cost);
	}
	printf("%lld\n",f[num]);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define N 10000010
#define K 300000
#define ll long long
using namespace std;
ll n,m,i,j,k[K],q,id,mul,lp[N],rp[N],f[N],x,num,data[N],top,p;
vector<ll> a[K],c[K];
struct node{
	ll height,cost;
}g[N];
int search(ll p){
	ll mid,k=0,l=1,r=top;
	while (l<=r){
		mid=(l+r)/2;
		if (data[mid]>=p){
			k=data[mid];
			r=mid-1;
		}
		else
			l=mid+1;
	}
	return k;
}
int main(){
	//freopen("shark.in","r",stdin);
	//freopen("shark.out","w",stdout);
	scanf("%lld%lld",&n,&m);
	for (i=1;i<=n;i++){
		scanf("%lld",&k[i]);
		a[i].push_back(0);
		c[i].push_back(0);
		for (j=1;j<=k[i];j++){
			scanf("%lld",&x);
			a[i].push_back(x);
		}
		for (j=1;j<=k[i];j++){
			scanf("%lld",&x);
			c[i].push_back(x);
		}
	}
	scanf("%lld",&q);
	while (q--){
		scanf("%lld%lld",&id,&mul);
		for (i=num+1;i<=num+k[id];i++)
			g[i].height=a[id][i-num];
		for (i=num+1;i<=num+k[id];i++)
			g[i].cost=c[id][i-num]*mul;
		num+=k[id];
	}
	for (i=1;i<=num;i++)
		lp[i]=rp[i]=i;
	top=1;
	data[1]=1;
	for (i=2;i<=num;i++){
		while (top&&g[i].height>i-data[top])
			lp[i]=lp[data[top]],top--;
		data[++top]=i;
	}
	top=1;
	data[1]=num;
	for (i=num-1;i>=1;i--){
		while (top&&g[i].height>data[top]-i)
			rp[i]=rp[data[top]],top--;
		data[++top]=i;
	}
	top=1;
	data[1]=1;
	for (i=0;i<=num;i++)
		f[i]=1e18;
	f[1]=g[1].cost;
	f[rp[1]]=g[1].cost;
	f[rp[2]]=min(f[rp[2]],g[1].cost+g[2].cost);
	for (i=2;i<=num;i++){
		f[rp[i+1]]=min(f[rp[i+1]],f[i]+g[i+1].cost);
		p=search(lp[i]-1);
		if (p)
			f[i]=min(f[i],g[i].cost+f[p]);
		f[i]=min(f[i],g[i].cost+f[i-1]);
		if (lp[i]<=1)
			f[i]=min(f[i],g[i].cost);
		while (top&&f[i]<=f[data[top]])
			top--;
		data[++top]=i;
	}
	printf("%lld\n",f[num]);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define N 20000000
#define K 300000
#define ll long long
using namespace std;
ll n,m,i,j,k[K],q,id,mul,lp[N],rp[N],f[N],x,num,data[N],top,p;
vector<ll> a[K],c[K];
struct node{
	ll height,cost;
}g[N];
int search(ll p){
	ll mid,k=0,l=1,r=top;
	while (l<=r){
		mid=(l+r)/2;
		if (data[mid]>=p){
			k=data[mid];
			r=mid-1;
		}
		else
			l=mid+1;
	}
	return k;
}
int main(){
	freopen("shark.in","r",stdin);
	freopen("shark.out","w",stdout);
	scanf("%lld%lld",&n,&m);
	for (i=1;i<=n;i++){
		scanf("%lld",&k[i]);
		a[i].push_back(0);
		c[i].push_back(0);
		for (j=1;j<=k[i];j++){
			scanf("%lld",&x);
			a[i].push_back(x);
		}
		for (j=1;j<=k[i];j++){
			scanf("%lld",&x);
			c[i].push_back(x);
		}
	}
	scanf("%lld",&q);
	while (q--){
		scanf("%lld%lld",&id,&mul);
		for (i=num+1;i<=num+k[id];i++)
			g[i].height=a[id][i-num];
		for (i=num+1;i<=num+k[id];i++)
			g[i].cost=c[id][i-num]*mul;
		num+=k[id];
	}
	for (i=1;i<=num;i++)
		lp[i]=rp[i]=i;
	top=1;
	data[1]=1;
	for (i=2;i<=num;i++){
		while (top&&g[i].height>i-data[top])
			lp[i]=lp[data[top]],top--;
		data[++top]=i;
	}
	top=1;
	data[1]=num;
	for (i=num-1;i>=1;i--){
		while (top&&g[i].height>data[top]-i)
			rp[i]=rp[data[top]],top--;
		data[++top]=i;
	}
	top=1;
	data[1]=1;
	for (i=0;i<=num;i++)
		f[i]=1e18;
	f[1]=g[1].cost;
	f[rp[1]]=g[1].cost;
	f[rp[2]]=min(f[rp[2]],g[1].cost+g[2].cost);
	for (i=2;i<=num;i++){
		f[rp[i+1]]=min(f[rp[i+1]],f[i]+g[i+1].cost);
		p=search(lp[i]-1);
		if (p)
			f[i]=min(f[i],g[i].cost+f[p]);
		f[i]=min(f[i],g[i].cost+f[i-1]);
		while (top&&f[i]<=f[data[top]])
			top--;
		data[++top]=i;
	}
	printf("%lld\n",f[num]);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define N 10000010
#define K 300000
#define ll long long
#pragma GCC optimize(2)
#pragma GCC optimize(3)
using namespace std;
ll n,m,i,j,k[K],q,id,mul,lp[N],rp[N],f[N],x,num,data[N],top,p,mn;
vector<ll> a[K],c[K];
struct node{
	ll height,cost;
}g[N];
int search(ll p){
	ll mid,k=0,l=1,r=top;
	while (l<=r){
		mid=(l+r)/2;
		if (data[mid]>=p){
			k=data[mid];
			r=mid-1;
		}
		else
			l=mid+1;
	}
	return k;
}
int main(){
	//freopen("shark.in","r",stdin);
	//freopen("shark.out","w",stdout);
	scanf("%lld%lld",&n,&m);
	for (i=1;i<=n;i++){
		scanf("%lld",&k[i]);
		a[i].push_back(0);
		c[i].push_back(0);
		for (j=1;j<=k[i];j++){
			scanf("%lld",&x);
			a[i].push_back(x);
		}
		for (j=1;j<=k[i];j++){
			scanf("%lld",&x);
			c[i].push_back(x);
		}
	}
	scanf("%lld",&q);
	while (q--){
		scanf("%lld%lld",&id,&mul);
		for (i=num+1;i<=num+k[id];i++)
			g[i].height=a[id][i-num];
		for (i=num+1;i<=num+k[id];i++)
			g[i].cost=c[id][i-num]*mul;
		num+=k[id];
	}
	for (i=1;i<=num;i++)
		lp[i]=rp[i]=i;
	top=1;
	data[1]=1;
	for (i=2;i<=num;i++){
		while (top&&g[i].height>i-data[top])
			lp[i]=lp[data[top]],top--;
		data[++top]=i;
	}
	top=1;
	data[1]=num;
	for (i=num-1;i>=1;i--){
		while (top&&g[i].height>data[top]-i)
			rp[i]=rp[data[top]],top--;
		data[++top]=i;
	}
	top=1;
	data[1]=1;
	for (i=0;i<=num;i++)
		f[i]=1e18;
	f[1]=g[1].cost;
	f[rp[1]]=g[1].cost;
	f[rp[2]]=min(f[rp[2]],g[1].cost+g[2].cost);
	mn=1e18;
	mn=0;
	for (i=2;i<=num;i++){
		if (lp[i]==lp[i-1])
			p=mn;
		else{
			p=search(lp[i]-1);
			mn=p;
		}
		if (p)
			f[i]=min(f[i],g[i].cost+f[p]);
		f[i]=min(f[i],g[i].cost+f[i-1]);
		if (lp[i]<=1)
			f[i]=min(f[i],g[i].cost);
		while (top&&f[i]<=f[data[top]])
			top--;
		data[++top]=i;
		f[rp[i+1]]=min(f[rp[i+1]],f[i]+g[i+1].cost);
	}
	printf("%lld\n",f[num]);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define N 10000010
#define K 300000
#define ll long long
#pragma GCC optimize(2)
#pragma GCC optimize(3)
using namespace std;
ll n,m,i,j,k[K],q,id,mul,lp[N],rp[N],f[N],x,num,data[N],top,p,mn;
vector<ll> a[K],c[K];
struct node{
	ll height,cost;
}g[N];
int search(ll p){
	ll mid,k=0,l=1,r=top;
	while (l<=r){
		mid=(l+r)/2;
		if (data[mid]>=p){
			k=data[mid];
			r=mid-1;
		}
		else
			l=mid+1;
	}
	return k;
}
int main(){
	//freopen("shark.in","r",stdin);
	//freopen("shark.out","w",stdout);
	scanf("%lld%lld",&n,&m);
	for (i=1;i<=n;i++){
		scanf("%lld",&k[i]);
		a[i].push_back(0);
		c[i].push_back(0);
		for (j=1;j<=k[i];j++){
			scanf("%lld",&x);
			a[i].push_back(x);
		}
		for (j=1;j<=k[i];j++){
			scanf("%lld",&x);
			c[i].push_back(x);
		}
	}
	scanf("%lld",&q);
	while (q--){
		scanf("%lld%lld",&id,&mul);
		for (i=num+1;i<=num+k[id];i++)
			g[i].height=a[id][i-num];
		for (i=num+1;i<=num+k[id];i++)
			g[i].cost=c[id][i-num]*mul;
		num+=k[id];
	}
	for (i=1;i<=num;i++)
		lp[i]=rp[i]=i;
	top=1;
	data[1]=1;
	for (i=2;i<=num;i++){
		while (top&&g[i].height>i-data[top])
			lp[i]=lp[data[top]],top--;
		data[++top]=i;
	}
	top=1;
	data[1]=num;
	for (i=num-1;i>=1;i--){
		while (top&&g[i].height>data[top]-i)
			rp[i]=rp[data[top]],top--;
		data[++top]=i;
	}
	top=1;
	data[1]=1;
	for (i=0;i<=num;i++)
		f[i]=1e18;
	f[1]=g[1].cost;
	f[rp[1]]=g[1].cost;
	f[rp[2]]=min(f[rp[2]],g[1].cost+g[2].cost);
	mn=1e18;
	mn=0;
	for (i=2;i<=num;i++){
		if (lp[i]==lp[i-1]&&mn){
			p=mn;
			if (f[i-1]<f[p])
				p=i-1,mn=i-1;
		}
		else{
			p=search(lp[i]-1);
			mn=p;
		}
		if (p)
			f[i]=min(f[i],g[i].cost+f[p]);
		f[i]=min(f[i],g[i].cost+f[i-1]);
		if (lp[i]<=1)
			f[i]=min(f[i],g[i].cost);
		while (top&&f[i]<=f[data[top]])
			top--;
		data[++top]=i;
		f[rp[i+1]]=min(f[rp[i+1]],f[i]+g[i+1].cost);
	}
	printf("%lld\n",f[num]);
	return 0;
}


use std::io::*;
use std::str::FromStr;
use std::fmt::Debug;

trait TokenIO {
    fn get_line<T: FromStr>(&mut self) -> Vec<T> where T: FromStr, T::Err: Debug;
}

impl <R: BufRead> TokenIO for R {
    fn get_line<T: FromStr>(&mut self) -> Vec<T> where T: FromStr, T::Err: Debug {
        let mut line = String::new();
        self.read_line(&mut line).unwrap();

        line.trim_right().split(" ").map(|x| x.parse::<T>().unwrap()).collect()
    }
}

pub fn main() {
    let stdin = stdin();
    let mut stdin = stdin.lock();

    let (n, m): (usize, usize) = {
        let nums = stdin.get_line();
        (nums[0], nums[1])
    };

    let mut blocks: Vec<Vec<(i64, i64)>> = Vec::with_capacity(n);
    for _ in 0..n {
        let ki: usize = stdin.get_line()[0];
        let heights: Vec<i64> = stdin.get_line();
        let costs: Vec<i64> = stdin.get_line();
        blocks.push(heights.into_iter().zip(costs.into_iter()).collect());
    }

    let mut heights: Vec<i64> = Vec::with_capacity(m);
    let mut costs: Vec<i64> = Vec::with_capacity(m);

    let q: usize = stdin.get_line()[0];
    for _ in 0..q {
        let (id, mul): (usize, i64) = {
            let nums = stdin.get_line();
            (nums[0], nums[1] as i64)
        };

        for &(h, c) in blocks[id - 1].iter() {
            heights.push(h);
            costs.push(mul * c);
        }
    }

    let mut left_bound = vec![0 as i64; m];
    for i in 0..m {
        left_bound[i] = {
            let left_hit = i as i64 - heights[i];
            let mut left = i as i64 - 1;
            while left >= 0 && left_hit < left {
                left = left_bound[left as usize];
            }
            left
        }
    }

    let mut right_bound = vec![m as i64; m];
    let mut dp = vec![std::i64::MAX / 2; m + 1];
    let mut right_min = vec![0; m];
    dp[m] = 0;
    for i in (0..m).rev() {
        let (rb, rm) = {
            let mut min = dp[i + 1];
            let right_hit = i as i64 + heights[i];
            let mut right = i as i64 + 1;
            while right < m as i64 && right_hit > right {
                min = min.min(right_min[right as usize]);
                right = right_bound[right as usize];
            }
            (right, min)
        };
        right_bound[i] = rb;
        right_min[i] = rm;

        let left = (left_bound[i] + 1) as usize;
        dp[left] = dp[left].min(dp[i + 1] + costs[i]);
        dp[i] = dp[i].min(right_min[i] + costs[i]);
    }

    println!("{}", dp[0]);
}


use std::io::*;
use std::str::{self, FromStr};
use std::fmt::Debug;

trait TokenIO {
    fn next_token<T: FromStr>(&mut self) -> T where T: FromStr, T::Err: Debug;
}

impl <R: Read> TokenIO for R {
    fn next_token<T: FromStr>(&mut self) -> T where T: FromStr, T::Err: Debug {
        let token: Vec<_> = self.bytes()
            .map(|b| b.unwrap())
            .skip_while(|b| b.is_ascii_whitespace())
            .take_while(|b| !b.is_ascii_whitespace())
            .collect();
        T::from_str(str::from_utf8(&token).unwrap()).unwrap()
    }
}

pub fn main() {
    let stdin = stdin();
    let mut stdin = stdin.lock();

    let n: usize = stdin.next_token();
    let m: usize = stdin.next_token();

    let mut blocks: Vec<Vec<(i64, i64)>> = Vec::with_capacity(n);
    for _ in 0..n {
        let ki: usize = stdin.next_token();
        let heights: Vec<i64> = (0..ki).map(|_| stdin.next_token()).collect();
        let costs: Vec<i64> = (0..ki).map(|_| stdin.next_token()).collect();
        blocks.push(heights.into_iter().zip(costs.into_iter()).collect());
    }

    let mut heights: Vec<i64> = Vec::with_capacity(m);
    let mut costs: Vec<i64> = Vec::with_capacity(m);

    let q: usize = stdin.next_token();
    for _ in 0..q {
        let id: usize = stdin.next_token();
        let mul: i64 = stdin.next_token();

        for &(h, c) in blocks[id - 1].iter() {
            heights.push(h);
            costs.push(mul * c);
        }
    }

    let mut left_bound = vec![0 as i64; m];
    for i in 0..m {
        left_bound[i] = {
            let left_hit = i as i64 - heights[i];
            let mut left = i as i64 - 1;
            while left >= 0 && left_hit < left {
                left = left_bound[left as usize];
            }
            left
        }
    }

    let mut right_bound = vec![m as i64; m];
    let mut dp = vec![std::i64::MAX / 2; m + 1];
    let mut right_min = vec![0; m];
    dp[m] = 0;
    for i in (0..m).rev() {
        let (rb, rm) = {
            let mut min = dp[i + 1];
            let right_hit = i as i64 + heights[i];
            let mut right = i as i64 + 1;
            while right < m as i64 && right_hit > right {
                min = min.min(right_min[right as usize]);
                right = right_bound[right as usize];
            }
            (right, min)
        };
        right_bound[i] = rb;
        right_min[i] = rm;

        let left = (left_bound[i] + 1) as usize;
        dp[left] = dp[left].min(dp[i + 1] + costs[i]);
        dp[i] = dp[i].min(right_min[i] + costs[i]);
    }

    println!("{}", dp[0]);
}


package main

import (
	"bufio"
	"fmt"
	"os"
)

var (
	que    []*Qpair
	height []int
	cost   []int64
	qf     int
	qr     int
)

type block struct {
	len int
	h   []int
	c   []int
}

type Qpair struct {
	w int
	v int64
}

func addQue(w int, v int64) {
	if qr == qf {
		que[qr] = &Qpair{
			w: w,
			v: v,
		}
		qr++
		return
	}
	if que[qr-1].w == w {
		if v < que[qr-1].v {
			que[qr-1].v = v
		}
		return
	}
	if que[qr-1].v > v {
		que[qr] = &Qpair{
			w: w,
			v: v,
		}
		qr++
		return
	}
	return
}
func findQue(w int) int64 {
	for qf < qr && que[qr-1].w < w {
		qr--
	}
	if qf == qr {
		return -1
	}
	return que[qr-1].v
}

func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m, k, q int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	dp := make([]int64, m+1)
	que = make([]*Qpair, m+1)
	height = make([]int, m+1)
	cost = make([]int64, m+1)
	blocks := make([]*block, n+1)

	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d\n", &k)
		b := &block{
			len: k,
			h:   make([]int, k),
			c:   make([]int, k),
		}
		for j := 0; j < k; j++ {
			fmt.Fscanf(buf, "%d", &b.h[j])
		}
		fmt.Fscanf(buf, "\n")
		for j := 0; j < k; j++ {
			fmt.Fscanf(buf, "%d", &b.c[j])
		}
		fmt.Fscanf(buf, "\n")
		blocks[i+1] = b

	}
	fmt.Fscanf(buf, "%d\n", &q)
	var mul int64
	front := 1
	for i := 0; i < q; i++ {
		fmt.Fscanf(buf, "%d %d\n", &k, &mul)
		for j := 0; j < blocks[k].len; j++ {
			height[front] = blocks[k].h[j]
			cost[front] = int64(blocks[k].c[j]) * mul
			front++
		}
	}
	left := make([]int, m+1)
	right := make([]int, m+1)
	var pre int64
	qr = 0
	for i := 1; i <= m; i++ {
		if height[i] == 1 {
			left[i] = i
			continue
		}
		pre = int64(i - height[i] + 1)
		if pre < 1 {
			pre = 1
		}
		for pre > 1 && qr > 0 && que[qr-1].w >= int(pre) {
			if que[qr-1].v < pre {
				pre = que[qr-1].v
			}
			qr--
		}
		if que[qr] == nil {
			que[qr] = &Qpair{}
		}
		que[qr].w = i
		que[qr].v = pre
		qr++
		left[i] = int(pre)
	}
	var int64m int64 = int64(m)
	qr = 0
	for i := m; i >= 1; i-- {
		if height[i] == 1 {
			right[i] = i
			continue
		}
		pre = int64(i + height[i] - 1)
		if pre > int64m {
			pre = int64m
		}
		for pre < int64m && qr > 0 && que[qr-1].w <= int(pre) {
			if que[qr-1].v > pre {
				pre = que[qr-1].v
			}
			qr--
		}
		if que[qr] == nil {
			que[qr] = &Qpair{}
		}
		que[qr].w = i
		que[qr].v = pre
		right[i] = int(pre)
		qr++
	}
	//fmt.Printf("h== %v\n", height)
	//fmt.Printf("c== %v\n", cost)
	//fmt.Printf("left== %v\n", left)
	//fmt.Printf("right== %v\n", right)
	qr=0
	qf=0
	for i := 1; i <= m; i++ {

		addQue(right[i], dp[i-1]+cost[i])
		if qr == qf {
			if que[qr] == nil {
				que[qr] = &Qpair{

				}
			}
			que[qr].w = right[i]
			que[qr].v = dp[i-1] + cost[i]
			qr++

		} else if que[qr-1].w == right[i] {
			if dp[i-1]+cost[i] < que[qr-1].v {
				que[qr-1].v = dp[i-1] + cost[i]
			}

		} else if que[qr-1].v > dp[i-1]+cost[i] {
			if que[qr] == nil {
				que[qr] = &Qpair{

				}
			}
			que[qr].w = right[i]
			que[qr].v = dp[i-1] + cost[i]
			qr++

		}

		dp[i] = -1
		if qr > qf {
			dp[i] = que[qr-1].v
		}

		var lv int64 = cost[i]
		//	fmt.Printf("i=%d front=%d add = %d dp=%d lv=%d\n", i, right[i],  dp[i-1]+int64(cost[i]), dp[i], lv)
	//	pre = left[i]
		if  left[i]-1 > 0 {
			lv += dp[left[i]-1]
		}
		if dp[i] <= 0 || dp[i] > lv {
			dp[i] = lv
		}
		for qr > qf && que[qr-1].w <= i {
			qr--
		}
	}
	//	fmt.Printf("dp=%d\n", dp)
	fmt.Printf("%d\n", dp[m])

}

/*
1 10
10
1 1 2 1 1 1 2 1 1 1
1 1 1 1 1 1 1 1 1 1
1
1 1
*/


package main

import (
	"bufio"
	"fmt"
	"os"
)

var (
	que    []*Qpair
	height []int
	cost   []int64
	qf     int
	qr     int
)

type block struct {
	len int
	h   []int
	c   []int
}

type Qpair struct {
	w int
	v int64
}

func addQue(w int, v int64) {
	if qr == qf {
		que[qr] = &Qpair{
			w: w,
			v: v,
		}
		qr++
		return
	}
	if que[qr-1].w == w {
		if v < que[qr-1].v {
			que[qr-1].v = v
		}
		return
	}
	if que[qr-1].v > v {
		que[qr] = &Qpair{
			w: w,
			v: v,
		}
		qr++
		return
	}
	return
}
func findQue(w int) int64 {
	for qf < qr && que[qr-1].w < w {
		qr--
	}
	if qf == qr {
		return -1
	}
	return que[qr-1].v
}

func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m, k, q int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	dp := make([]int64, m+1)
	que = make([]*Qpair, m+1)
	height = make([]int, m+1)
	cost = make([]int64, m+1)
	blocks := make([]*block, n+1)

	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d\n", &k)
		b := &block{
			len: k,
			h:   make([]int, k),
			c:   make([]int, k),
		}
		for j := 0; j < k; j++ {
			fmt.Fscanf(buf, "%d", &b.h[j])
		}
		fmt.Fscanf(buf, "\n")
		for j := 0; j < k; j++ {
			fmt.Fscanf(buf, "%d", &b.c[j])
		}
		fmt.Fscanf(buf, "\n")
		blocks[i+1] = b

	}
	fmt.Fscanf(buf, "%d\n", &q)
	var mul int64
	front := 1
	for i := 0; i < q; i++ {
		fmt.Fscanf(buf, "%d %d\n", &k, &mul)
		for j := 0; j < blocks[k].len; j++ {
			height[front] = blocks[k].h[j]
			cost[front] = int64(blocks[k].c[j]) * mul
			front++
		}
	}
	left := make([]int, m+1)
	right := make([]int, m+1)
	pre := m
	for i := 1; i <= m; i++ {
		if i == 1 || height[i] == 1 {
			pre = i
			left[i] = i
			continue
		}
		if pre > 1 && i-height[i]+1 < pre {
			minf := i - height[i] + 1
			for j := pre - 1; minf > 1 && j >= minf; j-- {
				if j-height[j]+1 < minf {
					minf = j - height[j] + 1
				}
			}
			if minf <= 1 {
				minf = 1
			}
			pre = minf
		}
		left[i] = pre
	}
	front = m
	for i := m; i >= 1; i-- {
		if height[i] == 1 {
			front = i
			right[i] = i
			continue
		}
		if front < m && i+height[i]-1 > front {
			maxf := i + height[i] - 1
			for j := front + 1; maxf < m && j <= maxf; j++ {
				if j+height[j]-1 > maxf {
					maxf = j + height[j] - 1
				}
			}
			if maxf > m {
				maxf = m
			}
			front = maxf
		}
		right[i] = front
	}
	//fmt.Printf("h== %v\n", height)
	//fmt.Printf("c== %v\n", cost)
	//fmt.Printf("left== %v\n", left)
	//fmt.Printf("right== %v\n", right)
	for i := 1; i <= m; i++ {

		addQue(right[i], dp[i-1]+int64(cost[i]))
		dp[i] = findQue(i)

		var lv int64 = int64(cost[i])
	//	fmt.Printf("i=%d front=%d add = %d dp=%d lv=%d\n", i, right[i],  dp[i-1]+int64(cost[i]), dp[i], lv)
		pre = left[i]
		if pre-1 > 0 {
			lv += dp[pre-1]
		}
		if dp[i] <= 0 || dp[i] > lv {
			dp[i] = lv
		}
		if height[i] == 1{
			qr =0
			qf = 0

		}
	}
//	fmt.Printf("dp=%d\n", dp)
	fmt.Printf("%d\n", dp[m])

}

/*
1 10
10
1 1 2 1 1 1 2 1 1 1
1 1 1 1 1 1 1 1 1 1
1
1 1
*/


package main

import (
	"bufio"
	"fmt"
	"os"
)

var (
	que    []*Qpair
	height []int
	cost   []int64
	qf     int
	qr     int
)

type block struct {
	len int
	h   []int
	c   []int
}

type Qpair struct {
	w int
	v int64
}

func addQue(w int, v int64) {
	if qr == qf {
		que[qr] = &Qpair{
			w: w,
			v: v,
		}
		qr++
		return
	}
	if que[qr-1].w == w {
		if v < que[qr-1].v {
			que[qr-1].v = v
		}
		return
	}
	if que[qr-1].v > v {
		que[qr] = &Qpair{
			w: w,
			v: v,
		}
		qr++
		return
	}
	return
}
func findQue(w int) int64 {
	for qf < qr && que[qr-1].w < w {
		qr--
	}
	if qf == qr {
		return -1
	}
	return que[qr-1].v
}

func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m, k, q int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	dp := make([]int64, m+1)
	que = make([]*Qpair, m+1)
	height = make([]int, m+1)
	cost = make([]int64, m+1)
	blocks := make([]*block, n+1)

	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d\n", &k)
		b := &block{
			len: k,
			h:   make([]int, k),
			c:   make([]int, k),
		}
		for j := 0; j < k; j++ {
			fmt.Fscanf(buf, "%d", &b.h[j])
		}
		fmt.Fscanf(buf, "\n")
		for j := 0; j < k; j++ {
			fmt.Fscanf(buf, "%d", &b.c[j])
		}
		fmt.Fscanf(buf, "\n")
		blocks[i+1] = b

	}
	fmt.Fscanf(buf, "%d\n", &q)
	var mul int64
	front := 1
	for i := 0; i < q; i++ {
		fmt.Fscanf(buf, "%d %d\n", &k, &mul)
		for j := 0; j < blocks[k].len; j++ {
			height[front] = blocks[k].h[j]
			cost[front] = int64(blocks[k].c[j]) * mul
			front++
		}
	}
	left := make([]int, m+1)
	right := make([]int, m+1)
	pre := m
	for i := 1; i <= m; i++ {
		if i == 1 || height[i] == 1 {
			pre = i
			left[i] = i
			continue
		}
		if pre > 1 && i-height[i]+1 < pre {
			minf := i - height[i] + 1
			for j := pre - 1; minf > 1 && j >= minf; j-- {
				if j-height[j]+1 < minf {
					minf = j - height[j] + 1
				}
			}
			if minf <= 1 {
				minf = 1
			}
			pre = minf
		}
		left[i] = pre
	}
	front = m
	for i := m; i >= 1; i-- {
		if height[i] == 1 {
			front = i
			right[i] = i
			continue
		}
		if front < m && i+height[i]-1 > front {
			maxf := i + height[i] - 1
			for j := front + 1; maxf < m && j <= maxf; j++ {
				if j+height[j]-1 > maxf {
					maxf = j + height[j] - 1
				}
			}
			if maxf > m {
				maxf = m
			}
			front = maxf
		}
		right[i] = front
	}
	//fmt.Printf("h== %v\n", height)
	//fmt.Printf("c== %v\n", cost)
	//fmt.Printf("left== %v\n", left)
	//fmt.Printf("right== %v\n", right)
	for i := 1; i <= m; i++ {

		addQue(right[i], dp[i-1]+int64(cost[i]))
		dp[i] = findQue(i)

		var lv int64 = int64(cost[i])
	//	fmt.Printf("i=%d front=%d add = %d dp=%d lv=%d\n", i, right[i],  dp[i-1]+int64(cost[i]), dp[i], lv)
		pre = left[i]
		if pre-1 > 0 {
			lv += dp[pre-1]
		}
		if dp[i] <= 0 || dp[i] > lv {
			dp[i] = lv
		}
		for qr > qf&&que[qr-1].w <= i{
			qr--
		}
	}
//	fmt.Printf("dp=%d\n", dp)
	fmt.Printf("%d\n", dp[m])

}

/*
1 10
10
1 1 2 1 1 1 2 1 1 1
1 1 1 1 1 1 1 1 1 1
1
1 1
*/


package main

import (
	"bufio"
	"fmt"
	"os"
)

var (
	que    []*Qpair
	height []int
	cost   []int64
	qf     int
	qr     int
)

type block struct {
	len int
	h   []int
	c   []int
}

type Qpair struct {
	w int
	v int64
}

func addQue(w int, v int64) {
	if qr == qf {
		que[qr] = &Qpair{
			w: w,
			v: v,
		}
		qr++
		return
	}
	if que[qr-1].w == w {
		if v < que[qr-1].v {
			que[qr-1].v = v
		}
		return
	}
	if que[qr-1].v > v {
		que[qr] = &Qpair{
			w: w,
			v: v,
		}
		qr++
		return
	}
	return
}
func findQue(w int) int64 {
	for qf < qr && que[qr-1].w < w {
		qr--
	}
	if qf == qr {
		return -1
	}
	return que[qr-1].v
}

func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m, k, q int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	dp := make([]int64, m+1)
	que = make([]*Qpair, m+1)
	height = make([]int, m+1)
	cost = make([]int64, m+1)
	blocks := make([]*block, n+1)

	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d\n", &k)
		b := &block{
			len: k,
			h:   make([]int, k),
			c:   make([]int, k),
		}
		for j := 0; j < k; j++ {
			fmt.Fscanf(buf, "%d", &b.h[j])
		}
		fmt.Fscanf(buf, "\n")
		for j := 0; j < k; j++ {
			fmt.Fscanf(buf, "%d", &b.c[j])
		}
		fmt.Fscanf(buf, "\n")
		blocks[i+1] = b

	}
	fmt.Fscanf(buf, "%d\n", &q)
	var mul int64
	front := 1
	for i := 0; i < q; i++ {
		fmt.Fscanf(buf, "%d %d\n", &k, &mul)
		for j := 0; j < blocks[k].len; j++ {
			height[front] = blocks[k].h[j]
			cost[front] = int64(blocks[k].c[j]) * mul
			front++
		}
	}
	left := make([]int, m+1)
	right := make([]int, m+1)
	pre := m
	for i := 1; i <= m; i++ {
		if i == 1 || height[i] == 1 {
			pre = i
			left[i] = i
			continue
		}
		if pre > 1 && i-height[i]+1 < pre {
			minf := i - height[i] + 1
			for j := pre - 1; minf > 1 && j >= minf; j-- {
				if j-height[j]+1 < minf {
					minf = j - height[j] + 1
				}
			}
			if minf <= 1 {
				minf = 1
			}
			pre = minf
		}
		left[i] = pre
	}
	front = m
	for i := m; i >= 1; i-- {
		if height[i] == 1 {
			front = i
			right[i] = i
			continue
		}
		if front < m && i+height[i]-1 > front {
			maxf := i + height[i] - 1
			for j := front + 1; maxf < m && j <= maxf; j++ {
				if j+height[j]-1 > maxf {
					maxf = j + height[j] - 1
				}
			}
			if maxf > m {
				maxf = m
			}
			front = maxf
		}
		right[i] = front
	}
	//fmt.Printf("h== %v\n", height)
	//fmt.Printf("c== %v\n", cost)
	//fmt.Printf("left== %v\n", left)
	//fmt.Printf("right== %v\n", right)
	for i := 1; i <= m; i++ {

		addQue(right[i], dp[i-1]+cost[i])
		if qr == qf {
			que[qr] = &Qpair{
				w: right[i],
				v: dp[i-1]+cost[i],
			}
			qr++

		}else if que[qr-1].w == right[i] {
			if dp[i-1]+cost[i] < que[qr-1].v {
				que[qr-1].v = dp[i-1]+cost[i]
			}

		}else if que[qr-1].v > dp[i-1]+cost[i] {
			que[qr] = &Qpair{
				w: right[i],
				v: dp[i-1]+cost[i],
			}
			qr++

		}

		dp[i] = -1
		if qr > qf{
			dp[i] = que[qr-1].v
		}

		var lv int64 = cost[i]
	//	fmt.Printf("i=%d front=%d add = %d dp=%d lv=%d\n", i, right[i],  dp[i-1]+int64(cost[i]), dp[i], lv)
		pre = left[i]
		if pre-1 > 0 {
			lv += dp[pre-1]
		}
		if dp[i] <= 0 || dp[i] > lv {
			dp[i] = lv
		}
		for qr > qf&&que[qr-1].w <= i{
			qr--
		}
	}
//	fmt.Printf("dp=%d\n", dp)
	fmt.Printf("%d\n", dp[m])

}

/*
1 10
10
1 1 2 1 1 1 2 1 1 1
1 1 1 1 1 1 1 1 1 1
1
1 1
*/


package main

import (
	"bufio"
	"fmt"
	"os"
)

var (
	que    []*Qpair
	height []int
	cost   []int64
	qf     int
	qr     int
)

type block struct {
	len int
	h   []int
	c   []int
}

type Qpair struct {
	w int
	v int64
}

func addQue(w int, v int64) {
	if qr == qf {
		que[qr] = &Qpair{
			w: w,
			v: v,
		}
		qr++
		return
	}
	if que[qr-1].w == w {
		if v < que[qr-1].v {
			que[qr-1].v = v
		}
		return
	}
	if que[qr-1].v > v {
		que[qr] = &Qpair{
			w: w,
			v: v,
		}
		qr++
		return
	}
	return
}
func findQue(w int) int64 {
	for qf < qr && que[qr-1].w < w {
		qr--
	}
	if qf == qr {
		return -1
	}
	return que[qr-1].v
}

func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m, k, q int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	dp := make([]int64, m+1)
	que = make([]*Qpair, m+1)
	height = make([]int, m+1)
	cost = make([]int64, m+1)
	blocks := make([]*block, n+1)

	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d\n", &k)
		b := &block{
			len: k,
			h:   make([]int, k),
			c:   make([]int, k),
		}
		for j := 0; j < k; j++ {
			fmt.Fscanf(buf, "%d", &b.h[j])
		}
		fmt.Fscanf(buf, "\n")
		for j := 0; j < k; j++ {
			fmt.Fscanf(buf, "%d", &b.c[j])
		}
		fmt.Fscanf(buf, "\n")
		blocks[i+1] = b

	}
	fmt.Fscanf(buf, "%d\n", &q)
	var mul int64
	front := 1
	for i := 0; i < q; i++ {
		fmt.Fscanf(buf, "%d %d\n", &k, &mul)
		for j := 0; j < blocks[k].len; j++ {
			height[front] = blocks[k].h[j]
			cost[front] = int64(blocks[k].c[j]) * mul
			front++
		}
	}
	left := make([]int, m+1)
	right := make([]int, m+1)
	pre := m
	for i := 1; i <= m; i++ {
		if i == 1 || height[i] == 1 {
			pre = i
			left[i] = i
			continue
		}
		if pre > 1 && i-height[i]+1 < pre {
			minf := i - height[i] + 1
			for j := pre - 1; minf > 1 && j >= minf; j-- {
				if j-height[j]+1 < minf {
					minf = j - height[j] + 1
				}
			}
			if minf <= 1 {
				minf = 1
			}
			pre = minf
		}
		left[i] = pre
	}
	front = m
	for i := m; i >= 1; i-- {
		if height[i] == 1 {
			front = i
			right[i] = i
			continue
		}
		if front < m && i+height[i]-1 > front {
			maxf := i + height[i] - 1
			for j := front + 1; maxf < m && j <= maxf; j++ {
				if j+height[j]-1 > maxf {
					maxf = j + height[j] - 1
				}
			}
			if maxf > m {
				maxf = m
			}
			front = maxf
		}
		right[i] = front
	}
	//fmt.Printf("h== %v\n", height)
	//fmt.Printf("c== %v\n", cost)
	//fmt.Printf("left== %v\n", left)
	//fmt.Printf("right== %v\n", right)
	for i := 1; i <= m; i++ {

		addQue(right[i], dp[i-1]+int64(cost[i]))
		dp[i] = findQue(i)

		var lv int64 = int64(cost[i])
	//	fmt.Printf("i=%d front=%d re = %d dp=%d lv=%d\n", i, right[i], pre, dp[i], lv)
		pre = left[i]
		if pre-1 > 0 {
			lv += dp[pre-1]
		}
		if dp[i] <= 0 || dp[i] > lv {
			dp[i] = lv
		}
	}
//	fmt.Printf("dp=%d\n", dp)
	fmt.Printf("%d\n", dp[m])

}

/*
209761007
933100336
1142861343
*/


package main

import (
	"bufio"
	"fmt"
	"os"
)

var (
	que    []*Qpair
	height []int
	cost   []int64
	qf     int
	qr     int
)

type block struct {
	len int
	h   []int
	c   []int
}

type Qpair struct {
	w int
	v int64
}

func addQue(w int, v int64) {
	for qr > qf && que[qr-1].v >= v {
		qr--
	}
	if qr > qf && que[qr-1].w == w {
		return
	}
	if que[qr] == nil {
		que[qr] = &Qpair{
		}
	}
	que[qr].v = v
	que[qr].w = w
	qr++

}
func findQue(w int) int64 {
	for qf < qr && que[qf].w < w {
		qf++
	}
	if qf == qr {
		return -1
	}
	return que[qf].v
}

func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m, k, q int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	dp := make([]int64, m+1)
	que = make([]*Qpair, m+1)
	height = make([]int, m+1)
	cost = make([]int64, m+1)
	blocks := make([]*block, n+1)

	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d\n", &k)
		b := &block{
			len: k,
			h:   make([]int, k),
			c:   make([]int, k),
		}
		for j := 0; j < k; j++ {
			fmt.Fscanf(buf, "%d", &b.h[j])
		}
		fmt.Fscanf(buf, "\n")
		for j := 0; j < k; j++ {
			fmt.Fscanf(buf, "%d", &b.c[j])
		}
		fmt.Fscanf(buf, "\n")
		blocks[i+1] = b

	}
	fmt.Fscanf(buf, "%d\n", &q)
	var mul int64
	front := 1
	for i := 0; i < q; i++ {
		fmt.Fscanf(buf, "%d %d\n", &k, &mul)
		for j := 0; j < blocks[k].len; j++ {
			height[front] = blocks[k].h[j]
			cost[front] = int64(blocks[k].c[j]) * mul
			front++
		}
	}
//	fmt.Printf("h== %v\n", height)
//	fmt.Printf("c== %v\n", cost)
	front = 0
	pre := m
	for i := 1; i <= m; i++ {
		if front < m && i+height[i]-1 > front {
			maxf := i + height[i] - 1
			for j := front + 1; maxf < m && j <= maxf; j++ {
				if j+height[j]-1 > maxf {
					maxf = j + height[j] - 1
					if maxf > m {
						maxf = m
					}
				}
			}
			front = maxf
		}
		if height[i] == 1 {
			pre = i
		}
		if pre > 1 && i-height[i]+1 < pre {
			minf := pre
			for j := pre - 1; minf > 1 && j >= minf; j-- {
				if j-height[j]+1 < minf {
					minf = j - height[j] + 1
					if minf <= 1 {
						minf = 1
					}
				}
			}
			pre = minf

		}

		addQue(front, dp[i-1]+int64(cost[i]))
		dp[i] = findQue(i)
	//	fmt.Printf("i=%d front=%d dp=%d\n", i, front, dp[i])
		var lv int64 = int64(cost[i])

		if pre-1 > 0 {
			lv += dp[pre]
		}
		if dp[i] <= 0 || dp[i] > lv {
			dp[i] = lv
		}
	}
//	fmt.Printf("dp=%d\n", dp)
	fmt.Printf("%d\n", dp[m])

}

/*
209761007
933100336
1142861343
*/


package main

import (
	"bufio"
	"fmt"
	"os"
)

var (
	que    []*Qpair
	height []int
	cost   []int64
	qf     int
	qr     int
)

type block struct {
	len int
	h   []int
	c   []int
}

type Qpair struct {
	w int
	v int64
}

func addQue(w int, v int64) {
	for qr > qf && que[qr-1].v >= v {
		qr--
	}
	if qr > qf && que[qr-1].w == w {
		return
	}
	if que[qr] == nil {
		que[qr] = &Qpair{
		}
	}
	que[qr].v = v
	que[qr].w = w
	qr++

}
func findQue(w int) int64 {
	for qf < qr && que[qf].w < w {
		qf++
	}
	if qf == qr {
		return -1
	}
	return que[qf].v
}

func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m, k, q int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	dp := make([]int64, m+1)
	que = make([]*Qpair, m+1)
	height = make([]int, m+1)
	cost = make([]int64, m+1)
	blocks := make([]*block, n+1)

	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d\n", &k)
		b := &block{
			len: k,
			h:   make([]int, k),
			c:   make([]int, k),
		}
		for j := 0; j < k; j++ {
			fmt.Fscanf(buf, "%d", &b.h[j])
		}
		fmt.Fscanf(buf, "\n")
		for j := 0; j < k; j++ {
			fmt.Fscanf(buf, "%d", &b.c[j])
		}
		fmt.Fscanf(buf, "\n")
		blocks[i+1] = b

	}
	fmt.Fscanf(buf, "%d\n", &q)
	var mul int64
	front := 1
	for i := 0; i < q; i++ {
		fmt.Fscanf(buf, "%d %d\n", &k, &mul)
		for j := 0; j < blocks[k].len; j++ {
			height[front] = blocks[k].h[j]
			cost[front] = int64(blocks[k].c[j]) * mul
			front++
		}
	}
//	fmt.Printf("h== %v\n", height)
//	fmt.Printf("c== %v\n", cost)
	front = 0
	pre := m
	for i := 1; i <= m; i++ {
		if front < m && i+height[i]-1 > front {
			maxf := i + height[i] - 1
			for j := front + 1; maxf < m && j <= maxf; j++ {
				if j+height[j]-1 > maxf {
					maxf = j + height[j] - 1
				}
			}
			if maxf > m {
				maxf = m
			}
			front = maxf
		}
		if height[i] == 1 {
			pre = i
		}
		if pre > 1 && i-height[i]+1 < pre {
			minf := i-height[i]+1
			for j := pre - 1; minf > 1 && j >= minf; j-- {
				if j-height[j]+1 < minf {
					minf = j - height[j] + 1

				}
			}
			if minf <= 1 {
				minf = 1
			}
			pre = minf

		}

		addQue(front, dp[i-1]+int64(cost[i]))
		dp[i] = findQue(i)
		var lv int64 = int64(cost[i])
	//	fmt.Printf("i=%d front=%d re = %d dp=%d lv=%d\n", i, front,pre, dp[i],lv)

		if pre-1 > 0 {
			lv += dp[pre-1]
		}

		if dp[i] <= 0 || dp[i] > lv {
			dp[i] = lv
		}
	}
//	fmt.Printf("dp=%d\n", dp)
	fmt.Printf("%d\n", dp[m])

}

/*
209761007
933100336
1142861343
*/


package main

import (
	"bufio"
	"fmt"
	"os"
)

var (
	que    []*Qpair
	height []int
	cost   []int64
	qf     int
	qr     int
)

type block struct {
	len int
	h   []int
	c   []int
}

type Qpair struct {
	w int
	v int64
}

func addQue(w int, v int64) {
	if qr == qf {
		que[qr] = &Qpair{
			w: w,
			v: v,
		}
		qr++
		return
	}
	if que[qr-1].w == w {
		if v < que[qr-1].v {
			que[qr-1].v = v
		}
		return
	}
	if que[qr-1].v > v {
		que[qr] = &Qpair{
			w: w,
			v: v,
		}
		qr++
		return
	}
	return
}
func findQue(w int) int64 {
	for qf < qr && que[qr-1].w < w {
		qr--
	}
	if qf == qr {
		return -1
	}
	return que[qr-1].v
}

func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m, k, q int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	dp := make([]int64, m+1)
	que = make([]*Qpair, m+1)
	height = make([]int, m+1)
	cost = make([]int64, m+1)
	blocks := make([]*block, n+1)

	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d\n", &k)
		b := &block{
			len: k,
			h:   make([]int, k),
			c:   make([]int, k),
		}
		for j := 0; j < k; j++ {
			fmt.Fscanf(buf, "%d", &b.h[j])
		}
		fmt.Fscanf(buf, "\n")
		for j := 0; j < k; j++ {
			fmt.Fscanf(buf, "%d", &b.c[j])
		}
		fmt.Fscanf(buf, "\n")
		blocks[i+1] = b

	}
	fmt.Fscanf(buf, "%d\n", &q)
	var mul int64
	front := 1
	for i := 0; i < q; i++ {
		fmt.Fscanf(buf, "%d %d\n", &k, &mul)
		for j := 0; j < blocks[k].len; j++ {
			height[front] = blocks[k].h[j]
			cost[front] = int64(blocks[k].c[j]) * mul
			front++
		}
	}
	left := make([]int, m+1)
	right := make([]int, m+1)
	pre := m
	for i := 1; i <= m; i++ {
		if i == 1 || height[i] == 1 {
			pre = i
			left[i] = i
			continue
		}
		if pre > 1 && i-height[i]+1 < pre {
			minf := i - height[i] + 1
			for j := pre - 1; minf > 1 && j >= minf; j-- {
				if j-height[j]+1 < minf {
					minf = j - height[j] + 1
				}
			}
			if minf <= 1 {
				minf = 1
			}
			pre = minf
		}
		left[i] = pre
	}
	front = m
	for i := m; i >= 1; i-- {
		if height[i] == 1 {
			front = i
			right[i] = i
			continue
		}
		if front < m && i+height[i]-1 > front {
			maxf := i + height[i] - 1
			for j := front + 1; maxf < m && j <= maxf; j++ {
				if j+height[j]-1 > maxf {
					maxf = j + height[j] - 1
				}
			}
			if maxf > m {
				maxf = m
			}
			front = maxf
		}
		right[i] = front
	}
	//fmt.Printf("h== %v\n", height)
	//fmt.Printf("c== %v\n", cost)
	//fmt.Printf("left== %v\n", left)
	//fmt.Printf("right== %v\n", right)
	for i := 1; i <= m; i++ {

		addQue(right[i], dp[i-1]+cost[i])
		if qr == qf {
			if que[qr] == nil {
				que[qr] = &Qpair{

				}
			}
			que[qr].w = right[i]
			que[qr].v = dp[i-1] + cost[i]
			qr++

		} else if que[qr-1].w == right[i] {
			if dp[i-1]+cost[i] < que[qr-1].v {
				que[qr-1].v = dp[i-1] + cost[i]
			}

		} else if que[qr-1].v > dp[i-1]+cost[i] {
			if que[qr] == nil {
				que[qr] = &Qpair{

				}
			}
			que[qr].w = right[i]
			que[qr].v = dp[i-1] + cost[i]
			qr++

		}

		dp[i] = -1
		if qr > qf {
			dp[i] = que[qr-1].v
		}

		var lv int64 = cost[i]
		//	fmt.Printf("i=%d front=%d add = %d dp=%d lv=%d\n", i, right[i],  dp[i-1]+int64(cost[i]), dp[i], lv)
		pre = left[i]
		if pre-1 > 0 {
			lv += dp[pre-1]
		}
		if dp[i] <= 0 || dp[i] > lv {
			dp[i] = lv
		}
		for qr > qf && que[qr-1].w <= i {
			qr--
		}
	}
	//	fmt.Printf("dp=%d\n", dp)
	fmt.Printf("%d\n", dp[m])

}

/*
1 10
10
1 1 2 1 1 1 2 1 1 1
1 1 1 1 1 1 1 1 1 1
1
1 1
*/


package main

import (
	"bufio"
	"fmt"
	"os"
)

var (
	que    []*Qpair
	height []int
	cost   []int64
	qf     int
	qr     int
)

type block struct {
	len int
	h   []int
	c   []int
}

type Qpair struct {
	w int
	v int64
}

func addQue(w int, v int64) {
	for qr > qf && que[qr-1].v >= v {
		qr--
	}
	if qr > qf && que[qr-1].w == w {
		return
	}
	if que[qr] == nil {
		que[qr] = &Qpair{
		}
	}
	que[qr].v = v
	que[qr].w = w
	qr++

}
func findQue(w int) int64 {
	for qf < qr && que[qf].w < w {
		qf++
	}
	if qf == qr {
		return -1
	}
	return que[qf].v
}

func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m, k, q int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	dp := make([]int64, m+1)
	que = make([]*Qpair, m+1)
	height = make([]int, m+1)
	cost = make([]int64, m+1)
	blocks := make([]*block, n+1)

	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d\n", &k)
		b := &block{
			len: k,
			h:   make([]int, k),
			c:   make([]int, k),
		}
		for j := 0; j < k; j++ {
			fmt.Fscanf(buf, "%d", &b.h[j])
		}
		fmt.Fscanf(buf, "\n")
		for j := 0; j < k; j++ {
			fmt.Fscanf(buf, "%d", &b.c[j])
		}
		fmt.Fscanf(buf, "\n")
		blocks[i+1] = b

	}
	fmt.Fscanf(buf, "%d\n", &q)
	var mul int64
	front := 1
	for i := 0; i < q; i++ {
		fmt.Fscanf(buf, "%d %d\n", &k, &mul)
		for j := 0; j < blocks[k].len; j++ {
			height[front] = blocks[k].h[j]
			cost[front] = int64(blocks[k].c[j]) * mul
			front++
		}
	}
//	fmt.Printf("h== %v\n",height)
//	fmt.Printf("c== %v\n",cost)
	front = 0
	for i := 1; i <= m; i++ {
		if i == 1 || height[i-1] == 1 {
			maxf := i
			for j := i; j <= maxf; j++ {
				if j+height[j] > maxf {
					maxf = j + height[j] - 1
					if maxf > m{
						maxf=m
					}
				}
			}
			front = maxf
		}
		addQue(front, dp[i-1]+int64(cost[i]))
		dp[i] = findQue(i)
	//	fmt.Printf("i=%d front=%d dp=%d\n",i,front,dp[i])
		var lv int64 = int64(cost[i])
		if i-height[i] > 0 {
			lv += dp[i-height[i]]
		}
		if dp[i] <= 0 || dp[i] > lv {
			dp[i] = lv
		}
	}
//	fmt.Printf("dp=%d\n",dp)
	fmt.Printf("%d\n", dp[m])

}


import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;

public class G {
    static class MinSegmentTree {
        final long ABSENT_VALUE = Long.MAX_VALUE;
        private int size;
        final private long[] a;

        MinSegmentTree(int n) {
            size = 1;
            while (size <= n) {
                size *= 2;
            }
            a = new long[2 * size];
            Arrays.fill(a, ABSENT_VALUE);
        }

        final void set(int i, long value) {
            a[size + i] = value;
            for (int j = (size + i) / 2; j > 0; j /= 2) {
                a[j] = Math.min(a[2 * j], a[2 * j + 1]);
            }
        }

        final void setIfBetter(int i, long value) {
            if (a[size + i] > value) {
                set(i, value);
            }
        }

        final long getMin(int l, int r) {
            long min = ABSENT_VALUE;
            for (l += size, r += size; l < r; l /= 2, r /= 2) {
                if (l % 2 == 1) {
                    min = Math.min(min, a[l++]);
                }
                if (r % 2 == 1) {
                    min = Math.min(min, a[--r]);
                }
            }
            return min;
        }
    }

    public static void main(String[] args) throws IOException {
        try (Input input = new StandardInput(); PrintWriter writer = new PrintWriter(System.out)) {
            int blockCount = input.nextInt();
            int totalDominoes = input.nextInt();
            int[][] heights = new int[blockCount][];
            int[][] costs = new int[blockCount][];
            for (int b = 0; b < blockCount; b++) {
                int blockSize = input.nextInt();
                heights[b] = input.nextIntArray(blockSize);
                costs[b] = input.nextIntArray(blockSize);
            }
            int[] h = new int[totalDominoes];
            long[] c = new long[totalDominoes];
            int offset = 0;
            for (int k = input.nextInt(); k > 0; k--) {
                int block = input.nextInt() - 1;
                long costMultiplier = input.nextInt();
                System.arraycopy(heights[block], 0, h, offset, heights[block].length);
                for (int cost : costs[block]) {
                    c[offset++] = costMultiplier * cost;
                }
            }
            int[] leftStack = new int[totalDominoes];
            int leftTop = 0;
            MinSegmentTree fallRight = new MinSegmentTree(totalDominoes + 1);
            long[] dp = new long[totalDominoes + 1];
            for (int i = 0; i < totalDominoes; i++) {
                int left = i - h[i];
                while (leftTop > 0 && left < leftStack[leftTop]) {
                    leftTop--;
                }
                if (leftTop > 0) {
                    left = leftStack[leftTop];
                } else {
                    left = -1;
                }
                leftStack[leftTop++] = i;
                long bestFromPredecessors = fallRight.getMin(i + 1, totalDominoes + 1);
                dp[i + 1] = Math.min(bestFromPredecessors, c[i] + dp[left + 1]);
                fallRight.setIfBetter(Math.min(totalDominoes, i + h[i]), Math.min(dp[i] + c[i], bestFromPredecessors));
            }
            writer.println(dp[totalDominoes]);
        }
    }

    interface Input extends Closeable {
        String next() throws IOException;

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

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

        default int[] nextIntArray(int size) throws IOException {
            int[] array = new int[size];
            for (int i = 0; i < size; i++) {
                array[i] = nextInt();
            }
            return array;
        }
    }

    private static class StandardInput implements Input {
        private final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        private StringTokenizer stringTokenizer;

        @Override
        public void close() throws IOException {
            reader.close();
        }

        @Override
        public String next() throws IOException {
            if (stringTokenizer == null || !stringTokenizer.hasMoreTokens()) {
                stringTokenizer = new StringTokenizer(reader.readLine());
            }
            return stringTokenizer.nextToken();
        }
    }
}


import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;

public class G {
    static class MinSegmentTree {
        final long ABSENT_VALUE = Long.MAX_VALUE;
        private int size;
        final private long[] a;

        MinSegmentTree(int n) {
            size = 1;
            while (size <= n) {
                size *= 2;
            }
            a = new long[2 * size];
            Arrays.fill(a, ABSENT_VALUE);
        }

        final void set(int i, long value) {
            a[size + i] = value;
            for (int j = (size + i) / 2; j > 0; j /= 2) {
                a[j] = Math.min(a[2 * j], a[2 * j + 1]);
            }
        }

        final void setIfBetter(int i, long value) {
            if (a[size + i] > value) {
                set(i, value);
            }
        }

        final long getMin(int l, int r) {
            long min = ABSENT_VALUE;
            for (l += size, r += size; l < r; l /= 2, r /= 2) {
                if (l % 2 == 1) {
                    min = Math.min(min, a[l++]);
                }
                if (r % 2 == 1) {
                    min = Math.min(min, a[--r]);
                }
            }
            return min;
        }
    }

    public static void main(String[] args) throws IOException {
        try (Input input = new StandardInput(); PrintWriter writer = new PrintWriter(System.out)) {
            int blockCount = input.nextInt();
            int totalDominoes = input.nextInt();
            int[][] heights = new int[blockCount][];
            int[][] costs = new int[blockCount][];
            for (int b = 0; b < blockCount; b++) {
                int blockSize = input.nextInt();
                heights[b] = input.nextIntArray(blockSize);
                costs[b] = input.nextIntArray(blockSize);
            }
            int[] h = new int[totalDominoes];
            long[] c = new long[totalDominoes];
            int offset = 0;
            for (int k = input.nextInt(); k > 0; k--) {
                int block = input.nextInt() - 1;
                long costMultiplier = input.nextInt();
                System.arraycopy(heights[block], 0, h, offset, heights[block].length);
                for (int cost : costs[block]) {
                    c[offset++] = costMultiplier * cost;
                }
            }
            int[] leftStack = new int[totalDominoes];
            int leftTop = 0;
            MinSegmentTree fallRight = new MinSegmentTree(totalDominoes + 1);
            long[] dp = new long[totalDominoes + 1];
            for (int i = 0; i < totalDominoes; i++) {
                int left = i - h[i];
                while (leftTop > 0 && left < leftStack[leftTop - 1]) {
                    leftTop--;
                }
                if (leftTop > 0) {
                    left = leftStack[leftTop - 1];
                } else {
                    left = -1;
                }
                leftStack[leftTop++] = i;
                long bestFromPredecessors = fallRight.getMin(i + 1, totalDominoes + 1);
                dp[i + 1] = Math.min(bestFromPredecessors, c[i] + dp[left + 1]);
                fallRight.setIfBetter(Math.min(totalDominoes, i + h[i]), Math.min(dp[i] + c[i], bestFromPredecessors));
            }
            writer.println(dp[totalDominoes]);
        }
    }

    interface Input extends Closeable {
        String next() throws IOException;

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

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

        default int[] nextIntArray(int size) throws IOException {
            int[] array = new int[size];
            for (int i = 0; i < size; i++) {
                array[i] = nextInt();
            }
            return array;
        }
    }

    private static class StandardInput implements Input {
        private final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        private StringTokenizer stringTokenizer;

        @Override
        public void close() throws IOException {
            reader.close();
        }

        @Override
        public String next() throws IOException {
            if (stringTokenizer == null || !stringTokenizer.hasMoreTokens()) {
                stringTokenizer = new StringTokenizer(reader.readLine());
            }
            return stringTokenizer.nextToken();
        }
    }
}


import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;

public class G {
    static class MinSegmentTree {
        final long ABSENT_VALUE = Long.MAX_VALUE;
        private int size;
        final private long[] a;

        MinSegmentTree(int n) {
            size = 1;
            while (size <= n) {
                size *= 2;
            }
            a = new long[2 * size];
            Arrays.fill(a, ABSENT_VALUE);
        }

        final void set(int i, long value) {
            a[size + i] = value;
            for (int j = (size + i) / 2; j > 0; j /= 2) {
                a[j] = Math.min(a[2 * j], a[2 * j + 1]);
            }
        }

        final void setIfBetter(int i, long value) {
            if (a[size + i] > value) {
                set(i, value);
            }
        }

        final long getMin(int l, int r) {
            long min = ABSENT_VALUE;
            for (l += size, r += size; l < r; l /= 2, r /= 2) {
                if (l % 2 == 1) {
                    min = Math.min(min, a[l++]);
                }
                if (r % 2 == 1) {
                    min = Math.min(min, a[--r]);
                }
            }
            return min;
        }
    }

    public static void main(String[] args) throws IOException {
        try (Input input = new StandardInput(); PrintWriter writer = new PrintWriter(System.out)) {
            int blockCount = input.nextInt();
            int totalDominoes = input.nextInt();
            int[][] heights = new int[blockCount][];
            int[][] costs = new int[blockCount][];
            for (int b = 0; b < blockCount; b++) {
                int blockSize = input.nextInt();
                heights[b] = input.nextIntArray(blockSize);
                costs[b] = input.nextIntArray(blockSize);
            }
            int[] h = new int[totalDominoes];
            long[] c = new long[totalDominoes];
            int offset = 0;
            for (int k = input.nextInt(); k > 0; k--) {
                int block = input.nextInt() - 1;
                long costMultiplier = input.nextInt();
                System.arraycopy(heights[block], 0, h, offset, heights[block].length);
                for (int cost : costs[block]) {
                    c[offset++] = costMultiplier * cost;
                }
            }
            MinSegmentTree fallLeft = new MinSegmentTree(totalDominoes);
            MinSegmentTree fallRight = new MinSegmentTree(totalDominoes + 1);
            long[] dp = new long[totalDominoes + 1];
            for (int i = 0; i < totalDominoes; i++) {
                long left = i - h[i];
                left = Math.max(-1, left);
                left = Math.min(left, fallLeft.getMin((int)left + 1, i));
                fallLeft.set(i, left);
                dp[i + 1] = Math.min(fallRight.getMin(i + 1, totalDominoes + 1), c[i] + dp[(int)left + 1]);
                fallRight.setIfBetter(Math.min(totalDominoes + 1, i + h[i]), dp[i + 1]);
            }
            writer.println(dp[totalDominoes]);
        }
    }

    interface Input extends Closeable {
        String next() throws IOException;

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

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

        default int[] nextIntArray(int size) throws IOException {
            int[] array = new int[size];
            for (int i = 0; i < size; i++) {
                array[i] = nextInt();
            }
            return array;
        }
    }

    private static class StandardInput implements Input {
        private final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        private StringTokenizer stringTokenizer;

        @Override
        public void close() throws IOException {
            reader.close();
        }

        @Override
        public String next() throws IOException {
            if (stringTokenizer == null || !stringTokenizer.hasMoreTokens()) {
                stringTokenizer = new StringTokenizer(reader.readLine());
            }
            return stringTokenizer.nextToken();
        }
    }
}


import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;

public class G {
    static class MinSegmentTree {
        final long ABSENT_VALUE = Long.MAX_VALUE;
        private int size;
        final private long[] a;

        MinSegmentTree(int n) {
            size = 1;
            while (size <= n) {
                size *= 2;
            }
            a = new long[2 * size];
            Arrays.fill(a, ABSENT_VALUE);
        }

        final void set(int i, long value) {
            a[size + i] = value;
            for (int j = (size + i) / 2; j > 0; j /= 2) {
                a[j] = Math.min(a[2 * j], a[2 * j + 1]);
            }
        }

        final void setIfBetter(int i, long value) {
            if (a[size + i] > value) {
                set(i, value);
            }
        }

        final long getMin(int l, int r) {
            long min = ABSENT_VALUE;
            for (l += size, r += size; l < r; l /= 2, r /= 2) {
                if (l % 2 == 1) {
                    min = Math.min(min, a[l++]);
                }
                if (r % 2 == 1) {
                    min = Math.min(min, a[--r]);
                }
            }
            return min;
        }
    }

    public static void main(String[] args) throws IOException {
        try (Input input = new StandardInput(); PrintWriter writer = new PrintWriter(System.out)) {
            int blockCount = input.nextInt();
            int totalDominoes = input.nextInt();
            int[][] heights = new int[blockCount][];
            int[][] costs = new int[blockCount][];
            for (int b = 0; b < blockCount; b++) {
                int blockSize = input.nextInt();
                heights[b] = input.nextIntArray(blockSize);
                costs[b] = input.nextIntArray(blockSize);
            }
            int[] h = new int[totalDominoes];
            long[] c = new long[totalDominoes];
            int offset = 0;
            for (int k = input.nextInt(); k > 0; k--) {
                int block = input.nextInt() - 1;
                long costMultiplier = input.nextInt();
                System.arraycopy(heights[block], 0, h, offset, heights[block].length);
                for (int cost : costs[block]) {
                    c[offset++] = costMultiplier * cost;
                }
            }
            MinSegmentTree fallLeft = new MinSegmentTree(totalDominoes);
            MinSegmentTree fallRight = new MinSegmentTree(totalDominoes + 1);
            long[] dp = new long[totalDominoes + 1];
            for (int i = 0; i < totalDominoes; i++) {
                long left = i - h[i];
                left = Math.max(-1, left);
                left = Math.min(left, fallLeft.getMin((int)left + 1, i));
                fallLeft.set(i, left);
                long bestFromPredecessors = fallRight.getMin(i + 1, totalDominoes + 1);
                dp[i + 1] = Math.min(bestFromPredecessors, c[i] + dp[(int)left + 1]);
                fallRight.setIfBetter(Math.min(totalDominoes, i + h[i]), Math.min(dp[i] + c[i], bestFromPredecessors));
            }
            writer.println(dp[totalDominoes]);
        }
    }

    interface Input extends Closeable {
        String next() throws IOException;

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

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

        default int[] nextIntArray(int size) throws IOException {
            int[] array = new int[size];
            for (int i = 0; i < size; i++) {
                array[i] = nextInt();
            }
            return array;
        }
    }

    private static class StandardInput implements Input {
        private final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        private StringTokenizer stringTokenizer;

        @Override
        public void close() throws IOException {
            reader.close();
        }

        @Override
        public String next() throws IOException {
            if (stringTokenizer == null || !stringTokenizer.hasMoreTokens()) {
                stringTokenizer = new StringTokenizer(reader.readLine());
            }
            return stringTokenizer.nextToken();
        }
    }
}


import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;

public class G {
    static class MinSegmentTree {
        final long ABSENT_VALUE = Long.MAX_VALUE;
        private int size;
        final private long[] a;

        MinSegmentTree(int n) {
            size = 1;
            while (size <= n) {
                size *= 2;
            }
            a = new long[2 * size];
            Arrays.fill(a, ABSENT_VALUE);
        }

        final void set(int i, long value) {
            a[size + i] = value;
            for (int j = (size + i) / 2; j > 0; j /= 2) {
                a[j] = Math.min(a[2 * j], a[2 * j + 1]);
            }
        }

        final void setIfBetter(int i, long value) {
            if (a[size + i] > value) {
                set(i, value);
            }
        }

        final long getMin(int l, int r) {
            long min = ABSENT_VALUE;
            for (l += size, r += size; l < r; l /= 2, r /= 2) {
                if (l % 2 == 1) {
                    min = Math.min(min, a[l++]);
                }
                if (r % 2 == 1) {
                    min = Math.min(min, a[--r]);
                }
            }
            return min;
        }
    }

    public static void main(String[] args) throws IOException {
        try (Input input = new StandardInput(); PrintWriter writer = new PrintWriter(System.out)) {
            int blockCount = input.nextInt();
            int totalDominoes = input.nextInt();
            int[][] heights = new int[blockCount][];
            int[][] costs = new int[blockCount][];
            for (int b = 0; b < blockCount; b++) {
                int blockSize = input.nextInt();
                heights[b] = input.nextIntArray(blockSize);
                costs[b] = input.nextIntArray(blockSize);
            }
            int[] h = new int[totalDominoes];
            long[] c = new long[totalDominoes];
            int offset = 0;
            for (int k = input.nextInt(); k > 0; k--) {
                int block = input.nextInt() - 1;
                long costMultiplier = input.nextInt();
                System.arraycopy(heights[block], 0, h, offset, heights[block].length);
                for (int cost : costs[block]) {
                    c[offset++] = costMultiplier * cost;
                }
            }
            MinSegmentTree fallLeft = new MinSegmentTree(totalDominoes);
            MinSegmentTree fallRight = new MinSegmentTree(totalDominoes + 1);
            long[] dp = new long[totalDominoes + 1];
            for (int i = 0; i < totalDominoes; i++) {
                long left = i - h[i];
                left = Math.max(-1, left);
                left = Math.min(left, fallLeft.getMin((int)left + 1, i));
                fallLeft.set(i, left);
                long bestFromPredecessors = fallRight.getMin(i + 1, totalDominoes + 1);
                dp[i + 1] = Math.min(bestFromPredecessors, c[i] + dp[(int)left + 1]);
                fallRight.setIfBetter(Math.min(totalDominoes + 1, i + h[i]), Math.min(dp[i] + c[i], bestFromPredecessors));
            }
            writer.println(dp[totalDominoes]);
        }
    }

    interface Input extends Closeable {
        String next() throws IOException;

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

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

        default int[] nextIntArray(int size) throws IOException {
            int[] array = new int[size];
            for (int i = 0; i < size; i++) {
                array[i] = nextInt();
            }
            return array;
        }
    }

    private static class StandardInput implements Input {
        private final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        private StringTokenizer stringTokenizer;

        @Override
        public void close() throws IOException {
            reader.close();
        }

        @Override
        public String next() throws IOException {
            if (stringTokenizer == null || !stringTokenizer.hasMoreTokens()) {
                stringTokenizer = new StringTokenizer(reader.readLine());
            }
            return stringTokenizer.nextToken();
        }
    }
}


import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;

public class G {
    static class MinSegmentTree {
        final long ABSENT_VALUE = Long.MAX_VALUE;
        private int size;
        final private long[] a;

        MinSegmentTree(int n) {
            size = 1;
            while (size <= n) {
                size *= 2;
            }
            a = new long[2 * size];
            Arrays.fill(a, ABSENT_VALUE);
        }

        final void set(int i, long value) {
            a[size + i] = value;
            for (int j = (size + i) / 2; j > 0; j /= 2) {
                a[j] = Math.min(a[2 * j], a[2 * j + 1]);
            }
        }

        final void setIfBetter(int i, long value) {
            if (a[size + i] > value) {
                set(i, value);
            }
        }

        final long getMin(int l, int r) {
            long min = ABSENT_VALUE;
            for (l += size, r += size; l < r; l /= 2, r /= 2) {
                if (l % 2 == 1) {
                    min = Math.min(min, a[l++]);
                }
                if (r % 2 == 1) {
                    min = Math.min(min, a[--r]);
                }
            }
            return min;
        }
    }

    public static void main(String[] args) throws IOException {
        try (Input input = new StandardInput(); PrintWriter writer = new PrintWriter(System.out)) {
            int blockCount = input.nextInt();
            int totalDominoes = input.nextInt();
            int[][] heights = new int[blockCount][];
            int[][] costs = new int[blockCount][];
            for (int b = 0; b < blockCount; b++) {
                int blockSize = input.nextInt();
                heights[b] = input.nextIntArray(blockSize);
                costs[b] = input.nextIntArray(blockSize);
            }
            int[] h = new int[totalDominoes];
            long[] c = new long[totalDominoes];
            int offset = 0;
            for (int k = input.nextInt(); k > 0; k--) {
                int block = input.nextInt() - 1;
                long costMultiplier = input.nextInt();
                System.arraycopy(heights[block], 0, h, offset, heights[block].length);
                for (int cost : costs[block]) {
                    c[offset++] = costMultiplier * cost;
                }
            }
            int[] leftStack = new int[totalDominoes];
            int leftTop = 0;
            MinSegmentTree fallRight = new MinSegmentTree(totalDominoes + 1);
            long[] dp = new long[totalDominoes + 1];
            for (int i = 0; i < totalDominoes; i++) {
                int left = i - h[i];
                while (leftTop > 0 && left < leftStack[leftTop]) {
                    leftTop--;
                }
                if (leftTop > 0) {
                    left = leftStack[leftTop - 1];
                } else {
                    left = -1;
                }
                leftStack[leftTop++] = i;
                long bestFromPredecessors = fallRight.getMin(i + 1, totalDominoes + 1);
                dp[i + 1] = Math.min(bestFromPredecessors, c[i] + dp[left + 1]);
                fallRight.setIfBetter(Math.min(totalDominoes, i + h[i]), Math.min(dp[i] + c[i], bestFromPredecessors));
            }
            writer.println(dp[totalDominoes]);
        }
    }

    interface Input extends Closeable {
        String next() throws IOException;

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

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

        default int[] nextIntArray(int size) throws IOException {
            int[] array = new int[size];
            for (int i = 0; i < size; i++) {
                array[i] = nextInt();
            }
            return array;
        }
    }

    private static class StandardInput implements Input {
        private final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        private StringTokenizer stringTokenizer;

        @Override
        public void close() throws IOException {
            reader.close();
        }

        @Override
        public String next() throws IOException {
            if (stringTokenizer == null || !stringTokenizer.hasMoreTokens()) {
                stringTokenizer = new StringTokenizer(reader.readLine());
            }
            return stringTokenizer.nextToken();
        }
    }
}


import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;

public class G {
    public static void main(String[] args) throws IOException {
        try (Input input = new StandardInput(); PrintWriter writer = new PrintWriter(System.out)) {
            int blockCount = input.nextInt();
            int totalDominoes = input.nextInt();
            int[][] heights = new int[blockCount][];
            int[][] costs = new int[blockCount][];
            for (int b = 0; b < blockCount; b++) {
                int blockSize = input.nextInt();
                heights[b] = input.nextIntArray(blockSize);
                costs[b] = input.nextIntArray(blockSize);
            }
            int[] h = new int[totalDominoes];
            long[] c = new long[totalDominoes];
            int offset = 0;
            for (int k = input.nextInt(); k > 0; k--) {
                int block = input.nextInt() - 1;
                long costMultiplier = input.nextInt();
                System.arraycopy(heights[block], 0, h, offset, heights[block].length);
                for (int cost : costs[block]) {
                    c[offset++] = costMultiplier * cost;
                }
            }
            int[] leftStack = new int[totalDominoes];
            int leftTop = 0;
            int[] rightStack = new int[totalDominoes];
            long[] rightStackValue = new long[totalDominoes];
            int rightTop = 0;
            long[] dp = new long[totalDominoes + 1];
            for (int i = 0; i < totalDominoes; i++) {
                int left = i - h[i];
                while (leftTop > 0 && left < leftStack[leftTop - 1]) {
                    leftTop--;
                }
                if (leftTop > 0) {
                    left = leftStack[leftTop - 1];
                } else {
                    left = -1;
                }
                leftStack[leftTop++] = i;
                while (rightTop > 0 && rightStack[rightTop - 1] <= i) {
                    rightTop--;
                }
                long bestFromPredecessors = rightTop == 0 ? Long.MAX_VALUE : rightStackValue[rightTop - 1];
                dp[i + 1] = Math.min(bestFromPredecessors, c[i] + dp[left + 1]);
                bestFromPredecessors = Math.min(bestFromPredecessors, dp[i] + c[i]);
                while (rightTop > 0 && rightStack[rightTop - 1] < i + h[i]) {
                    rightTop--;
                }
                if (rightTop == 0 || rightStackValue[rightTop - 1] != bestFromPredecessors) {
                    rightStack[rightTop] = i + h[i];
                    rightStackValue[rightTop++] = bestFromPredecessors;
                }
            }
            writer.println(dp[totalDominoes]);
        }
    }

    interface Input extends Closeable {
        String next() throws IOException;

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

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

        default int[] nextIntArray(int size) throws IOException {
            int[] array = new int[size];
            for (int i = 0; i < size; i++) {
                array[i] = nextInt();
            }
            return array;
        }
    }

    private static class StandardInput implements Input {
        private final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        private StringTokenizer stringTokenizer;

        @Override
        public void close() throws IOException {
            reader.close();
        }

        @Override
        public String next() throws IOException {
            if (stringTokenizer == null || !stringTokenizer.hasMoreTokens()) {
                stringTokenizer = new StringTokenizer(reader.readLine());
            }
            return stringTokenizer.nextToken();
        }
    }
}


//package round541;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class G {
	InputStream is;
	PrintWriter out;
	String INPUT = "";
//	String INPUT = "1 7\n" +
//			"7\n" +
//			"1 3 1 1 1 5 1\n" +
//			"1 1 4 5 1 4 8\n" + "1 1 1";
//	String INPUT = "2 7\n" +
//			"3\n" +
//			"1 2 2\n" +
//			"1 2 1\n" +
//			"1\n" +
//			"3\n" +
//			"2\n" +
//			"3\n" +
//			"2 2\n" +
//			"1 3\n" +
//			"1 1";

	void solve()
	{
		int n = ni(), m = ni();
		int[][] as = new int[n][];
		int[][] cs = new int[n][];
		for(int i = 0;i < n;i++){
			int K = ni();
			as[i] = na(K);
			cs[i] = na(K);
		}

		int[] hs = new int[m];
		long[] costs = new long[m];

		int p = 0;
		int Q = ni();
		for(int z = 0;z < Q;z++){
			int id = ni()-1, mul = ni();
			for(int j = 0;j < as[id].length;j++){
				hs[p] = as[id][j];
				costs[p] = (long)cs[id][j] * mul;
				p++;
			}
		}

//		tr(hs);
//		tr(costs);
//
		assert p == m;

		out.println(minimumDominoCost(hs, costs));
	}

	long minimumDominoCost(int[] hs, long[] costs)
	{
		int n = hs.length;
		assert n == costs.length;
		int[] pre = enumDominoReaches(hs);
		int[] suf = enumDominoReaches(rev_(hs));

		int[][] g = hopBucket(suf, n);
		long[] dp = new long[n+1];
		Arrays.fill(dp, Long.MAX_VALUE / 2);
		dp[0] = 0;

		int[] stack = new int[n+1]; // pos
		int sp = 0;
		stack[sp++] = 0;
		for(int i = 0;i < n;i++){
			// merge
			// dp[pre[i], i) + cost[i]
			while(sp-2 >= 0 && stack[sp-2] >= pre[i]){
				dp[stack[sp-2]] = Math.min(dp[stack[sp-2]], dp[stack[sp-1]]);
				sp--;
			}
//			tr("stack", Arrays.copyOf(stack, sp));
			assert sp-1 >= 0;
			dp[i+1] = Math.min(dp[i+1], dp[stack[sp-1]] + costs[i]);
//			tr("z", i+1, dp[i+1]);
			stack[sp++] = i+1;

			// dp[j-1] + cost[j] (j -> i)
			for(int j = g[0][n-1-i];j != -1;j = g[1][j]){
				dp[i+1] = Math.min(dp[i+1], dp[n-1-j] + costs[n-1-j]);
			}
		}

//		tr(dp);
		return dp[n];
	}

	public int[][] hopBucket(int[] a, int m)
	{
		int n = a.length;
		int[] first = new int[m];
		Arrays.fill(first, -1);
		int[] next = new int[n];
		for(int i = n-1;i >= 0;i--) {
			next[i] = first[a[i]];
			first[a[i]] = i;
		}
		return new int[][]{first, next};
	}

	public static int[] rev(int[] a)
	{
		int[] b = new int[a.length];
		for(int i = 0;i < a.length;i++)b[a.length-1-i] = a[i];
		return b;
	}

	public static int[] rev_(int[] a)
	{
		for(int i = 0, j = a.length-1;i < j;i++,j--){
			int c = a[i]; a[i] = a[j]; a[j] = c;
		}
		return a;
	}

	int[] enumDominoReaches(int[] hs)
	{
		int n = hs.length;
		int[] reach = new int[n];
		int[] stack = new int[n];
		int sp = 0;
		for(int i = 0;i < n;i++){
			// fall (i-hs[i], i]
			int min = i-hs[i]+1;
			while(sp > 0 && stack[sp-1] > i-hs[i]) {
				min = Math.min(min, reach[stack[sp-1]]);
				sp--;
			}
			reach[i] = Math.max(min, 0);
			stack[sp++] = i;
		}
		return reach;
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new G().run(); }

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


//package round541;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class G {
	InputStream is;
	PrintWriter out;
	String INPUT = "";
//	String INPUT = "1 7\n" +
//			"7\n" +
//			"1 3 1 1 1 5 1\n" +
//			"1 1 4 5 1 4 8\n" + "1 1 1";
//	String INPUT = "2 7\n" +
//			"3\n" +
//			"1 2 2\n" +
//			"1 2 1\n" +
//			"1\n" +
//			"3\n" +
//			"2\n" +
//			"3\n" +
//			"2 2\n" +
//			"1 3\n" +
//			"1 1";

	void solve()
	{
		int n = ni(), m = ni();
		int[][] as = new int[n][];
		int[][] cs = new int[n][];
		for(int i = 0;i < n;i++){
			int K = ni();
			as[i] = na(K);
			cs[i] = na(K);
		}

		int[] hs = new int[m];
		long[] costs = new long[m];

		int p = 0;
		int Q = ni();
		for(int z = 0;z < Q;z++){
			int id = ni()-1, mul = ni();
			for(int j = 0;j < as[id].length;j++){
				hs[p] = as[id][j];
				costs[p] = (long)cs[id][j] * mul;
				p++;
			}
		}

//		tr(hs);
//		tr(costs);
//
		assert p == m;

		out.println(minimumDominoCost(hs, costs));
	}

	long minimumDominoCost(int[] hs, long[] costs)
	{
		int n = hs.length;
		assert n == costs.length;
		int[] pre = enumDominoReaches(hs);
		int[] suf = enumDominoReaches(rev(hs));

		int[][] g = hopBucket(suf, n);
		long[] dp = new long[n+1];
		Arrays.fill(dp, Long.MAX_VALUE / 2);
		dp[0] = 0;

		int[] stack = new int[n+1]; // pos
		int sp = 0;
		stack[sp++] = 0;
		for(int i = 0;i < n;i++){
			// merge
			// dp[pre[i], i) + cost[i]
			while(sp-2 >= 0 && stack[sp-2] >= pre[i]){
				dp[stack[sp-2]] = Math.min(dp[stack[sp-2]], dp[stack[sp-1]]);
				sp--;
			}
//			tr("stack", Arrays.copyOf(stack, sp));
			assert sp-1 >= 0;
			dp[i+1] = Math.min(dp[i+1], dp[stack[sp-1]] + costs[i]);
//			tr("z", i+1, dp[i+1]);
			stack[sp++] = i+1;

			// dp[j-1] + cost[j] (j -> i)
			for(int j = g[0][n-1-i];j != -1;j = g[1][j]){
				dp[i+1] = Math.min(dp[i+1], dp[n-1-j] + costs[n-1-j]);
			}
		}

//		tr(dp);
		return dp[n];
	}

	public int[][] hopBucket(int[] a, int m)
	{
		int n = a.length;
		int[] first = new int[m];
		Arrays.fill(first, -1);
		int[] next = new int[n];
		for(int i = n-1;i >= 0;i--) {
			next[i] = first[a[i]];
			first[a[i]] = i;
		}
		return new int[][]{first, next};
	}

	public static int[] rev(int[] a)
	{
		int[] b = new int[a.length];
		for(int i = 0;i < a.length;i++)b[a.length-1-i] = a[i];
		return b;
	}

	int[] enumDominoReaches(int[] hs)
	{
		int n = hs.length;
		int[] reach = new int[n];
		int[] stack = new int[n];
		int sp = 0;
		for(int i = 0;i < n;i++){
			// fall (i-hs[i], i]
			int min = i-hs[i]+1;
			while(sp > 0 && stack[sp-1] > i-hs[i]) {
				min = Math.min(min, reach[stack[sp-1]]);
				sp--;
			}
			reach[i] = Math.max(min, 0);
			stack[sp++] = i;
		}
		return reach;
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new G().run(); }

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


//package round541;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class G {
	InputStream is;
	PrintWriter out;
	String INPUT = "";
//	String INPUT = "1 7\n" +
//			"7\n" +
//			"1 3 1 1 1 5 1\n" +
//			"1 1 4 5 1 4 8\n" + "1 1 1";
//	String INPUT = "2 7\n" +
//			"3\n" +
//			"1 2 2\n" +
//			"1 2 1\n" +
//			"1\n" +
//			"3\n" +
//			"2\n" +
//			"3\n" +
//			"2 2\n" +
//			"1 3\n" +
//			"1 1";

	void solve()
	{
		int n = ni(), m = ni();
		int[][] as = new int[n][];
		int[][] cs = new int[n][];
		for(int i = 0;i < n;i++){
			int K = ni();
			as[i] = na(K);
			cs[i] = na(K);
		}

		int[] hs = new int[m];
		long[] costs = new long[m];

		int p = 0;
		int Q = ni();
		for(int z = 0;z < Q;z++){
			int id = ni()-1, mul = ni();
			for(int j = 0;j < as[id].length;j++){
				hs[p] = as[id][j];
				costs[p] = (long)cs[id][j] * mul;
				p++;
			}
		}

//		tr(hs);
//		tr(costs);
//
		assert p == m;

		out.println(minimumDominoCost(hs, costs));
	}

	long minimumDominoCost(int[] hs, long[] costs)
	{
		int n = hs.length;
		assert n == costs.length;
		int[] pre = enumDominoReaches(hs);
		int[] suf = enumDominoReaches(rev(hs));

		int[][] g = hopBucket(suf, n);
		long[] dp = new long[n+1];
		Arrays.fill(dp, Long.MAX_VALUE / 2);
		dp[0] = 0;

		int[] stack = new int[n+1]; // pos
		int sp = 0;
		stack[sp++] = 0;
		for(int i = 0;i < n;i++){
			// merge
			// dp[pre[i], i) + cost[i]
			while(sp-2 >= 0 && stack[sp-2] >= pre[i]){
				dp[stack[sp-2]] = Math.min(dp[stack[sp-2]], dp[stack[sp-1]]);
				sp--;
			}
//			tr("stack", Arrays.copyOf(stack, sp));
			assert sp-1 >= 0;
			dp[i+1] = Math.min(dp[i+1], dp[stack[sp-1]] + costs[i]);
//			tr("z", i+1, dp[i+1]);
			stack[sp++] = i+1;

			// dp[j-1] + cost[j] (j -> i)
			for(int j = g[0][n-1-i];j != -1;j = g[1][j]){
				dp[i+1] = Math.min(dp[i+1], dp[n-1-j] + costs[n-1-j]);
			}
		}

//		tr(dp);
		return dp[n];
	}

	public int[][] hopBucket(int[] a, int m)
	{
		int n = a.length;
		int[] first = new int[m];
		Arrays.fill(first, -1);
		int[] next = new int[n];
		for(int i = 0;i < n;i++){
			next[i] = first[a[i]];
			first[a[i]] = i;
		}
		return new int[][]{first, next};
	}

	public static int[] rev(int[] a)
	{
		int[] b = new int[a.length];
		for(int i = 0;i < a.length;i++)b[a.length-1-i] = a[i];
		return b;
	}

	int[] enumDominoReaches(int[] hs)
	{
		int n = hs.length;
		int[] reach = new int[n];
		int[] stack = new int[n];
		int sp = 0;
		for(int i = 0;i < n;i++){
			// fall (i-hs[i], i]
			int min = i-hs[i]+1;
			while(sp > 0 && stack[sp-1] > i-hs[i]) {
				min = Math.min(min, reach[stack[sp-1]]);
				sp--;
			}
			reach[i] = Math.max(min, 0);
			stack[sp++] = i;
		}
		return reach;
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new G().run(); }

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


import java.util.*;
import java.io.*;
public class Main {
	public static void main(String[] args) throws IOException {
		StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
		in.nextToken();
		int n=(int)in.nval;
		in.nextToken();
		int m=(int)in.nval;
		ArrayList<Integer>[] h=new ArrayList[n+1];
		ArrayList<Long>[] c=new ArrayList[n+1];
		for (int i=1;i<=n;++i) {
			h[i]=new ArrayList();
			c[i]=new ArrayList();
		}
		for (int i=1;i<=n;++i) {
			in.nextToken();
			int k=(int)in.nval;
			for (int j=0;j<k;++j) {
				in.nextToken();
				int a=(int)in.nval;
				h[i].add(a);
			}
			for (int j=0;j<k;++j) {
				in.nextToken();
				long a=(long)in.nval;
				c[i].add(a);
			}
		}
		in.nextToken();
		int q=(int)in.nval;
		int[] H=new int[m+1];
		long[] C=new long[m+1];
		int cnt=0;
		for (int i=0;i<q;++i) {
			in.nextToken();
			int id=(int)in.nval;
			in.nextToken();
			int mul=(int)in.nval;
			for (int j=0;j<h[id].size();++j) {
				H[++cnt]=h[id].get(j);
				C[cnt]=1L*c[id].get(j)*mul;
			}
		}
		int[] L=new int[m+1];
		int[] R=new int[m+1];
		int[] deq=new int[m+1];
		int ptr=0;
		for (int i=1;i<=m;++i) {
			int nowL=i-H[i]+1;
			while (ptr>0&&deq[ptr-1]>=nowL) nowL=Math.min(nowL,L[deq[--ptr]]);
			nowL=Math.max(1,nowL);
			L[deq[ptr++]=i]=nowL;
		}
		ptr=0;
		for (int i=m;i>=1;--i) {
			int nowR=i+H[i]-1;
			while (ptr>0&&deq[ptr-1]<=nowR) nowR=Math.max(nowR,R[deq[--ptr]]);
			nowR=Math.min(nowR,m);
			R[deq[ptr++]=i]=nowR;
		}
		long[] dp=new long[m+1];
		ptr=0;
		long[] mmin=new long[m+1];
		for (int i=1;i<=m;++i) {
			dp[i]=dp[L[i]-1]+C[i];
			while (ptr>0&&i>R[deq[ptr-1]]) --ptr;
			if (ptr>0) dp[i]=Math.min(dp[i],mmin[ptr-1]);
			deq[ptr]=i;
			mmin[ptr++]=dp[i-1]+C[i];
			if (ptr>1) mmin[ptr-1]=Math.min(mmin[ptr-1],mmin[ptr-2]);
		}
		System.out.println(dp[m]);
	}
}


import java.util.*;
public class Main {
	public static void main(String[] args) {
		Scanner in=new Scanner(System.in);
		int n=in.nextInt();
		int m=in.nextInt();
		ArrayList<Integer>[] h=new ArrayList[n+1];
		ArrayList<Long>[] c=new ArrayList[n+1];
		for (int i=1;i<=n;++i) {
			h[i]=new ArrayList();
			c[i]=new ArrayList();
		}
		for (int i=1;i<=n;++i) {
			int k=in.nextInt();
			for (int j=0;j<k;++j) {
				int a=in.nextInt();
				h[i].add(a);
			}
			for (int j=0;j<k;++j) {
				long a=in.nextLong();
				c[i].add(a);
			}
		}
		int q=in.nextInt();
		int[] H=new int[m+1];
		long[] C=new long[m+1];
		int cnt=0;
		for (int i=0;i<q;++i) {
			int id=in.nextInt();
			int mul=in.nextInt();
			for (int j=0;j<h[id].size();++j) {
				H[++cnt]=h[id].get(j);
				C[cnt]=1L*c[id].get(j)*mul;
			}
		}
		int[] L=new int[m+1];
		int[] R=new int[m+1];
		int[] deq=new int[m+1];
		int ptr=0;
		for (int i=1;i<=m;++i) {
			int nowL=i-H[i]+1;
			while (ptr>0&&deq[ptr-1]>=nowL) nowL=Math.min(nowL,L[deq[--ptr]]);
			nowL=Math.max(1,nowL);
			L[deq[ptr++]=i]=nowL;
		}
		ptr=0;
		for (int i=m;i>=1;--i) {
			int nowR=i+H[i]-1;
			while (ptr>0&&deq[ptr-1]<=nowR) nowR=Math.max(nowR,R[deq[--ptr]]);
			nowR=Math.min(nowR,m);
			R[deq[ptr++]=i]=nowR;
		}
		long[] dp=new long[m+1];
		ptr=0;
		long[] mmin=new long[m+1];
		for (int i=1;i<=m;++i) {
			dp[i]=dp[L[i]-1]+C[i];
			while (ptr>0&&i>R[deq[ptr-1]]) --ptr;
			if (ptr>0) dp[i]=Math.min(dp[i],mmin[ptr-1]);
			deq[ptr]=i;
			mmin[ptr++]=dp[i-1]+C[i];
			if (ptr>1) mmin[ptr-1]=Math.min(mmin[ptr-1],mmin[ptr-2]);
		}
		System.out.println(dp[m]);
	}
}


#include<stdio.h>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
#include<cstring>
#define int long long
using namespace std;
const int maxn = 10000005;
int n,m;
int dp[maxn],L[maxn],R[maxn],RF[maxn],H[maxn],C[maxn];
vector<int>KH[250005],KC[250005];

main() {
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++) {
		int K; scanf("%lld",&K);
		KH[i].resize(K); KC[i].resize(K);
		for(int j=0;j<K;j++) {
			scanf("%lld",&KH[i][j]);
		}
		for(int j=0;j<K;j++) {
			scanf("%lld",&KC[i][j]);
		}
	}
	int Q; int tot = 0;
	scanf("%lld",&Q);
	memset(dp,0x3f,sizeof dp);
	for(int i=1;i<=Q;i++) {
		int id,mu; scanf("%lld%lld",&id,&mu);
		int ss = KH[id].size();
		for(int j=0;j<ss;j++) {
			++tot;
			H[tot] = KH[id][j];
			C[tot] = KC[id][j]*mu;
			L[tot] = tot-1;
			while(L[tot]>=1&&tot-L[tot]<H[tot]) L[tot] = L[L[tot]];
		}
	}
	dp[m+1] = 0;
	for(int i=m;i>=1;i--) {
		RF[i] = dp[i+1];
		R[i] = i+1;
		while(R[i]<=m&&R[i]-i<H[i]) {
			RF[i] = min(RF[i],RF[R[i]]);
			R[i] = R[R[i]];
		}
		dp[L[i]+1] = min(dp[L[i]+1],dp[i+1]+C[i]);
		dp[i] = min(dp[i],RF[i]+C[i]);
	}
	printf("%lld",dp[1]);
}


#include<bits/stdc++.h>
#define rep(i,x,y) for(int i=(x);i<=(y);++i)
#define dep(i,x,y) for(int i=(x);i>=(y);--i)
#define pb push_back
#define fr first
#define sc second
#define N 250010
#define M 10000010
#define Inf 2000000000000000000ll
using namespace std;
typedef long long ll;
typedef pair<int,ll> pil;
vector<pil>bl[N];int n,m;
int h[M],l[M],r[M],f[M],d[M];ll c[M],a[M];
int gf(int x){return f[x]==x?x:f[x]=gf(f[x]);}
int main(){int tot=0;
	scanf("%d%d",&n,&m);
	rep(i,1,n){int k;
		scanf("%d",&k);
		rep(j,0,k-1){int x;
			scanf("%d",&x);bl[i].pb({x,0});
		}
		rep(j,0,k-1)scanf("%lld",&bl[i][j].sc);
	}
	int k;scanf("%d",&k);
	while(k--){int x;ll y;
		scanf("%d%lld",&x,&y);
		for(pil i:bl[x])h[++tot]=i.fr,c[tot]=i.sc*y;
	}int t=0;
	rep(i,1,m){l[i]=i;
		while(t&&i-d[t]<h[i])l[i]=l[d[t--]];
		d[++t]=i;
	}t=0;
	dep(i,m,1){r[i]=i;
		while(t&&d[t]-i<h[i])r[i]=r[d[t--]];
		d[++t]=i;
	}
	rep(i,1,m)a[i]=Inf,f[i]=i;t=0;
	rep(i,1,m){
		a[r[i]]=min(a[r[i]],a[i-1]+c[i]);
		a[i]=min(a[i],a[gf(l[i]-1)]+c[i]);
		for(l[i]=i-1;a[i]<=a[l[i]];l[i]=l[l[i]])f[l[i]]=i;
	}
	printf("%lld\n",a[m]);
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int M=10000050;
const int N=250050;
ll w[M];
int h[M],lid[N],len[N],C[N],d[N];
int stk[M],c,q[M],ql,rng[M];
ll dp[M][2];
int main()
{
	int n,m,i,j;
	scanf("%i %i",&n,&m);
	for(i=1;i<=n;i++)
	{
		scanf("%i",&len[i]);
		for(j=lid[i];j<lid[i]+len[i];j++) scanf("%i",&d[j]);
		for(j=lid[i];j<lid[i]+len[i];j++) scanf("%i",&C[j]);
		lid[i+1]=lid[i]+len[i];
	}
	int qu,id,mul,cnt=0;
	scanf("%i",&qu);
	for(;qu--;)
	{
		scanf("%i %i",&id,&mul);
		for(i=lid[id];i<lid[id]+len[id];i++)
		{
			cnt++;
			h[cnt]=d[i];
			w[cnt]=(ll)C[i]*mul;
			//printf("(%i %lld)\n",h[cnt],w[cnt]);
		}
		//printf(":D\n");
	}
	for(i=1;i<=m;i++)
	{
		while(c && i-h[i]<stk[c]) c--;
		int l=stk[c]+1;
		stk[++c]=i;
		dp[i][0]=min(dp[l-1][0],dp[l-1][1])+w[i];
		dp[i][1]=min(dp[i-1][0],dp[i-1][1])+w[i];
		while(ql && rng[q[ql]]<=i) ql--;
		rng[i]=i+h[i];
		if(ql) dp[i][1]=min(dp[i][1],dp[q[ql]][1]);
		while(ql && rng[q[ql]]<=rng[i]) ql--;
		if(!ql || dp[i][1]<dp[q[ql]][1]) q[++ql]=i;
		//printf("%i %lld\n",h[i],w[i]);
		//printf("l:%i h:%i w:%lld (%lld %lld)\n",l,h[i],w[i],dp[i][0],dp[i][1]);
	}
	printf("%lld\n",min(dp[m][0],dp[m][1]));
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int mxN=2.5e5, mxM=1e7;
int n, m, q, h[mxM], l[mxM], r[mxM];
vector<array<int, 2>> a[mxN];
ll c[mxM], dp[mxM+1], rm[mxM];
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n >> m;
	for(int i=0, k; i<n; ++i)
	{
		cin >> k;
		a[i].resize(k);
		for(int b : {0, 1})
			for(int j=0; j<k; ++j)
				cin >> a[i][j][b];
	}
	cin >> q;
	for(int i=0, x, y; q--; )
	{
		cin >> x >> y, --x;
		for(int j=0; j<a[x].size(); ++j, ++i)
		{
			h[i]=a[x][j][0];
			c[i]=(ll)y*a[x][j][1];
			l[i]=i-1;
			while(l[i]>=0&&i-l[i]<h[i])
				l[i]=l[l[i]];
		}
	}
	memset(dp, 0x3f, 8*m);
	for(int i=m-1; i>=0; --i)
	{
		rm[i]=dp[i+1];
		r[i]=i+1;
		while(r[i]<m&&r[i]-i<h[i])
		{
			rm[i]=min(rm[r[i]], rm[i]);
			r[i]=r[r[i]];
		}
		dp[l[i]+1]=min(dp[i+1]+c[i], dp[l[i]+1]);
		dp[i]=min(rm[i]+c[i], dp[i]);
	}
	cout << dp[0];
}