#include <bits/stdc++.h>
using namespace std;
const int Maxn = 300005;
int res, cnt, head[Maxn], choose[Maxn], target[Maxn], las[Maxn], ct, n[Maxn], k,
    val[Maxn], a[20][Maxn], b[Maxn], bel[Maxn], state_cnt;
bool vis1[Maxn], vis2[Maxn], ans[Maxn], done[20], flag;
map<long long, int> Ma;
long long sum[Maxn], tot;
int tmp_state, Solution[Maxn][20], Solution_cnt;
struct edg {
  int nxt, to;
} edge[2 * Maxn];
void add(int x, int y) {
  if (bel[x] == bel[y]) return;
  if (done[bel[x]] || done[bel[y]]) return;
  edge[++cnt] = (edg){head[x], y};
  head[x] = cnt;
}
void dfs(int u) {
  vis1[u] = true;
  vis2[u] = true;
  for (int i = head[u]; i; i = edge[i].nxt) {
    int to = edge[i].to;
    if (vis2[to]) {
      res = to;
      tmp_state = 0;
      state_cnt++;
      tmp_state |= (1 << (bel[to] - 1));
      tmp_state |= (1 << (bel[u] - 1));
      vis2[u] = false;
      Solution[state_cnt][1] = to, Solution[state_cnt][2] = u;
      Solution_cnt = 2;
      return;
    }
    dfs(to);
    if (flag) return;
    if (tmp_state & (1 << (bel[u] - 1))) {
      if (res == u)
        val[state_cnt] = tmp_state,
        reverse(Solution[state_cnt] + 1,
                Solution[state_cnt] + Solution_cnt + 1),
        Solution[state_cnt][Solution_cnt + 1] = Solution[state_cnt][1],
        tmp_state = 0;
      else
        state_cnt--, tmp_state = 0;
      flag = true;
      return;
    } else if (tmp_state) {
      tmp_state |= (1 << (bel[u] - 1));
      Solution[state_cnt][++Solution_cnt] = u;
      vis2[u] = false;
      return;
    }
  }
  vis2[u] = false;
}
void get_ans(int id) {
  choose[bel[Solution[id][1]]] = b[Solution[id][1]];
  for (int i = 2; Solution[id][i]; i++) {
    choose[bel[Solution[id][i]]] = b[Solution[id][i]];
    target[bel[Solution[id][i - 1]]] = bel[Solution[id][i]];
  }
}
int main() {
  scanf("%d", &k);
  for (int i = 1; i <= k; i++) {
    scanf("%d", &n[i]);
    for (int j = 1; j <= n[i]; j++)
      scanf("%d", &a[i][j]), b[++ct] = a[i][j], sum[i] += a[i][j],
                             tot += a[i][j];
  }
  if (tot % k) {
    printf("NO");
    return 0;
  }
  tot /= k;
  for (int i = 1; i <= k; i++)
    if (tot == sum[i]) done[i] = true;
  sort(b + 1, b + 1 + ct);
  for (int i = 1; i <= k; i++)
    for (int j = 1; j <= n[i]; j++)
      Ma[a[i][j]] = lower_bound(b + 1, b + 1 + ct, a[i][j]) - b,
      bel[Ma[a[i][j]]] = i;
  for (int i = 1; i <= k; i++)
    for (int j = 1; j <= n[i]; j++)
      if (Ma[tot - sum[i] + a[i][j]])
        add(Ma[tot - sum[i] + a[i][j]], Ma[a[i][j]]);
  for (int i = 1; i <= ct; i++)
    if (!vis1[i]) flag = false, dfs(i);
  for (int i = 1; i <= k; i++)
    if (sum[i] == tot) val[++state_cnt] = 1 << (i - 1);
  int maxi = (1 << k) - 1;
  ans[0] = true;
  for (int i = 0; i <= maxi; i++)
    if (ans[i])
      for (int j = 1; j <= state_cnt; j++)
        if (!(val[j] & i)) ans[val[j] | i] = true, las[val[j] | i] = j;
  if (ans[maxi]) {
    printf("YES\n");
    int state_now = maxi;
    while (state_now) {
      get_ans(las[state_now]);
      state_now ^= val[las[state_now]];
    }
    for (int i = 1; i <= k; i++)
      if (target[i])
        printf("%d %d\n", choose[i], target[i]);
      else
        printf("%d %d\n", a[i][1], i);
    return 0;
  }
  printf("NO");
  return 0;
}
