#include <bits/stdc++.h>
using namespace std;
template <typename T>
using V = vector<T>;
template <typename T>
using VV = vector<V<T>>;
template <typename T>
using Mi = map<long long, T>;
template <typename T>
using MMi = map<long long, Mi<T>>;
const double PI = 3.141592653589793238463;
pair<long long, long long> zero = {-1, -1};
void cinArr(vector<long long> &arr) {
  for (int i = 0; i < arr.size(); i++) {
    cin >> arr[i];
  }
}
void cinArr(V<int> &arr) {
  for (int i = 0; i < arr.size(); i++) {
    cin >> arr[i];
  }
}
void cinMatr(vector<vector<long long>> &matr) {
  long long n = matr.size();
  long long m = matr[0].size();
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> matr[i][j];
    }
  }
}
void coutArr(vector<long long> &arr) {
  for (long long val : arr) {
    cout << val << " ";
  }
  cout << '\n';
}
int xx[4] = {1, -1, 0, 0};
int yy[4] = {0, 0, 1, -1};
V<int> prim;
V<int> prims;
void er(long long n) {
  prim = V<int>(n + 1);
  for (int i = 0; i <= n; i++) {
    prim[i] = i;
  }
  for (long long i = 2; i <= n; i++) {
    if (prim[i] == i) {
      prims.push_back(i);
      for (long long j = i * i; j <= n; j += i) {
        if (prim[j] == j) {
          prim[j] = i;
        }
      }
    }
  }
}
class LCA {
 private:
  long long N;
  long long n;
  vector<vector<long long>> up;
  vector<vector<long long>> g;
  vector<long long> lvl;
  void dfs(long long v, long long h) {
    lvl[v] = h;
    for (long long u : g[v]) {
      dfs(u, h + 1);
    }
  }

