#include<stdio.h>
int n,m,num,ans=0x3f3f3f3f;
int dp[10005][10005],up[100005],down[100005],p,l,h,flag[10005][10005];
int min(int a,int b)
{
if(a<b)
{
return a;
}
else
{
return b;
}
}
int main()
{
scanf("%d%d%d",&n,&m,&num);//n长 m高 num柱子数
for(int i=1;i<=n;i++)
{
scanf("%d%d",&up[i],&down[i]);//up[n] down[n]
}
for(int i=1;i<=num;i++)//数组赋值
{
scanf("%d%d%d",&p,&l,&h);//重复使用
for(int j=m;j>=0;j--)
{
if(j>=m-l || j<=m-h)
{
flag[j][p]=1;
}
}
}
for(int i=0;i<=m;i++)
{
for(int j=0;j<=n;j++)
{
dp[i][j]=0x3f3f3f3f;
}
}
for(int i=0;i<=m;i++)
{
dp[i][0]=0;
}
for(int i=1;i<=n;i++)//n(i)长 m(j)高
{
for(int j=0;j<m;j++)
{
if(!flag[j][i])
{
if(j>=down[i])
{
dp[j][i]=dp[j-down[i]][i-1];
for(int k=1;k<=m;k++)
{
if(j+k*up[i]<=m)
{
dp[j][i]=min(dp[j][i],dp[j+k*up[i]][i-1]+k);
}
if(j-k*up[i+1]<=0 && !flag[0][i+1])
{
dp[0][i+1]=min(dp[0][i+1],dp[j][i]+k);
continue;
}
}
}
else
{
for(int k=1;k<=m;k++)
{
if(j+k*up[i]<=m)
{
dp[j][i]=min(dp[j][i],dp[j+k*up[i]][i-1]+k);
}
if(j-k*up[i+1]<=0 && !flag[0][i+1])
{
dp[0][i+1]=min(dp[0][i+1],dp[j][i]+k);
continue;
}
}
}
}
}
}
/* for(int i=0;i<=m;i++)//输出
{
for(int j=0;j<=n;j++)
{
if(dp[i][j]==0x3f3f3f3f && flag[i][j]==0)
{
printf("D ");
}
else if(dp[i][j]==0x3f3f3f3f && flag[i][j]==1)
{
printf("X ");
}
else
{
printf("%d ",dp[i][j]);
}
}
printf("\n");
}*/
int cxh=1,f1=0,f2=0;
for(int i=0;i<=m;i++)
{
ans=min(dp[i][n],ans);
}
if(ans==0x3f3f3f3f)
{
cxh=0;
ans=0;
for(int i=1;i<=n;i++)//n(i)长 m(j)高
{
f1=0;
f2=0;
for(int j=0;j<=m;j++)
{
if(flag[j][i]==1)
f1=1;
if(dp[j][i]!=0x3f3f3f3f)
f2=1;
}
if(f1 && f2)
{
ans++;
}
if(!f2)
{
break;
}
}
}
printf("%d\n%d\n",cxh,ans);
return 0;
}