Example

Input

2 10
Warsaw Petersburg
3
Kiev Moscow Petersburg
150 120
3
Moscow Minsk Warsaw
100 150


Output

380 1
#include <bits/stdc++.h>
using namespace std;
struct Info {
  int min_time, min_change;
};
struct Data {
  Data(int arg_to, int arg_cost, int arg_line_id) {
    to = arg_to;
    cost = arg_cost;
    line_id = arg_line_id;
  }
  int to, cost, line_id;
};
struct STATE {
  STATE(int arg_st_id, int arg_sum_cost, int arg_change_num, int arg_line_id) {
    st_id = arg_st_id;
    sum_cost = arg_sum_cost;
    change_num = arg_change_num;
    line_id = arg_line_id;
  }
  bool operator<(const struct STATE &arg) const {
    if (sum_cost != arg.sum_cost) {
      return sum_cost > arg.sum_cost;
    } else {
      return change_num > arg.change_num;
    }
  }
  int st_id, sum_cost, change_num, line_id;
};
Info min_cost[100000];
map<unsigned long long int, int> MAP;
vector<Data> G[100000];
int st_index[100000], cost[100000];
unsigned long long int makeCode(char buf[11]) {
  int length;
  for (length = 0; buf[length] != '\0'; length++)
    ;
  unsigned long long int ret = 0;
  for (int i = 0; i < length; i++) {
    ret = buf[i] + ret * 99999883;
  }
  return ret;
}
int main() {
  int N, T;
  scanf("%d %d", &N, &T);
  unsigned long long int tmp_code;
  char buf[11];
  int start = 0, goal = 1;
  scanf("%s", buf);
  MAP[makeCode(buf)] = start;
  scanf("%s", buf);
  MAP[makeCode(buf)] = goal;
  int index = 2, tmp, tmp_cost;
  for (int loop = 0; loop < N; loop++) {
    scanf("%d", &tmp);
    for (int i = 0; i < tmp; i++) {
      scanf("%s", buf);
      tmp_code = makeCode(buf);
      auto at = MAP.find(tmp_code);
      if (at != MAP.end()) {
        st_index[i] = MAP[tmp_code];
      } else {
        MAP[tmp_code] = index;
        st_index[i] = index;
        index++;
      }
    }
    for (int i = 0; i < tmp - 1; i++) {
      scanf("%d", &tmp_cost);
      G[st_index[i]].push_back(Data(st_index[i + 1], tmp_cost, loop));
      G[st_index[i + 1]].push_back(Data(st_index[i], tmp_cost, loop));
    }
  }
  for (int i = 0; i < index; i++) {
    min_cost[i].min_change = 2000000000;
    min_cost[i].min_time = 2000000000;
  }
  priority_queue<STATE> Q;
  for (int i = 0; i < G[start].size(); i++) {
    if (min_cost[G[start][i].to].min_time > G[start][i].cost) {
      min_cost[G[start][i].to].min_time = G[start][i].cost;
      min_cost[G[start][i].to].min_change = 0;
      Q.push(STATE(G[start][i].to, G[start][i].cost, 0, G[start][i].line_id));
    }
  }
  int next_st, next_cost, next_change;
  while (!Q.empty()) {
    if (Q.top().st_id == goal) {
      printf("%d %d\n", Q.top().sum_cost, Q.top().change_num);
      return 0;
    } else if ((Q.top().sum_cost > min_cost[Q.top().st_id].min_time) ||
               (Q.top().sum_cost == min_cost[Q.top().st_id].min_time &&
                Q.top().change_num > min_cost[Q.top().st_id].min_change)) {
      Q.pop();
    } else {
      for (int i = 0; i < G[Q.top().st_id].size(); i++) {
        next_st = G[Q.top().st_id][i].to;
        next_cost = Q.top().sum_cost + G[Q.top().st_id][i].cost;
        next_change = Q.top().change_num;
        if (G[Q.top().st_id][i].line_id != Q.top().line_id) {
          next_cost += T;
          next_change++;
        }
        if (min_cost[next_st].min_time > next_cost) {
          min_cost[next_st].min_time = next_cost;
          min_cost[next_st].min_change = next_change;
          Q.push(STATE(next_st, next_cost, next_change,
                       G[Q.top().st_id][i].line_id));
        } else if (min_cost[next_st].min_time == next_cost &&
                   min_cost[next_st].min_change > next_change) {
          min_cost[next_st].min_change = next_change;
          Q.push(STATE(next_st, next_cost, next_change,
                       G[Q.top().st_id][i].line_id));
        }
      }
      Q.pop();
    }
  }
  printf("-1\n");
  return 0;
}
