#include<bits/stdc++.h>
using namespace std;
const int N=6e5+10;
int head[8*N],ver[20*N],nex[20*N],edge[20*N],tot,d[8*N],v[8*N];
int n,m,s,root1,root2,cnt;
int len[8*N],que[8*N],que2[8*N],t1,t2;
int xx[8*N],ll[8*N],rr[8*N],zz[8*N],tt[8*N];
int nu[8*N];
long long num,ans;
priority_queue<pair<int ,int > >q;
const int mod=1e9+7;
void add(int x,int y,int z)
{
ver[++tot]=y,edge[tot]=z,nex[tot]=head[x],head[x]=tot;
}
void dij(int str)
{
memset(v,0,sizeof(v));
d[nu[str]]=0;
q.push(make_pair(0,nu[str]));
while(q.size())
{
int x=q.top().second;q.pop();
if(v[x])continue;
v[x]=1;
for(int i=head[x];i;i=nex[i])
{
int y=ver[i],z=edge[i];
if(d[y]==-1||d[y]>d[x]+z)
{
d[y]=d[x]+z;
q.push(make_pair(-d[y],y));
}
}
}
for(int i=1;i<=n;i++)
if(d[nu[i]]!=-1)
{
ans+=1ll*d[nu[i]]*len[i]%mod;
ans%=mod;
num-=len[i];
}
}
void build(int p,int l,int r)
{
int addd=(l==r)?0:n*4;
add(p+addd,n*4+(p>>1),0);
if(l==r)
{
nu[l]=p;
return ;
}
int mid=(l+r)>>1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
add(p,p*2,0);
add(p,p*2+1,0);
}
void treeadd(int p,int l1,int r1,int l2,int r2,int u,int z,int op)
{
if(l2>r1||r2<l1)return ;
if(l1<=l2&&r2<=r1)
{
if(op==2)add(nu[u],p,z);
else
{
int g=(l2==r2)?0:n*4;
add(p+g,nu[u],z);
}
return ;
}
int mid=(l2+r2)>>1;
if(l1<=mid)treeadd(p*2,l1,r1,l2,mid,u,z,op);
if(r1>mid)treeadd(p*2+1,l1,r1,mid+1,r2,u,z,op);
}
int main()
{
memset(d,-1,sizeof(d));
scanf("%d%d%d",&n,&m,&s);
// cnt=n;
// build1(root1,1,n);
// build2(root2,1,n);
que[++t1]=s;
num=n;
for(int i=1;i<=m;i++)
{
// int type;
scanf("%d",&tt[i]);
if(tt[i]==1)
{
// int x,y,z;
scanf("%d%d%d",&xx[i],&ll[i],&rr[i]);
que[++t1]=xx[i];
que[++t1]=ll[i];
}
else
{
scanf("%d%d%d%d",&xx[i],&ll[i],&rr[i],&zz[i]);
que[++t1]=xx[i];
que[++t1]=ll[i];
que[++t1]=rr[i];
}
}
sort(que+1,que+t1+1);
for(int i=1;i<=t1;i++)if(i==1||que[i-1]!=que[i])que2[++t2]=que[i];
t1=0;
memset(que,0,sizeof(que));
for(int i=1;i<=t2;i++){
if(i>1&&que2[i]-que2[i-1]>1)
{
que[++t1]=que2[i-1]+1;
len[t1]=que2[i]-que2[i-1]+1;
}
que[++t1]=que2[i],len[t1]=1;
}
n=t1;
s=lower_bound(que+1,que+t1+1,s)-que;
build(1,1,n);
for(int i=1;i<=m;i++)
{
if(tt[i]==1)
{
int x=lower_bound(que+1,que+t1+1,xx[i])-que;
int y=lower_bound(que+1,que+t1+1,ll[i])-que;
add(nu[x],nu[y],rr[i]);
}
else
{
int x=lower_bound(que+1,que+1+n,xx[i])-que;
int l=lower_bound(que+1,que+1+n,ll[i])-que;
int r=lower_bound(que+1,que+1+n,rr[i])-que;
int z=zz[i];
treeadd(1,1,n,l,r,x,z,tt[i]);
}
}
dij(s);
printf("%lld %lld\n",ans,num);
return 0;
}
n<=1000000000,m<=100000 样例没过,求调!!!