 public:
  LCA(vector<long long> &parent) {
    n = parent.size();
    N = log2(n) + 1;
    g = vector<vector<long long>>(n);
    lvl = vector<long long>(n);
    long long core = -1;
    for (int i = 0; i < n; i++) {
      if (parent[i] != -1) {
        g[parent[i]].push_back(i);
      } else {
        core = i;
      }
    }
    dfs(core, 0);
    up = vector<vector<long long>>(N, vector<long long>(n));
    up[0] = parent;
    for (int i = 1; i < N; i++) {
      for (int j = 0; j < n; j++) {
        long long parent = up[i - 1][j];
        if (parent == -1) {
          up[i][j] = -1;
        } else {
          up[i][j] = up[i - 1][parent];
        }
      }
    }
  }
  long long getParent(long long v, long long needUp) {
    for (int i = N - 1; i >= 0; i--) {
      if (up[i][v] != -1 && lvl[v] - lvl[up[i][v]] <= needUp) {
        needUp -= lvl[v] - lvl[up[i][v]];
        v = up[i][v];
      }
    }
    if (needUp != 0) {
      return -1;
    } else {
      return v;
    }
  }
  long long getLCA(long long a, long long b) {
    if (lvl[a] > lvl[b]) {
      long long del = abs(lvl[a] - lvl[b]);
      a = getParent(a, del);
    }
    if (lvl[a] < lvl[b]) {
      long long del = abs(lvl[a] - lvl[b]);
      b = getParent(b, del);
    }
    if (a == b) {
      return a;
    }
    for (int i = N - 1; i >= 0; i--) {
      if (up[i][a] != up[i][b]) {
        a = up[i][a];
        b = up[i][b];
      }
    }
    return up[0][a];
  }
  long long getLvl(long long v) { return lvl[v]; }
};
class Node {
 private:
  long long a;
  long long del;
  LCA &lca;
  long long l;
  long long r;
  Node *lChildren;
  Node *rChildren;
  pair<long long, long long> merge(pair<long long, long long> x,
                                   pair<long long, long long> y, long long len1,
                                   long long len2) {
    if (len1 > 2 && len2 > 2) {
      long long a = x.first;
      long long b = x.second;
      long long c = y.first;
      long long d = y.second;
      long long ac = lca.getLCA(a, c);
      long long acb = lca.getLCA(ac, b);
      long long acd = lca.getLCA(ac, d);
      if (lca.getLvl(acb) > lca.getLvl(acd)) {
        return {acb, d};
      } else {
        return {acd, b};
      }
    }
    if (len1 == 0) {
      return y;
    }
    if (len2 == 0) {
      return x;
    }
    long long a = x.first;
    long long b = x.second;
    long long c = y.first;
    long long d = y.second;
    if (len1 == 1 && len2 == 1) {
      if (lca.getLvl(b) > lca.getLvl(d)) {
        return {b, d};
      } else {
        return {d, b};
      }
    }
    if (len1 == 1) {
      if (len2 == 2) {
        long long bc = lca.getLCA(b, c);
        long long bd = lca.getLCA(b, d);
        long long cd = lca.getLCA(c, d);
        long long lbc = lca.getLvl(bc);
        long long lbd = lca.getLvl(bd);
        long long lcd = lca.getLvl(cd);
        if (lbc > lbd && lbc > lcd) {
          return {bc, d};
        }
        if (lbd > lcd) {
          return {bd, c};
        }
        return {cd, b};
      }
      long long bc = lca.getLCA(b, c);
      long long cd = lca.getLCA(c, d);
      long long lbc = lca.getLvl(bc);
      long long lcd = lca.getLvl(cd);
      if (lbc > lcd) {
        return {bc, d};
      } else {
        return {cd, b};
      }
    }
    if (len2 == 1) {
      if (len1 == 2) {
        long long ab = lca.getLCA(a, b);
        long long ad = lca.getLCA(a, d);
        long long bd = lca.getLCA(b, d);
        long long lab = lca.getLvl(ab);
        long long lad = lca.getLvl(ad);
        long long lbd = lca.getLvl(bd);
        if (lab > lad && lab > lbd) {
          return {ab, d};
        }
        if (lad > lbd) {
          return {ad, b};
        }
        return {bd, a};
      }
      long long ab = lca.getLCA(b, a);
      long long ad = lca.getLCA(a, d);
      long long lab = lca.getLvl(ab);
      long long lad = lca.getLvl(ad);
      if (lab > lad) {
        return {ab, d};
      } else {
        return {ad, b};
      }
    }
    if (len1 == 2 && len2 > 2) {
      long long abc = lca.getLCA(a, lca.getLCA(b, c));
      long long acd = lca.getLCA(a, lca.getLCA(c, d));
      long long bcd = lca.getLCA(b, lca.getLCA(c, d));
      long long labc = lca.getLvl(abc);
      long long lacd = lca.getLvl(acd);
      long long lbcd = lca.getLvl(bcd);
      long long ans = max({labc, lacd, lbcd});
      if (labc == ans) {
        return {abc, d};
      }
      if (lacd == ans) {
        return {acd, b};
      }
      if (lbcd == ans) {
        return {bcd, a};
      }
    }
    if (len2 == 2 && len1 > 2) {
      long long abc = lca.getLCA(a, lca.getLCA(b, c));
      long long abd = lca.getLCA(a, lca.getLCA(b, d));
      long long acd = lca.getLCA(a, lca.getLCA(c, d));
      long long labc = lca.getLvl(abc);
      long long labd = lca.getLvl(abd);
      long long lacd = lca.getLvl(acd);
      long long ans = max({labc, labd, lacd});
      if (labc == ans) {
        return {abc, d};
      }
      if (labd == ans) {
        return {abd, c};
      }
      if (lacd == ans) {
        return {acd, b};
      }
    }
    long long abc = lca.getLCA(a, lca.getLCA(b, c));
    long long abd = lca.getLCA(a, lca.getLCA(b, d));
    long long acd = lca.getLCA(a, lca.getLCA(c, d));
    long long bcd = lca.getLCA(b, lca.getLCA(c, d));
    long long labc = lca.getLvl(abc);
    long long labd = lca.getLvl(abd);
    long long lacd = lca.getLvl(acd);
    long long lbcd = lca.getLvl(bcd);
    long long ans = max({labc, labd, lacd, lbcd});
    if (labc == ans) {
      return {abc, d};
    }
    if (labd == ans) {
      return {abd, c};
    }
    if (lacd == ans) {
      return {acd, b};
    }
    if (lbcd == ans) {
      return {bcd, a};
    }
    return zero;
  }
  Node(long long l, long long r, vector<long long> &arr, LCA &lca) : lca(lca) {
    this->l = l;
    this->r = r;
    if (l == r) {
      a = -1;
      del = arr[l];
    } else {
      long long mid = (l + r) / 2;
      lChildren = new Node(l, mid, arr, lca);
      rChildren = new Node(mid + 1, r, arr, lca);
      long long len1 = mid - l + 1;
      long long len2 = r - mid;
      pair<long long, long long> p =
          merge(lChildren->getValue(), rChildren->getValue(), len1, len2);
      a = p.first;
      del = p.second;
    }
  }

