#include <bits/stdc++.h>
using namespace std;
void read(int& head) { scanf("%d", &head); }
int K;
vector<long long int> box[16];
long long int boxsum[16];
map<long long int, int> whereis;
set<int> cycles;
map<int, vector<int>> cycle_info;
map<int, vector<long long int>> sought_info;
void find_cycle(int head, int headpos, long long int target,
                set<long long int>& used_in_cycle) {
  int curr = head;
  long long int seeking_value = target - (boxsum[head] - box[head][headpos]);
  int seenmask = 0;
  seenmask |= (1 << curr);
  vector<int> cycle;
  vector<long long int> sought;
  set<long long int> localused;
  while (1) {
    if (whereis.find(seeking_value) == whereis.end()) return;
    if (used_in_cycle.find(seeking_value) != used_in_cycle.end()) return;
    if (localused.find(seeking_value) != localused.end()) return;
    localused.insert(seeking_value);
    cycle.push_back(curr);
    sought.push_back(seeking_value);
    int next = whereis[seeking_value];
    if (seenmask & (1 << next)) {
      if (next == head and curr != head and
          seeking_value == box[head][headpos]) {
        int mask = 0;
        for (auto e : cycle) mask |= (1 << e);
        cycles.insert(mask);
        cycle_info[mask] = cycle;
        sought_info[mask] = sought;
        for (auto e : localused) used_in_cycle.insert(e);
        return;
      }
      return;
    }
    curr = next;
    seenmask |= (1 << curr);
    seeking_value = target - (boxsum[curr] - seeking_value);
  }
}
bool mem[1 << 16];
int dep[1 << 16];
void dp(int target) {
  mem[0] = true;
  for (auto c : cycles) {
    mem[c] = true;
    dep[c] = c;
  }
  for (int mask = 0; mask < (1 << K); mask++) {
    if (mem[mask]) continue;
    for (int submask = mask; submask; submask = (submask - 1) & mask) {
      if (mem[mask]) break;
      if (cycles.find(submask) != cycles.end()) {
        int cycle = submask;
        int leftovermask = mask & (~cycle);
        if (mem[leftovermask]) {
          dep[mask] = cycle;
          mem[mask] = true;
          break;
        }
      }
    }
  }
}
pair<long long int, int> answer[16];
void recover_cycle(int mask) {
  if (mask == 0) return;
  int cycle = dep[mask];
  vector<int> cinfo = cycle_info[cycle];
  vector<long long int> sinfo = sought_info[cycle];
  for (int i = 0; i < cinfo.size(); i++) {
    answer[cinfo[(i + 1) % (cinfo.size())]] =
        pair<long long int, int>(sinfo[i], cinfo[i]);
  }
  int leftovermask = mask & (~cycle);
  recover_cycle(leftovermask);
}
int main() {
  read(K);
  long long int target = 0;
  for (int i = 0; i < K; i++) {
    boxsum[i] = 0;
    int ni;
    read(ni);
    for (int j = 0; j < ni; j++) {
      int tmp;
      read(tmp);
      box[i].push_back(tmp);
      boxsum[i] += tmp;
      target += tmp;
      whereis[tmp] = i;
    }
  }
  if (target % K != 0) {
    printf("No\n");
    return 0;
  }
  target = target / K;
  set<long long int> used_in_cycle;
  for (int i = 0; i < K; i++) {
    if (boxsum[i] == target) continue;
    for (int j = 0; j < box[i].size(); j++) {
      find_cycle(i, j, target, used_in_cycle);
    }
  }
  for (int i = 0; i < K; i++)
    if (boxsum[i] == target) {
      vector<int> tmpc;
      tmpc.push_back(i);
      vector<long long int> tmps;
      tmps.push_back(box[i][0]);
      cycles.insert(1 << i);
      cycle_info[1 << i] = tmpc;
      sought_info[1 << i] = tmps;
    }
  memset(mem, 0, sizeof(mem));
  dp(target);
  if (mem[(1 << K) - 1]) {
    memset(answer, -1, sizeof(answer));
    recover_cycle((1 << K) - 1);
    for (int i = 0; i < K; i++)
      if (boxsum[i] == target)
        answer[i] = pair<long long int, int>(box[i][0], i);
    printf("Yes\n");
    for (int i = 0; i < K; i++) {
      printf("%lld %d\n", answer[i].first, 1 + answer[i].second);
    }
  } else {
    printf("No\n");
    return 0;
  }
}