 public:
  Node(vector<long long> &arr, LCA &lca) : Node(0, arr.size() - 1, arr, lca) {}
  pair<long long, long long> getValue() {
    pair<long long, long long> p = {a, del};
    return p;
  }
  pair<long long, long long> getValue(long long left, long long right) {
    if (l == left && r == right) {
      return getValue();
    }
    long long mid = (l + r) / 2;
    pair<long long, long long> p1, p2;
    long long len1 = 0;
    long long len2 = 0;
    p1 = p2 = zero;
    if (left <= mid) {
      p1 = lChildren->getValue(left, min(right, mid));
      len1 = min(right, mid) - left + 1;
    }
    if (right > mid) {
      p2 = rChildren->getValue(max(mid + 1, left), right);
      len2 = right - max(mid + 1, left) + 1;
    }
    pair<long long, long long> p = merge(p1, p2, len1, len2);
    return p;
  }
  void update(long long l, long long r, long long value) {
    if (l == this->l && r == this->r) {
      return;
    }
    long long mid = (this->l + this->r) / 2;
    if (l <= mid) {
      lChildren->update(l, min(mid, r), value);
    }
    if (r > mid) {
      rChildren->update(max(mid + 1, l), r, value);
    }
  }
};
long long gcd(long long a, long long b) {
  if (a < b) {
    swap(a, b);
  }
  if (b == 0) {
    return a;
  }
  return gcd(b, a % b);
}
long long gcd(long long a, long long b, long long &x, long long &y) {
  if (a == 0) {
    x = 0;
    y = 1;
    return b;
  }
  long long x1, y1;
  long long d = gcd(b % a, a, x1, y1);
  x = y1 - (b / a) * x1;
  y = x1;
  return d;
}
long long nok(long long a, long long b) {
  long long nnod = gcd(a, b);
  long long ans = a / nnod * b;
  return ans;
}
long long divup(long long a, long long b) {
  if (a % b == 0) {
    return a / b;
  } else {
    return a / b + 1;
  }
}
class SNM {
 private:
  vector<long long> parent;
  vector<long long> size;

 public:
  SNM(long long n) {
    parent = vector<long long>(n);
    size = vector<long long>(n, 1);
    for (int i = 0; i < n; i++) {
      parent[i] = i;
    }
  }
  void make_set(int v) { parent[v] = v; }
  int find_set(int v) {
    if (v == parent[v]) return v;
    long long ans = find_set(parent[v]);
    parent[v] = ans;
    return ans;
  }
  void union_sets(int a, int b) {
    a = find_set(a);
    b = find_set(b);
    if (a != b) {
      parent[b] = a;
      size[a] += size[b];
    }
  }
  long long getSize(int v) {
    v = find_set(v);
    return size[v];
  }
};
long long bs(long long x, vector<long long> &arr) {
  long long l = 0;
  long long r = arr.size();
  while (l < r) {
    long long mid = (l + r) / 2;
    if (arr[mid] > x) {
      r = mid;
    } else {
      l = mid + 1;
    }
  }
  return l;
}
void delR(long long v, vector<vector<long long>> &g, vector<bool> &viz,
          vector<vector<long long>> &G) {
  viz[v] = true;
  for (long long u : g[v]) {
    if (!viz[u]) {
      G[v].push_back(u);
      delR(u, g, viz, G);
    }
  }
}
pair<long long, long long> drob(long long a, long long b) {
  long long nod = gcd(a, b);
  a /= nod;
  b /= nod;
  return {a, b};
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  long long n;
  cin >> n;
  vector<bool> flags(26, false);
  flags[0] = true;
  flags['e' - 'a'] = true;
  flags['o' - 'a'] = true;
  flags['i' - 'a'] = true;
  flags['u' - 'a'] = true;
  V<string> arr(n);
  set<pair<long long, long long>> buffer;
  map<long long, map<long long, V<long long>>> strs;
  for (int i = 0; i < n; i++) {
    cin >> arr[i];
    long long lastG;
    long long len = 0;
    for (int j = 0; j < arr[i].size(); j++) {
      if (flags[arr[i][j] - 'a']) {
        lastG = arr[i][j] - 'a';
        len++;
      }
    }
    strs[len][lastG].push_back(i);
  }
  set<pair<long long, long long>> alsoBuf;
  for (auto &C : strs) {
    auto &v = C.second;
    vector<long long> lenbuf;
    for (auto &Ms : v) {
      auto &ms = Ms.second;
      for (int i = 0; i < ms.size() - 1; i += 2) {
        long long s1 = ms[i];
        long long s2 = ms[i + 1];
        buffer.insert({s1, s2});
      }
      if (ms.size() % 2 != 0) {
        lenbuf.push_back(ms[ms.size() - 1]);
      }
    }
    long long len = lenbuf.size() / 2;
    for (int i = 0; i / 2 < len; i += 2) {
      long long s1 = lenbuf[i];
      long long s2 = lenbuf[i + 1];
      alsoBuf.insert({s1, s2});
    }
  }
  V<pair<pair<long long, long long>, pair<long long, long long>>> ans;
  while (buffer.size() > 0) {
    pair<long long, long long> p1 = *buffer.begin();
    buffer.erase(buffer.begin());
    if (alsoBuf.size() > 0) {
      pair<long long, long long> p2 = *alsoBuf.begin();
      alsoBuf.erase(alsoBuf.begin());
      ans.push_back({p2, p1});
    } else if (buffer.size() > 0) {
      pair<long long, long long> p2 = *buffer.begin();
      buffer.erase(buffer.begin());
      ans.push_back({p2, p1});
    } else {
      break;
    }
  }
  cout << ans.size() << '\n';
  for (auto pp : ans) {
    long long a = pp.first.first;
    long long b = pp.second.first;
    long long c = pp.first.second;
    long long d = pp.second.second;
    cout << arr[a] << " " << arr[b] << '\n' << arr[c] << " " << arr[d] << '\n';
  }
  return 0;
}
