#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define NINF -INF-1
#define ll long long
#define pi acos(-1.0)
#define mem(a,b) memset(a,b,sizeof(a))
#define lson rt<<1
#define rson rt<<1|1
const ll MAXN=2e6+7;
const ll mod=1e9+7;
struct node
{
    int sum;
    char b;
    string a;
}no[MAXN];
bool cmp(node x,node y)
{
    if(x.sum==y.sum)
        return x.b<y.b;
    return x.sum<y.sum;
}
vector<pair<int,int> >q,q1;
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>no[i].a;
        int len=no[i].a.size();
        for(int j=0;j<len;j++)
        {
            if(no[i].a[j]=='a')
                no[i].sum++,no[i].b=no[i].a[j];
            else if(no[i].a[j]=='e')
                no[i].sum++,no[i].b=no[i].a[j];
            else if(no[i].a[j]=='i')
                no[i].sum++,no[i].b=no[i].a[j];
            else if(no[i].a[j]=='o')
                no[i].sum++,no[i].b=no[i].a[j];
            else if(no[i].a[j]=='u')
                no[i].sum++,no[i].b=no[i].a[j];
        }
    }
    sort(no+1,no+n+1,cmp);
    int flag=-1,cnt=1;
    for(int i=1;i<=n;i++)
    {
        if(no[i].b==no[i+1].b&&no[i].sum==no[i+1].sum)
        {
            q.push_back(make_pair(i,i+1));
            i++;
        }
        else if(no[i].sum!=cnt)
        {
            flag=i;
            cnt=no[i].sum;
        }
        else if(flag==-1)
            flag=i;
        else
        {
            q1.push_back(make_pair(flag,i));
        }
    }
    int len=q.size(),len1=q1.size();
    int sum=min(len,len1),sum1=(len-len1)/2;
    if(len>len1)
        cout<<sum+sum1<<endl;
    else
        cout<<sum<<endl;
    for(int i=0;i<sum;i++)
    {
        cout<<no[q1[i].first].a<<" "<<no[q[i].first].a<<endl;
        cout<<no[q1[i].second].a<<" "<<no[q[i].second].a<<endl;
    }
    for(int i=sum;i<sum+sum1*2;i++)
    {
        cout<<no[q[i].first].a<<" "<<no[q[i+1].first].a<<endl;
        cout<<no[q[i].second].a<<" "<<no[q[i+1].second].a<<endl;
        i++;
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 1e5 + 10;
const int MOD = 1e9 + 7;
int n, m, k, t;

struct Word
{
    string word;
    int num;
    char last;
    bool operator < (const Word& that) const
    {
        if (this->num != that.num)
            return this->num < that.num;
        return this->last < that.last;
    }
}words[MAXN];

int main()
{
    ios::sync_with_stdio(false), cin.tie(0);
    cin >> n;
    for (int i = 1;i <= n;i++)
    {
        cin >> words[i].word;
        for (auto c:words[i].word)
        {
            if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u')
            {
                words[i].num++;
                words[i].last = c;
            }
        }
    }
    sort(words+1, words+1+n);
    vector<pair<int, int> > fi, se;
    int pos = 1;
    int w = -1, cnt = 1;
    while(pos <= n)
    {
//        if (words[pos].num == words[pos+1].num && words[pos].last == words[pos+1].last)
//        {
//            se.emplace_back(make_pair(pos, pos+1));
//            pos += 2;
//        }
//        else if (words[pos].num != cnt)
//        {
//            w = pos;
//            cnt = words[pos].num;
//            pos++;
//        }
//        else if (w == -1)
//        {
//            w = pos;
//            pos++;
//        }
//        else
//        {
//            fi.emplace_back(make_pair(w, pos));
//            w = -1;
//            pos++;
//        }
        if(words[pos].num==words[pos+1].num)
        {
            if(words[pos].last==words[pos+1].last)
                se.emplace_back(make_pair(pos,pos+1));
            else
                fi.emplace_back(make_pair(pos,pos+1));
            pos++;
        }
        pos++;
    }
    int s1 = fi.size(), s2 = se.size();
    int res = 0;
    res += min(s1, s2) + max(0, (s2-s1)/2);
    cout << res << endl;
    int i;
    for (i = 0;i < min(fi.size(), se.size());i++)
    {
        cout << words[fi[i].first].word << ' ' << words[se[i].first].word << endl;
        cout << words[fi[i].second].word << ' ' << words[se[i].second].word << endl;
    }
    for (;i+1 < se.size();i+=2)
    {
        cout << words[se[i].first].word << ' ' << words[se[i+1].first].word << endl;
        cout << words[se[i].second].word << ' ' << words[se[i+1].second].word << endl;
    }

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define NINF -INF-1
#define ll long long
#define pi acos(-1.0)
#define mem(a,b) memset(a,b,sizeof(a))
#define lson rt<<1
#define rson rt<<1|1
const ll MAXN=2e6+7;
const ll mod=1e9+7;
struct node
{
    int sum;
    char b;
    string a;
}no[MAXN];
bool cmp(node x,node y)
{
    if(x.sum==y.sum)
        return x.b<y.b;
    return x.sum<y.sum;
}
int a[MAXN],b[MAXN];
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>no[i].a;
        int len=no[i].a.size();
        for(int j=0;j<len;j++)
        {
            if(no[i].a[j]=='a')
                no[i].sum++,no[i].b=no[i].a[j];
            else if(no[i].a[j]=='e')
                no[i].sum++,no[i].b=no[i].a[j];
            else if(no[i].a[j]=='i')
                no[i].sum++,no[i].b=no[i].a[j];
            else if(no[i].a[j]=='o')
                no[i].sum++,no[i].b=no[i].a[j];
            else if(no[i].a[j]=='u')
                no[i].sum++,no[i].b=no[i].a[j];
        }
    }
    sort(no+1,no+n+1,cmp);
    int cnt=0,cnt1=0;
    for(int i=1;i<=n;i++)
    {
        if(no[i].sum==no[i+1].sum)
        {
            if(no[i].b==no[i+1].b)
                a[++cnt]=i;
            else
                b[++cnt1]=i;
            i++;
        }
    }
    int minn=min(cnt,cnt1),cnt2=0;
    if(cnt>cnt1)
        cnt2=(cnt-cnt1)/2;
    cout<<minn+cnt2<<endl;
    for(int i=1;i<=minn;i++)
    {
        cout<<no[b[i]].a<<" "<<no[a[i]].a<<endl;
        cout<<no[b[i]+1].a<<" "<<no[a[i]+1].a<<endl;
    }
    for(int i=minn+1;i<=minn+cnt2*2;i++)
    {
        cout<<no[a[i]].a<<" "<<no[a[i+1]].a<<endl;
        cout<<no[a[i]+1].a<<" "<<no[a[i+1]+1].a<<endl;
        i++;
    }
}


#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define NINF -INF-1
#define ll long long
#define pi acos(-1.0)
#define mem(a,b) memset(a,b,sizeof(a))
#define lson rt<<1
#define rson rt<<1|1
const ll MAXN=2e6+7;
const ll mod=1e9+7;
struct node
{
    int sum;
    char b;
    string a;
}no[MAXN];
bool cmp(node x,node y)
{
    if(x.sum==y.sum)
        return x.b<y.b;
    return x.sum<y.sum;
}
vector<pair<int,int> >q,q1;
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>no[i].a;
        int len=no[i].a.size();
        for(int j=0;j<len;j++)
        {
            if(no[i].a[j]=='a')
                no[i].sum++,no[i].b=no[i].a[j];
            else if(no[i].a[j]=='e')
                no[i].sum++,no[i].b=no[i].a[j];
            else if(no[i].a[j]=='i')
                no[i].sum++,no[i].b=no[i].a[j];
            else if(no[i].a[j]=='o')
                no[i].sum++,no[i].b=no[i].a[j];
            else if(no[i].a[j]=='u')
                no[i].sum++,no[i].b=no[i].a[j];
        }
    }
    sort(no+1,no+n+1,cmp);
    int cnt=0,cnt1=0;
    int flag=-1,flag1=1;
    for(int i=1;i<=n;i++)
    {
        if(no[i].sum==no[i+1].sum&&no[i].b==no[i+1].b)
        {
            q.push_back(make_pair(i,i+1));
            i++;
        }
        else if(no[i].sum!=flag1)
        {
            flag=i;
            flag1=no[i].sum;
        }
        else if(flag==-1)
            flag=i;
        else
        {
            q1.push_back(make_pair(flag,i));
            flag=-1;
        }
    }
    cnt=q.size(),cnt1=q1.size();
    int minn=min(cnt,cnt1),cnt2=0;
    if(cnt>cnt1)
        cnt2=(cnt-cnt1)/2;
    cout<<minn+cnt2<<endl;
    for(int i=0;i<minn;i++)
    {
        cout<<no[q1[i].first].a<<" "<<no[q[i].first].a<<endl;
        cout<<no[q1[i].second].a<<" "<<no[q[i].second].a<<endl;
    }
    for(int i=minn;i<minn+cnt2*2;i++)
    {
        cout<<no[q[i].first].a<<" "<<no[q[i+1].first].a<<endl;
        cout<<no[q[i].second].a<<" "<<no[q[i+1].second].a<<endl;
        i++;
    }
}


#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define NINF -INF-1
#define ll long long
#define pi acos(-1.0)
#define mem(a,b) memset(a,b,sizeof(a))
#define lson rt<<1
#define rson rt<<1|1
const ll MAXN=2e6+7;
const ll mod=1e9+7;
struct node
{
    int sum;
    char b;
    string a;
}no[MAXN];
bool cmp(node x,node y)
{
    if(x.sum==y.sum)
        return x.b<y.b;
    return x.sum<y.sum;
}
vector<pair<int,int> >q,q1;
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>no[i].a;
        int len=no[i].a.size();
        for(int j=0;j<len;j++)
        {
            if(no[i].a[j]=='a')
                no[i].sum++,no[i].b=no[i].a[j];
            else if(no[i].a[j]=='e')
                no[i].sum++,no[i].b=no[i].a[j];
            else if(no[i].a[j]=='i')
                no[i].sum++,no[i].b=no[i].a[j];
            else if(no[i].a[j]=='o')
                no[i].sum++,no[i].b=no[i].a[j];
            else if(no[i].a[j]=='u')
                no[i].sum++,no[i].b=no[i].a[j];
        }
    }
    sort(no+1,no+n+1,cmp);
    int flag=-1,cnt=1;
    for(int i=1;i<=n;i++)
    {
        if(no[i].b==no[i+1].b&&no[i].sum==no[i+1].sum)
        {
            q.push_back(make_pair(i,i+1));
            i++;
        }
        else if(no[i].sum!=cnt)
        {
            flag=i;
            cnt=no[i].sum;
        }
        else if(flag==-1)
            flag=i;
        else
        {
            q1.push_back(make_pair(flag,i));
            flag=-1;
        }
    }
    int len=q.size(),len1=q1.size();
    int sum=min(len,len1),sum1=(len-len1)/2;
    if(len>len1)
        cout<<sum+sum1<<endl;
    else
        cout<<sum<<endl;
    for(int i=0;i<sum;i++)
    {
        cout<<no[q1[i].first].a<<" "<<no[q[i].first].a<<endl;
        cout<<no[q1[i].second].a<<" "<<no[q[i].second].a<<endl;
    }
    for(int i=sum;i<sum+sum1*2;i++)
    {
        cout<<no[q[i].first].a<<" "<<no[q[i+1].first].a<<endl;
        cout<<no[q[i].second].a<<" "<<no[q[i+1].second].a<<endl;
        i++;
    }
}


#include <bits/stdc++.h>
#include <algorithm>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ass 1e18
#define MOD 1000000007
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define boost ios_base::sync_with_stdio(false);cin.tie(NULL);
#define debug(x) cout << #x << ": " << x << endl;
#define debug2(x,y) cout<<#x<<": "<< x<< ", "<< #y<< ": "<< y<< endl;
#define debug3(x,y,z) cout<<#x<<": "<< x<< ", "<< #y<< ": "<< y<<" "<<#z<<" : "<<z<< endl;
using namespace std;
typedef long long int ll;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define ordered_set tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update>
vector<string>v[5][1000000];
vector<pair<string,string> > l,s;

ll show(char x)
{
	if(x=='a')
		return 0;
	if(x=='e')
		return 1;
	if(x=='i')
		return 2;
	if(x=='o')
		return 3;
	return 4;
}

int main()
{
	boost
	ll n,i,cnt,maxi=0,j,k,a,flag=0;
	cin>>n;
	char c;
	string str;
	for(j=0;j<n;j++)
	{
		cnt=0;
		cin>>str;
		for(i=0;i<str.size();i++)
		{
			if(str[i]=='o'||str[i]=='a'||str[i]=='e'||str[i]=='i'||str[i]=='u')
			{
				cnt++;
				c=str[i];
			}
		}
		v[show(c)][cnt].pb(str);
		maxi=max(maxi,cnt);
	}
	for(i=1;i<=maxi;i++)
	{
		flag=0;
		for(j=0;j<5;j++)
		{
			a=v[j][i].size();
			//debug3(i,j,v[j][i].size());
			if(a%2==1)
			{
				if(flag)
				{
					l.pb(mp(str,v[j][i][a-1]));
					flag=0;
				}
				else
				{
					flag=1;
					str=v[j][i][a-1];
				}
				for(k=0;k<=a-3;k=k+2)
				{
					if(k+1>=a-1||k>=a)
						continue;
					s.pb(mp(v[j][i][k],v[j][i][k+1]));
				}
			}
			else
			{
				for(k=0;k<a;k=k+2)
					s.pb(mp(v[j][i][k],v[j][i][k+1]));
			}
		}
	}
	//debug2(s.size(),l.size());
	if(s.size()>l.size())
	{
		ll ans=s.size()-l.size();
		cout<<ans/2+l.size()<<"\n";
		for(i=0;i<l.size();i++)
		{
			cout<<l[i].fi<<" "<<s[i].fi<<"\n";
			cout<<l[i].se<<" "<<s[i].se<<"\n";
		}
		for(j=i;j<s.size();j++)
		{
			if(j+1==s.size())
				continue;
			cout<<s[j].fi<<" "<<s[j+1].fi<<"\n";
			cout<<s[j].se<<" "<<s[j+1].se<<"\n";
		}
	}
	else
	{
		cout<<s.size()<<"\n";
		for(i=0;i<s.size();i++)
		{
			cout<<l[i].fi<<" "<<s[i].fi<<"\n";
			cout<<l[i].se<<" "<<s[i].se<<"\n";
		}
	}
	return 0;
}


#include <bits/stdc++.h>
#include <algorithm>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ass 1e18
#define MOD 1000000007
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define boost ios_base::sync_with_stdio(false);cin.tie(NULL);
#define debug(x) cout << #x << ": " << x << endl;
#define debug2(x,y) cout<<#x<<": "<< x<< ", "<< #y<< ": "<< y<< endl;
#define debug3(x,y,z) cout<<#x<<": "<< x<< ", "<< #y<< ": "<< y<<" "<<#z<<" : "<<z<< endl;
using namespace std;
typedef long long int ll;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define ordered_set tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update>
ll arr[200005];
vector<string>v[5][1000000];
vector<pair<string,string> > l,s;

ll show(char x)
{
	if(x=='a')
		return 0;
	if(x=='e')
		return 1;
	if(x=='i')
		return 2;
	if(x=='o')
		return 3;
	return 4;
}

int main()
{
	boost
	ll n,i,cnt,maxi=0,j,k,a,flag=0;
	cin>>n;
	char c;
	string str;
	for(j=0;j<n;j++)
	{
		cnt=0;
		cin>>str;
		for(i=0;i<str.size();i++)
		{
			if(str[i]=='o'||str[i]=='a'||str[i]=='e'||str[i]=='i'||str[i]=='u')
			{
				cnt++;
				c=str[i];
			}
		}
		//debug3(show(c),cnt,str);
		v[show(c)][cnt].pb(str);
		maxi=max(maxi,cnt);
	}
	for(i=1;i<=maxi;i++)
	{
		flag=0;
		for(j=0;j<5;j++)
		{
			//debug3(i,j,v[j][i].size());
			if(v[j][i].size()%2==1)
			{
				a=v[j][i].size();
				if(flag)
				{
					l.pb(mp(str,v[j][i][a-1]));
					flag=0;
				}
				else
				{
					flag=1;
					str=v[j][i][a-1];
				}
				for(k=0;k<a-1;k=k+2)
					s.pb(mp(v[j][i][k],v[j][i][k+1]));
			}
			else
			{
				for(k=0;k<v[j][i].size();k=k+2)
					s.pb(mp(v[j][i][k],v[j][i][k+1]));
			}
		}
	}
	//debug2(s.size(),l.size());
	if(s.size()>l.size())
	{
		ll ans=s.size()-l.size();
		cout<<ans/2+l.size()<<"\n";
		for(i=0;i<l.size();i++)
		{
			cout<<l[i].fi<<" "<<s[i].fi<<"\n";
			cout<<l[i].se<<" "<<s[i].se<<"\n";
		}
		for(j=i;j<s.size();j++)
		{
			if(j+1==s.size())
				continue;
			cout<<s[j].fi<<" "<<s[j+1].fi<<"\n";
			cout<<s[j].se<<" "<<s[j+1].se<<"\n";
		}
	}
	else
	{
		cout<<s.size()<<"\n";
		for(i=0;i<s.size();i++)
		{
			cout<<l[i].fi<<" "<<s[i].fi<<"\n";
			cout<<l[i].se<<" "<<s[i].se<<"\n";
		}
	}
	return 0;
}


#include <bits/stdc++.h>
#include <algorithm>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ass 1e18
#define MOD 1000000007
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define boost ios_base::sync_with_stdio(false);cin.tie(NULL);
#define debug(x) cout << #x << ": " << x << endl;
#define debug2(x,y) cout<<#x<<": "<< x<< ", "<< #y<< ": "<< y<< endl;
#define debug3(x,y,z) cout<<#x<<": "<< x<< ", "<< #y<< ": "<< y<<" "<<#z<<" : "<<z<< endl;
using namespace std;
typedef long long int ll;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define ordered_set tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update>
vector<string>v[5][1000000];
vector<pair<string,string> > l,s;

ll show(char x)
{
	if(x=='a')
		return 0;
	if(x=='e')
		return 1;
	if(x=='i')
		return 2;
	if(x=='o')
		return 3;
	return 4;
}

int main()
{
	boost
	ll n,i,cnt,maxi=0,j,k,a,flag=0;
	cin>>n;
	char c;
	string str;
	for(j=0;j<n;j++)
	{
		cnt=0;
		cin>>str;
		for(i=0;i<str.size();i++)
		{
			if(str[i]=='o'||str[i]=='a'||str[i]=='e'||str[i]=='i'||str[i]=='u')
			{
				cnt++;
				c=str[i];
			}
		}
		v[show(c)][cnt].pb(str);
		maxi=max(maxi,cnt);
	}
	for(i=1;i<=maxi;i++)
	{
		flag=0;
		for(j=0;j<5;j++)
		{
			a=v[j][i].size();
			if(a%2==1)
			{
				if(flag)
				{
					l.pb(mp(str,v[j][i][a-1]));
					flag=0;
				}
				else
				{
					flag=1;
					str=v[j][i][a-1];
				}
				v[j][i].pop_back();
				for(k=0;k<v[j][i].size();k=k+2)
					s.pb(mp(v[j][i][k],v[j][i][k+1]));
			}
			else
			{
				for(k=0;k<a;k=k+2)
					s.pb(mp(v[j][i][k],v[j][i][k+1]));
			}
		}
	}
	if(s.size()>l.size())
	{
		ll ans=s.size()-l.size();
		cout<<ans/2+l.size()<<"\n";
		for(i=0;i<l.size();i++)
		{
			cout<<l[i].fi<<" "<<s[i].fi<<"\n";
			cout<<l[i].se<<" "<<s[i].se<<"\n";
		}
		for(j=i;j<s.size();j=j+2)
		{
			if(j+1==s.size())
				continue;
			cout<<s[j].fi<<" "<<s[j+1].fi<<"\n";
			cout<<s[j].se<<" "<<s[j+1].se<<"\n";
		}
	}
	else
	{
		cout<<s.size()<<"\n";
		for(i=0;i<s.size();i++)
		{
			cout<<l[i].fi<<" "<<s[i].fi<<"\n";
			cout<<l[i].se<<" "<<s[i].se<<"\n";
		}
	}
	return 0;
}


#include <bits/stdc++.h>
#include <algorithm>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ass 1e18
#define MOD 1000000007
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define boost ios_base::sync_with_stdio(false);cin.tie(NULL);
#define debug(x) cout << #x << ": " << x << endl;
#define debug2(x,y) cout<<#x<<": "<< x<< ", "<< #y<< ": "<< y<< endl;
#define debug3(x,y,z) cout<<#x<<": "<< x<< ", "<< #y<< ": "<< y<<" "<<#z<<" : "<<z<< endl;
using namespace std;
typedef long long int ll;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define ordered_set tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update>
vector<string>v[5][1000000];
vector<pair<string,string> > l,s;

ll show(char x)
{
	if(x=='a')
		return 0;
	if(x=='e')
		return 1;
	if(x=='i')
		return 2;
	if(x=='o')
		return 3;
	return 4;
}

int main()
{
	boost
	ll n,i,cnt,maxi=0,j,k,a,flag=0;
	cin>>n;
	char c;
	string str;
	for(j=0;j<n;j++)
	{
		cnt=0;
		cin>>str;
		for(i=0;i<str.size();i++)
		{
			if(str[i]=='o'||str[i]=='a'||str[i]=='e'||str[i]=='i'||str[i]=='u')
			{
				cnt++;
				c=str[i];
			}
		}
		v[show(c)][cnt].pb(str);
		maxi=max(maxi,cnt);
	}
	for(i=1;i<=maxi;i++)
	{
		flag=0;
		for(j=0;j<5;j++)
		{
			a=v[j][i].size();
			if(a%2==1)
			{
				if(flag)
				{
					l.pb(mp(str,v[j][i][a-1]));
					flag=0;
				}
				else
				{
					flag=1;
					str=v[j][i][a-1];
				}
				v[j][i].pop_back();
				for(k=0;k<v[j][i].size();k=k+2)
					s.pb(mp(v[j][i][k],v[j][i][k+1]));
			}
			else
			{
				for(k=0;k<a;k=k+2)
					s.pb(mp(v[j][i][k],v[j][i][k+1]));
			}
		}
	}
	if(s.size()>l.size())
	{
		ll ans=s.size()-l.size();
		cout<<ans/2+l.size()<<"\n";
		for(i=0;i<l.size();i++)
		{
			cout<<l[i].fi<<" "<<s[i].fi<<"\n";
			cout<<l[i].se<<" "<<s[i].se<<"\n";
		}
		for(j=i;j<s.size();j++)
		{
			if(j+1==s.size())
				continue;
			cout<<s[j].fi<<" "<<s[j+1].fi<<"\n";
			cout<<s[j].se<<" "<<s[j+1].se<<"\n";
		}
	}
	else
	{
		cout<<s.size()<<"\n";
		for(i=0;i<s.size();i++)
		{
			cout<<l[i].fi<<" "<<s[i].fi<<"\n";
			cout<<l[i].se<<" "<<s[i].se<<"\n";
		}
	}
	return 0;
}


#include <bits/stdc++.h>
#include <algorithm>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ass 1e18
#define MOD 1000000007
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define boost ios_base::sync_with_stdio(false);cin.tie(NULL);
#define debug(x) cout << #x << ": " << x << endl;
#define debug2(x,y) cout<<#x<<": "<< x<< ", "<< #y<< ": "<< y<< endl;
#define debug3(x,y,z) cout<<#x<<": "<< x<< ", "<< #y<< ": "<< y<<" "<<#z<<" : "<<z<< endl;
using namespace std;
typedef long long int ll;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define ordered_set tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update>
vector<string>v[5][1000000];
vector<pair<string,string> > l,s;

ll show(char x)
{
	if(x=='a')
		return 0;
	if(x=='e')
		return 1;
	if(x=='i')
		return 2;
	if(x=='o')
		return 3;
	return 4;
}

int main()
{
	boost
	ll n,i,cnt,maxi=0,j,k,a,flag=0;
	cin>>n;
	char c;
	string str;
	for(j=0;j<n;j++)
	{
		cnt=0;
		cin>>str;
		for(i=0;i<str.size();i++)
		{
			if(str[i]=='o'||str[i]=='a'||str[i]=='e'||str[i]=='i'||str[i]=='u')
			{
				cnt++;
				c=str[i];
			}
		}
		v[show(c)][cnt].pb(str);
		maxi=max(maxi,cnt);
	}
	for(i=1;i<=maxi;i++)
	{
		flag=0;
		for(j=0;j<5;j++)
		{
			a=v[j][i].size();
			//debug3(i,j,v[j][i].size());
			if(a%2==1)
			{
				if(flag)
				{
					l.pb(mp(str,v[j][i][a-1]));
					flag=0;
				}
				else
				{
					flag=1;
					str=v[j][i][a-1];
				}
				for(k=0;k<a-2;k=k+2)
					s.pb(mp(v[j][i][k],v[j][i][k+1]));
			}
			else
			{
				for(k=0;k<a;k=k+2)
					s.pb(mp(v[j][i][k],v[j][i][k+1]));
			}
		}
	}
	//debug2(s.size(),l.size());
	if(s.size()>l.size())
	{
		ll ans=s.size()-l.size();
		cout<<ans/2+l.size()<<"\n";
		for(i=0;i<l.size();i++)
		{
			cout<<l[i].fi<<" "<<s[i].fi<<"\n";
			cout<<l[i].se<<" "<<s[i].se<<"\n";
		}
		for(j=i;j<s.size();j++)
		{
			if(j+1==s.size())
				continue;
			cout<<s[j].fi<<" "<<s[j+1].fi<<"\n";
			cout<<s[j].se<<" "<<s[j+1].se<<"\n";
		}
	}
	else
	{
		cout<<s.size()<<"\n";
		for(i=0;i<s.size();i++)
		{
			cout<<l[i].fi<<" "<<s[i].fi<<"\n";
			cout<<l[i].se<<" "<<s[i].se<<"\n";
		}
	}
	return 0;
}


#include <bits/stdc++.h>
#include <algorithm>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ass 1e18
#define MOD 1000000007
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define boost ios_base::sync_with_stdio(false);cin.tie(NULL);
#define debug(x) cout << #x << ": " << x << endl;
#define debug2(x,y) cout<<#x<<": "<< x<< ", "<< #y<< ": "<< y<< endl;
#define debug3(x,y,z) cout<<#x<<": "<< x<< ", "<< #y<< ": "<< y<<" "<<#z<<" : "<<z<< endl;
using namespace std;
typedef long long int ll;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define ordered_set tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update>
vector<string>v[5][1000000];
vector<pair<string,string> > l,s;

ll show(char x)
{
	if(x=='a')
		return 0;
	if(x=='e')
		return 1;
	if(x=='i')
		return 2;
	if(x=='o')
		return 3;
	return 4;
}

int main()
{
	boost
	ll n,i,cnt,maxi=0,j,k,a,flag=0;
	cin>>n;
	char c;
	string str;
	for(j=0;j<n;j++)
	{
		cnt=0;
		cin>>str;
		for(i=0;i<str.size();i++)
		{
			if(str[i]=='o'||str[i]=='a'||str[i]=='e'||str[i]=='i'||str[i]=='u')
			{
				cnt++;
				c=str[i];
			}
		}
		v[show(c)][cnt].pb(str);
		maxi=max(maxi,cnt);
	}
	for(i=1;i<=maxi;i++)
	{
		flag=0;
		for(j=0;j<5;j++)
		{
			a=v[j][i].size();
			//debug3(i,j,v[j][i].size());
			if(a%2==1)
			{
				if(flag)
				{
					l.pb(mp(str,v[j][i][a-1]));
					flag=0;
				}
				else
				{
					flag=1;
					str=v[j][i][a-1];
				}
				for(k=0;k<a-3;k=k+2)
					s.pb(mp(v[j][i][k],v[j][i][k+1]));
			}
			else
			{
				for(k=0;k<a;k=k+2)
					s.pb(mp(v[j][i][k],v[j][i][k+1]));
			}
		}
	}
	//debug2(s.size(),l.size());
	if(s.size()>l.size())
	{
		ll ans=s.size()-l.size();
		cout<<ans/2+l.size()<<"\n";
		for(i=0;i<l.size();i++)
		{
			cout<<l[i].fi<<" "<<s[i].fi<<"\n";
			cout<<l[i].se<<" "<<s[i].se<<"\n";
		}
		for(j=i;j<s.size();j++)
		{
			if(j+1==s.size())
				continue;
			cout<<s[j].fi<<" "<<s[j+1].fi<<"\n";
			cout<<s[j].se<<" "<<s[j+1].se<<"\n";
		}
	}
	else
	{
		cout<<s.size()<<"\n";
		for(i=0;i<s.size();i++)
		{
			cout<<l[i].fi<<" "<<s[i].fi<<"\n";
			cout<<l[i].se<<" "<<s[i].se<<"\n";
		}
	}
	return 0;
}


#include <bits/stdc++.h>
#include <chrono>

using namespace std;
using namespace std::chrono;

// #pragma GCC target ("avx2")
// #pragma GCC optimization ("O3")
// #pragma GCC optimization ("unroll-loops")
// #pragma optimization_level 3
// #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define f0r(a, b) for (long long a = 0; a < (b); ++a)
#define f1r(a, b, c) for (long long a = (b); a < (c); ++a)
#define f0rd(a, b) for (long long a = (b); a >= 0; --a)
#define f1rd(a, b, c) for (long long a = (b); a >= (c); --a)
#define ms(arr, v) memset(arr, v, sizeof(arr))
#define pb push_back
#define send {ios_base::sync_with_stdio(false);}
#define help {cin.tie(NULL); cout.tie(NULL);}
#define fix(prec) {cout << setprecision(prec) << fixed;}
#define mp make_pair
#define f first
#define s second
#define presum(p, a, n) {p[0] = a[0]; for (int i = 1; i < (n); i++) p[i] = a[i] + p[i-1];}
#define all(v) v.begin(), v.end()
#define getunique(v) {sort(all(v)); v.erase(unique(all(v)), v.end());}
#define readgraph(list, edges) for (int i = 0; i < edges; i++) {int a, b; cin >> a >> b; a--; b--; list[a].pb(b); list[b].pb(a);}
#define ai(a, n) for (int ele = 0; ele < n; ele++) cin >> a[ele];
#define ain(a, lb, rb) for (int ele = lb; ele <= rb; ele++) cin >> a[ele];
#define ao(a, n) {for (int ele = 0; ele < (n); ele++) { if (ele) cout << " "; cout << a[ele]; } cout << '\n';}
#define aout(a, lb, rb) {for (int ele = (lb); ele <= (rb); ele++) { if (ele > (lb)) cout << " "; cout << a[ele]; } cout << '\n';}
typedef long long ll;
typedef double ld;
typedef long double lld;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vpi;
typedef vector<pll> vpl;

template<typename A> ostream& operator<<(ostream &cout, vector<A> const &v);
template<typename A, typename B> ostream& operator<<(ostream &cout, pair<A, B> const &p) { return cout << "(" << p.f << ", " << p.s << ")"; }
template<typename A> ostream& operator<<(ostream &cout, vector<A> const &v) {
  cout << "["; for(int i = 0; i < v.size(); i++) {if (i) cout << ", "; cout << v[i];} return cout << "]";
}
template<typename A, typename B> istream& operator>>(istream& cin, pair<A, B> &p) {
  cin >> p.first;
  return cin >> p.second;
}

mt19937 rng(steady_clock::now().time_since_epoch().count());
// mt19937 rng(61378913);
/* usage - just do rng() */

void usaco(string filename) {
  // #pragma message("be careful, freopen may be wrong")
	freopen((filename + ".in").c_str(), "r", stdin);
	freopen((filename + ".out").c_str(), "w", stdout);
}

const lld pi = 3.14159265358979323846;
// const ll mod = 1000000007;
// const ll mod = 998244353;
// ll mod;

ll n, m, k, q, l, r, x, y, z;
ll a[1000005];
ll b[1000005];
ll c[1000005];
string s, t;
ll ans = 0;

string ss[100005];
pair<ll, char> stat[100005];
map<pair<ll, char>, set<int> > cnt;
map<ll, set<int> > vcnt;
set<pair<int, pair<ll, char> > > cs;
set<pair<int, ll> > vs;

bool ivow(char a) {
  return a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u';
}

void rm(pii x) {
  set<int>& a = cnt[stat[x.f]];
  set<int>& b = vcnt[stat[x.f].f];
  cs.erase(mp(a.size(), stat[x.f]));
  vs.erase(mp(b.size(), stat[x.f].f));

  a.erase(x.f);
  b.erase(x.f);
  a.erase(x.s);
  b.erase(x.s);

  if (a.size()) cs.insert(mp(a.size(), stat[x.f]));
  if (b.size()) vs.insert(mp(b.size(), stat[x.f].f));
}

pii getc() {
  if (!cs.size()) return mp(-1, -1);
  auto x = *cs.rbegin();
  if (x.f >= 2) {
    return mp(*cnt[x.s].begin(), *cnt[x.s].rbegin());
  }
  return mp(-1, -1);
}

pii getv() {
  if (!vs.size()) return mp(-1, -1);
  auto x = *vs.rbegin();
  if (x.f >= 2) {
    return mp(*vcnt[x.s].begin(), *vcnt[x.s].rbegin());
  }
  return mp(-1, -1);
}

pair<pii, pii> res[25005];

void solve(int tc) {
  cin >> n;
  f0r(i, n) {
    cin >> s; ss[i] = s;
    ll cv = 0; char t;
    f0r(i, s.length()) {
      if (ivow(s[i])) {
        ++cv; t = s[i];
      }
    }

    stat[i] = mp(cv, t);
    cnt[stat[i]].insert(i);
    vcnt[cv].insert(i);
  }

  for (auto x: cnt) cs.insert(mp(x.s.size(), x.f));
  for (auto x: vcnt) vs.insert(mp(x.s.size(), x.f));

  while (1) {
    pii x = getc();
    if (x.f != -1) {
      rm(x);
      pii y = getv();
      if (y.f == -1) y = getc();
      if (y.f == -1) break;

      res[ans++] = mp(mp(y.f, x.f), mp(y.s, x.s));
      rm(y);
    } else break;
  }

  printf("%lld\n", ans);
  f0r(i, ans) {
    pair<pii, pii> x = res[i];
    printf("%s %s\n", ss[x.f.f].c_str(), ss[x.f.s].c_str());
    printf("%s %s\n", ss[x.s.f].c_str(), ss[x.s.s].c_str());
  }
}

int main() {
  send help

  // usaco("file");

  int tc;
  tc = 1;
  // cin >> tc;
  for (int t = 0; t < tc; t++) solve(t);
}


#include <bits/stdc++.h>
#include <chrono>

using namespace std;
using namespace std::chrono;

// #pragma GCC target ("avx2")
// #pragma GCC optimization ("O3")
// #pragma GCC optimization ("unroll-loops")
// #pragma optimization_level 3
// #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define f0r(a, b) for (long long a = 0; a < (b); ++a)
#define f1r(a, b, c) for (long long a = (b); a < (c); ++a)
#define f0rd(a, b) for (long long a = (b); a >= 0; --a)
#define f1rd(a, b, c) for (long long a = (b); a >= (c); --a)
#define ms(arr, v) memset(arr, v, sizeof(arr))
#define pb push_back
#define send {ios_base::sync_with_stdio(false);}
#define help {cin.tie(NULL); cout.tie(NULL);}
#define fix(prec) {cout << setprecision(prec) << fixed;}
#define mp make_pair
#define f first
#define s second
#define presum(p, a, n) {p[0] = a[0]; for (int i = 1; i < (n); i++) p[i] = a[i] + p[i-1];}
#define all(v) v.begin(), v.end()
#define getunique(v) {sort(all(v)); v.erase(unique(all(v)), v.end());}
#define readgraph(list, edges) for (int i = 0; i < edges; i++) {int a, b; cin >> a >> b; a--; b--; list[a].pb(b); list[b].pb(a);}
#define ai(a, n) for (int ele = 0; ele < n; ele++) cin >> a[ele];
#define ain(a, lb, rb) for (int ele = lb; ele <= rb; ele++) cin >> a[ele];
#define ao(a, n) {for (int ele = 0; ele < (n); ele++) { if (ele) cout << " "; cout << a[ele]; } cout << '\n';}
#define aout(a, lb, rb) {for (int ele = (lb); ele <= (rb); ele++) { if (ele > (lb)) cout << " "; cout << a[ele]; } cout << '\n';}
typedef long long ll;
typedef double ld;
typedef long double lld;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vpi;
typedef vector<pll> vpl;

template<typename A> ostream& operator<<(ostream &cout, vector<A> const &v);
template<typename A, typename B> ostream& operator<<(ostream &cout, pair<A, B> const &p) { return cout << "(" << p.f << ", " << p.s << ")"; }
template<typename A> ostream& operator<<(ostream &cout, vector<A> const &v) {
  cout << "["; for(int i = 0; i < v.size(); i++) {if (i) cout << ", "; cout << v[i];} return cout << "]";
}
template<typename A, typename B> istream& operator>>(istream& cin, pair<A, B> &p) {
  cin >> p.first;
  return cin >> p.second;
}

mt19937 rng(steady_clock::now().time_since_epoch().count());
// mt19937 rng(61378913);
/* usage - just do rng() */

void usaco(string filename) {
  // #pragma message("be careful, freopen may be wrong")
	freopen((filename + ".in").c_str(), "r", stdin);
	freopen((filename + ".out").c_str(), "w", stdout);
}

const lld pi = 3.14159265358979323846;
// const ll mod = 1000000007;
// const ll mod = 998244353;
// ll mod;

ll n, m, k, q, l, r, x, y, z;
ll a[1000005];
ll b[1000005];
ll c[1000005];
string s, t;
ll ans = 0;

string ss[100005];
pair<ll, char> stat[100005];
map<pair<ll, char>, set<int> > cnt;
map<ll, set<int> > vcnt;
set<pair<int, pair<ll, char> > > cs;
set<pair<int, ll> > vs;

bool ivow(char a) {
  return a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u';
}

void rm(pii x) {
  set<int>& a = cnt[stat[x.f]];
  set<int>& b = vcnt[stat[x.f].f];
  cs.erase(mp(a.size(), stat[x.f]));
  vs.erase(mp(b.size(), stat[x.f].f));

  a.erase(x.f);
  b.erase(x.f);
  a.erase(x.s);
  b.erase(x.s);

  cs.insert(mp(a.size(), stat[x.f]));
  vs.insert(mp(b.size(), stat[x.f].f));
}

pii getc() {
  auto x = *cs.rbegin();
  if (x.f >= 2) {
    auto y = cnt[x.s];
    return mp(*y.begin(), *next(y.begin()));
  }
  return mp(-1, -1);
}

pii getv() {
  auto x = *vs.rbegin();
  if (x.f >= 2) {
    auto y = vcnt[x.s];
    return mp(*y.begin(), *next(y.begin()));
  }
  return mp(-1, -1);
}

vector<pair<pii, pii> > res;

void solve(int tc) {
  cin >> n;
  f0r(i, n) {
    cin >> s; ss[i] = s;
    ll cv = 0; char t;
    f0r(i, s.length()) {
      if (ivow(s[i])) {
        ++cv; t = s[i];
      }
    }

    stat[i] = mp(cv, t);
    cnt[stat[i]].insert(i);
    vcnt[cv].insert(i);
  }

  for (auto x: cnt) cs.insert(mp(x.s.size(), x.f));
  for (auto x: vcnt) vs.insert(mp(x.s.size(), x.f));

  while (1) {
    pii x = getc();
    if (x.f != -1) {
      rm(x);
      pii y = getv();
      if (y.f == -1) y = getc();
      if (y.f == -1) break;

      res.pb(mp(mp(y.f, x.f), mp(y.s, x.s)));
      rm(y);
    } else break;
  }

  cout << res.size() << '\n';
  for (auto x: res) {
    cout << ss[x.f.f] << " " << ss[x.f.s] << '\n';
    cout << ss[x.s.f] << " " << ss[x.s.s] << '\n';
  }
}

int main() {
  send help

  // usaco("file");

  int tc;
  tc = 1;
  // cin >> tc;
  for (int t = 0; t < tc; t++) solve(t);
}


#include <bits/stdc++.h>
#include <chrono>

using namespace std;
using namespace std::chrono;

// #pragma GCC target ("avx2")
// #pragma GCC optimization ("O3")
// #pragma GCC optimization ("unroll-loops")
// #pragma optimization_level 3
// #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define f0r(a, b) for (long long a = 0; a < (b); ++a)
#define f1r(a, b, c) for (long long a = (b); a < (c); ++a)
#define f0rd(a, b) for (long long a = (b); a >= 0; --a)
#define f1rd(a, b, c) for (long long a = (b); a >= (c); --a)
#define ms(arr, v) memset(arr, v, sizeof(arr))
#define pb push_back
#define send {ios_base::sync_with_stdio(false);}
#define help {cin.tie(NULL); cout.tie(NULL);}
#define fix(prec) {cout << setprecision(prec) << fixed;}
#define mp make_pair
#define f first
#define s second
#define presum(p, a, n) {p[0] = a[0]; for (int i = 1; i < (n); i++) p[i] = a[i] + p[i-1];}
#define all(v) v.begin(), v.end()
#define getunique(v) {sort(all(v)); v.erase(unique(all(v)), v.end());}
#define readgraph(list, edges) for (int i = 0; i < edges; i++) {int a, b; cin >> a >> b; a--; b--; list[a].pb(b); list[b].pb(a);}
#define ai(a, n) for (int ele = 0; ele < n; ele++) cin >> a[ele];
#define ain(a, lb, rb) for (int ele = lb; ele <= rb; ele++) cin >> a[ele];
#define ao(a, n) {for (int ele = 0; ele < (n); ele++) { if (ele) cout << " "; cout << a[ele]; } cout << '\n';}
#define aout(a, lb, rb) {for (int ele = (lb); ele <= (rb); ele++) { if (ele > (lb)) cout << " "; cout << a[ele]; } cout << '\n';}
typedef long long ll;
typedef double ld;
typedef long double lld;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vpi;
typedef vector<pll> vpl;

template<typename A> ostream& operator<<(ostream &cout, vector<A> const &v);
template<typename A, typename B> ostream& operator<<(ostream &cout, pair<A, B> const &p) { return cout << "(" << p.f << ", " << p.s << ")"; }
template<typename A> ostream& operator<<(ostream &cout, vector<A> const &v) {
  cout << "["; for(int i = 0; i < v.size(); i++) {if (i) cout << ", "; cout << v[i];} return cout << "]";
}
template<typename A, typename B> istream& operator>>(istream& cin, pair<A, B> &p) {
  cin >> p.first;
  return cin >> p.second;
}

mt19937 rng(steady_clock::now().time_since_epoch().count());
// mt19937 rng(61378913);
/* usage - just do rng() */

void usaco(string filename) {
  // #pragma message("be careful, freopen may be wrong")
	freopen((filename + ".in").c_str(), "r", stdin);
	freopen((filename + ".out").c_str(), "w", stdout);
}

const lld pi = 3.14159265358979323846;
// const ll mod = 1000000007;
// const ll mod = 998244353;
// ll mod;

ll n, m, k, q, l, r, x, y, z;
ll a[1000005];
ll b[1000005];
ll c[1000005];
string s, t;
ll ans = 0;

string ss[100005];
pair<ll, char> stat[100005];
map<pair<ll, char>, set<int> > cnt;
map<ll, set<int> > vcnt;
set<pair<int, pair<ll, char> > > cs;
set<pair<int, ll> > vs;

bool ivow(char a) {
  return a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u';
}

void rm(pii x) {
  set<int>& a = cnt[stat[x.f]];
  set<int>& b = vcnt[stat[x.f].f];
  cs.erase(mp(a.size(), stat[x.f]));
  vs.erase(mp(b.size(), stat[x.f].f));

  a.erase(x.f);
  b.erase(x.f);
  a.erase(x.s);
  b.erase(x.s);

  cs.insert(mp(a.size(), stat[x.f]));
  vs.insert(mp(b.size(), stat[x.f].f));
}

pii getc() {
  if (!cs.size()) return mp(-1, -1);
  auto x = *cs.rbegin();
  if (x.f >= 2) {
    return mp(*cnt[x.s].begin(), *cnt[x.s].rbegin());
  }
  return mp(-1, -1);
}

pii getv() {
  if (!vs.size()) return mp(-1, -1);
  auto x = *vs.rbegin();
  if (x.f >= 2) {
    return mp(*vcnt[x.s].begin(), *vcnt[x.s].rbegin());
  }
  return mp(-1, -1);
}

pair<pii, pii> res[25005];

void solve(int tc) {
  cin >> n;
  f0r(i, n) {
    cin >> s; ss[i] = s;
    ll cv = 0; char t;
    f0r(i, s.length()) {
      if (ivow(s[i])) {
        ++cv; t = s[i];
      }
    }

    stat[i] = mp(cv, t);
    cnt[stat[i]].insert(i);
    vcnt[cv].insert(i);
  }

  for (auto x: cnt) cs.insert(mp(x.s.size(), x.f));
  for (auto x: vcnt) vs.insert(mp(x.s.size(), x.f));

  while (1) {
    pii x = getc();
    if (x.f != -1) {
      rm(x);
      pii y = getv();
      if (y.f == -1) y = getc();
      if (y.f == -1) break;

      res[ans++] = mp(mp(y.f, x.f), mp(y.s, x.s));
      rm(y);
    } else break;
  }

  printf("%lld\n", ans);
  f0r(i, ans) {
    pair<pii, pii> x = res[i];
    printf("%s %s\n", ss[x.f.f].c_str(), ss[x.f.s].c_str());
    printf("%s %s\n", ss[x.s.f].c_str(), ss[x.s.s].c_str());
  }
}

int main() {
  send help

  // usaco("file");

  int tc;
  tc = 1;
  // cin >> tc;
  for (int t = 0; t < tc; t++) solve(t);
}


#include <bits/stdc++.h>
#include <chrono>

using namespace std;
using namespace std::chrono;

// #pragma GCC target ("avx2")
// #pragma GCC optimization ("O3")
// #pragma GCC optimization ("unroll-loops")
// #pragma optimization_level 3
// #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define f0r(a, b) for (long long a = 0; a < (b); ++a)
#define f1r(a, b, c) for (long long a = (b); a < (c); ++a)
#define f0rd(a, b) for (long long a = (b); a >= 0; --a)
#define f1rd(a, b, c) for (long long a = (b); a >= (c); --a)
#define ms(arr, v) memset(arr, v, sizeof(arr))
#define pb push_back
#define send {ios_base::sync_with_stdio(false);}
#define help {cin.tie(NULL); cout.tie(NULL);}
#define fix(prec) {cout << setprecision(prec) << fixed;}
#define mp make_pair
#define f first
#define s second
#define presum(p, a, n) {p[0] = a[0]; for (int i = 1; i < (n); i++) p[i] = a[i] + p[i-1];}
#define all(v) v.begin(), v.end()
#define getunique(v) {sort(all(v)); v.erase(unique(all(v)), v.end());}
#define readgraph(list, edges) for (int i = 0; i < edges; i++) {int a, b; cin >> a >> b; a--; b--; list[a].pb(b); list[b].pb(a);}
#define ai(a, n) for (int ele = 0; ele < n; ele++) cin >> a[ele];
#define ain(a, lb, rb) for (int ele = lb; ele <= rb; ele++) cin >> a[ele];
#define ao(a, n) {for (int ele = 0; ele < (n); ele++) { if (ele) cout << " "; cout << a[ele]; } cout << '\n';}
#define aout(a, lb, rb) {for (int ele = (lb); ele <= (rb); ele++) { if (ele > (lb)) cout << " "; cout << a[ele]; } cout << '\n';}
typedef long long ll;
typedef double ld;
typedef long double lld;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vpi;
typedef vector<pll> vpl;

template<typename A> ostream& operator<<(ostream &cout, vector<A> const &v);
template<typename A, typename B> ostream& operator<<(ostream &cout, pair<A, B> const &p) { return cout << "(" << p.f << ", " << p.s << ")"; }
template<typename A> ostream& operator<<(ostream &cout, vector<A> const &v) {
  cout << "["; for(int i = 0; i < v.size(); i++) {if (i) cout << ", "; cout << v[i];} return cout << "]";
}
template<typename A, typename B> istream& operator>>(istream& cin, pair<A, B> &p) {
  cin >> p.first;
  return cin >> p.second;
}

mt19937 rng(steady_clock::now().time_since_epoch().count());
// mt19937 rng(61378913);
/* usage - just do rng() */

void usaco(string filename) {
  // #pragma message("be careful, freopen may be wrong")
	freopen((filename + ".in").c_str(), "r", stdin);
	freopen((filename + ".out").c_str(), "w", stdout);
}

const lld pi = 3.14159265358979323846;
// const ll mod = 1000000007;
// const ll mod = 998244353;
// ll mod;

ll n, m, k, q, l, r, x, y, z;
ll a[1000005];
ll b[1000005];
ll c[1000005];
string s, t;
ll ans = 0;

string ss[100005];
pair<ll, char> stat[100005];
map<pair<ll, char>, set<int> > cnt;
map<ll, set<int> > vcnt;
set<pair<int, pair<ll, char> > > cs;
set<pair<int, ll> > vs;

bool ivow(char a) {
  return a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u';
}

void rm(pii x) {
  set<int>& a = cnt[stat[x.f]];
  set<int>& b = vcnt[stat[x.f].f];
  cs.erase(mp(a.size(), stat[x.f]));
  vs.erase(mp(b.size(), stat[x.f].f));

  a.erase(x.f);
  b.erase(x.f);
  a.erase(x.s);
  b.erase(x.s);

  cs.insert(mp(a.size(), stat[x.f]));
  vs.insert(mp(b.size(), stat[x.f].f));
}

pii getc() {
  auto x = *cs.rbegin();
  if (x.f >= 2) {
    auto y = cnt[x.s];
    return mp(*y.begin(), *next(y.begin()));
  }
  return mp(-1, -1);
}

pii getv() {
  auto x = *vs.rbegin();
  if (x.f >= 2) {
    auto y = vcnt[x.s];
    return mp(*y.begin(), *next(y.begin()));
  }
  return mp(-1, -1);
}

pair<pii, pii> res[25005];

void solve(int tc) {
  cin >> n;
  f0r(i, n) {
    cin >> s; ss[i] = s;
    ll cv = 0; char t;
    f0r(i, s.length()) {
      if (ivow(s[i])) {
        ++cv; t = s[i];
      }
    }

    stat[i] = mp(cv, t);
    cnt[stat[i]].insert(i);
    vcnt[cv].insert(i);
  }

  for (auto x: cnt) cs.insert(mp(x.s.size(), x.f));
  for (auto x: vcnt) vs.insert(mp(x.s.size(), x.f));

  while (1) {
    pii x = getc();
    if (x.f != -1) {
      rm(x);
      pii y = getv();
      if (y.f == -1) y = getc();
      if (y.f == -1) break;

      res[ans++] = mp(mp(y.f, x.f), mp(y.s, x.s));
      rm(y);
    } else break;
  }

  printf("%lld\n", ans);
  f0r(i, ans) {
    pair<pii, pii> x = res[i];
    printf("%s %s\n", ss[x.f.f].c_str(), ss[x.f.s].c_str());
    printf("%s %s\n", ss[x.s.f].c_str(), ss[x.s.s].c_str());
  }
}

int main() {
  send help

  // usaco("file");

  int tc;
  tc = 1;
  // cin >> tc;
  for (int t = 0; t < tc; t++) solve(t);
}


#include <bits/stdc++.h>
#include <chrono>

using namespace std;
using namespace std::chrono;

// #pragma GCC target ("avx2")
// #pragma GCC optimization ("O3")
// #pragma GCC optimization ("unroll-loops")
// #pragma optimization_level 3
// #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define f0r(a, b) for (long long a = 0; a < (b); ++a)
#define f1r(a, b, c) for (long long a = (b); a < (c); ++a)
#define f0rd(a, b) for (long long a = (b); a >= 0; --a)
#define f1rd(a, b, c) for (long long a = (b); a >= (c); --a)
#define ms(arr, v) memset(arr, v, sizeof(arr))
#define pb push_back
#define send {ios_base::sync_with_stdio(false);}
#define help {cin.tie(NULL); cout.tie(NULL);}
#define fix(prec) {cout << setprecision(prec) << fixed;}
#define mp make_pair
#define f first
#define s second
#define presum(p, a, n) {p[0] = a[0]; for (int i = 1; i < (n); i++) p[i] = a[i] + p[i-1];}
#define all(v) v.begin(), v.end()
#define getunique(v) {sort(all(v)); v.erase(unique(all(v)), v.end());}
#define readgraph(list, edges) for (int i = 0; i < edges; i++) {int a, b; cin >> a >> b; a--; b--; list[a].pb(b); list[b].pb(a);}
#define ai(a, n) for (int ele = 0; ele < n; ele++) cin >> a[ele];
#define ain(a, lb, rb) for (int ele = lb; ele <= rb; ele++) cin >> a[ele];
#define ao(a, n) {for (int ele = 0; ele < (n); ele++) { if (ele) cout << " "; cout << a[ele]; } cout << '\n';}
#define aout(a, lb, rb) {for (int ele = (lb); ele <= (rb); ele++) { if (ele > (lb)) cout << " "; cout << a[ele]; } cout << '\n';}
typedef long long ll;
typedef double ld;
typedef long double lld;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vpi;
typedef vector<pll> vpl;

template<typename A> ostream& operator<<(ostream &cout, vector<A> const &v);
template<typename A, typename B> ostream& operator<<(ostream &cout, pair<A, B> const &p) { return cout << "(" << p.f << ", " << p.s << ")"; }
template<typename A> ostream& operator<<(ostream &cout, vector<A> const &v) {
  cout << "["; for(int i = 0; i < v.size(); i++) {if (i) cout << ", "; cout << v[i];} return cout << "]";
}
template<typename A, typename B> istream& operator>>(istream& cin, pair<A, B> &p) {
  cin >> p.first;
  return cin >> p.second;
}

mt19937 rng(steady_clock::now().time_since_epoch().count());
// mt19937 rng(61378913);
/* usage - just do rng() */

void usaco(string filename) {
  // #pragma message("be careful, freopen may be wrong")
	freopen((filename + ".in").c_str(), "r", stdin);
	freopen((filename + ".out").c_str(), "w", stdout);
}

const lld pi = 3.14159265358979323846;
// const ll mod = 1000000007;
// const ll mod = 998244353;
// ll mod;

ll n, m, k, q, l, r, x, y, z;
ll a[1000005];
ll b[1000005];
ll c[1000005];
string s, t;
ll ans = 0;

string ss[100005];
pair<ll, char> stat[100005];
map<pair<ll, char>, set<int> > cnt;
map<ll, set<int> > vcnt;
set<pair<int, pair<ll, char> > > cs;
set<pair<int, ll> > vs;

bool ivow(char a) {
  return a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u';
}

void rm(pii x) {
  set<int>& a = cnt[stat[x.f]];
  set<int>& b = vcnt[stat[x.f].f];
  cs.erase(mp(a.size(), stat[x.f]));
  vs.erase(mp(b.size(), stat[x.f].f));

  a.erase(x.f);
  b.erase(x.f);
  a.erase(x.s);
  b.erase(x.s);

  cs.insert(mp(a.size(), stat[x.f]));
  vs.insert(mp(b.size(), stat[x.f].f));
}

pii getc() {
  auto x = *cs.rbegin();
  if (x.f >= 2) {
    return mp(*cnt[x.s].begin(), *next(cnt[x.s].begin()));
  }
  return mp(-1, -1);
}

pii getv() {
  auto x = *vs.rbegin();
  if (x.f >= 2) {
    return mp(*vcnt[x.s].begin(), *next(vcnt[x.s].begin()));
  }
  return mp(-1, -1);
}

pair<pii, pii> res[25005];

void solve(int tc) {
  cin >> n;
  f0r(i, n) {
    cin >> s; ss[i] = s;
    ll cv = 0; char t;
    f0r(i, s.length()) {
      if (ivow(s[i])) {
        ++cv; t = s[i];
      }
    }

    stat[i] = mp(cv, t);
    cnt[stat[i]].insert(i);
    vcnt[cv].insert(i);
  }

  for (auto x: cnt) cs.insert(mp(x.s.size(), x.f));
  for (auto x: vcnt) vs.insert(mp(x.s.size(), x.f));

  while (1) {
    pii x = getc();
    if (x.f != -1) {
      rm(x);
      pii y = getv();
      if (y.f == -1) y = getc();
      if (y.f == -1) break;

      res[ans++] = mp(mp(y.f, x.f), mp(y.s, x.s));
      rm(y);
    } else break;
  }

  printf("%lld\n", ans);
  f0r(i, ans) {
    pair<pii, pii> x = res[i];
    printf("%s %s\n", ss[x.f.f].c_str(), ss[x.f.s].c_str());
    printf("%s %s\n", ss[x.s.f].c_str(), ss[x.s.s].c_str());
  }
}

int main() {
  send help

  // usaco("file");

  int tc;
  tc = 1;
  // cin >> tc;
  for (int t = 0; t < tc; t++) solve(t);
}


#include <bits/stdc++.h>
#include <chrono>

using namespace std;
using namespace std::chrono;

// #pragma GCC target ("avx2")
// #pragma GCC optimization ("O3")
// #pragma GCC optimization ("unroll-loops")
// #pragma optimization_level 3
// #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define f0r(a, b) for (long long a = 0; a < (b); ++a)
#define f1r(a, b, c) for (long long a = (b); a < (c); ++a)
#define f0rd(a, b) for (long long a = (b); a >= 0; --a)
#define f1rd(a, b, c) for (long long a = (b); a >= (c); --a)
#define ms(arr, v) memset(arr, v, sizeof(arr))
#define pb push_back
#define send {ios_base::sync_with_stdio(false);}
#define help {cin.tie(NULL); cout.tie(NULL);}
#define fix(prec) {cout << setprecision(prec) << fixed;}
#define mp make_pair
#define f first
#define s second
#define presum(p, a, n) {p[0] = a[0]; for (int i = 1; i < (n); i++) p[i] = a[i] + p[i-1];}
#define all(v) v.begin(), v.end()
#define getunique(v) {sort(all(v)); v.erase(unique(all(v)), v.end());}
#define readgraph(list, edges) for (int i = 0; i < edges; i++) {int a, b; cin >> a >> b; a--; b--; list[a].pb(b); list[b].pb(a);}
#define ai(a, n) for (int ele = 0; ele < n; ele++) cin >> a[ele];
#define ain(a, lb, rb) for (int ele = lb; ele <= rb; ele++) cin >> a[ele];
#define ao(a, n) {for (int ele = 0; ele < (n); ele++) { if (ele) cout << " "; cout << a[ele]; } cout << '\n';}
#define aout(a, lb, rb) {for (int ele = (lb); ele <= (rb); ele++) { if (ele > (lb)) cout << " "; cout << a[ele]; } cout << '\n';}
typedef long long ll;
typedef double ld;
typedef long double lld;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vpi;
typedef vector<pll> vpl;

template<typename A> ostream& operator<<(ostream &cout, vector<A> const &v);
template<typename A, typename B> ostream& operator<<(ostream &cout, pair<A, B> const &p) { return cout << "(" << p.f << ", " << p.s << ")"; }
template<typename A> ostream& operator<<(ostream &cout, vector<A> const &v) {
  cout << "["; for(int i = 0; i < v.size(); i++) {if (i) cout << ", "; cout << v[i];} return cout << "]";
}
template<typename A, typename B> istream& operator>>(istream& cin, pair<A, B> &p) {
  cin >> p.first;
  return cin >> p.second;
}

mt19937 rng(steady_clock::now().time_since_epoch().count());
// mt19937 rng(61378913);
/* usage - just do rng() */

void usaco(string filename) {
  // #pragma message("be careful, freopen may be wrong")
	freopen((filename + ".in").c_str(), "r", stdin);
	freopen((filename + ".out").c_str(), "w", stdout);
}

const lld pi = 3.14159265358979323846;
// const ll mod = 1000000007;
// const ll mod = 998244353;
// ll mod;

ll n, m, k, q, l, r, x, y, z;
ll a[1000005];
ll b[1000005];
ll c[1000005];
string s, t;
ll ans = 0;

string ss[100005];
pair<ll, char> stat[100005];
map<pair<ll, char>, set<int> > cnt;
map<ll, set<int> > vcnt;
set<pair<int, pair<ll, char> > > cs;
set<pair<int, ll> > vs;

bool ivow(char a) {
  return a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u';
}

void rm(pii x) {
  cs.erase(mp(cnt[stat[x.f]].size(), stat[x.f]));
  vs.erase(mp(vcnt[stat[x.f].f].size(), stat[x.f].f));

  cnt[stat[x.f]].erase(x.f);
  vcnt[stat[x.f].f].erase(x.f);
  cnt[stat[x.f]].erase(x.s);
  vcnt[stat[x.f].f].erase(x.s);

  cs.insert(mp(cnt[stat[x.f]].size(), stat[x.f]));
  vs.insert(mp(vcnt[stat[x.f].f].size(), stat[x.f].f));
}

pii getc() {
  auto x = *cs.rbegin();
  if (x.f >= 2) {
    auto y = cnt[x.s];
    return mp(*y.begin(), *next(y.begin()));
  }
  return mp(-1, -1);
}

pii getv() {
  auto x = *vs.rbegin();
  if (x.f >= 2) {
    auto y = vcnt[x.s];
    return mp(*y.begin(), *next(y.begin()));
  }
  return mp(-1, -1);
}

vector<pair<pii, pii> > res;

void solve(int tc) {
  cin >> n;
  f0r(i, n) {
    cin >> s; ss[i] = s;
    ll cv = 0; char t;
    f0r(i, s.length()) {
      if (ivow(s[i])) {
        ++cv; t = s[i];
      }
    }

    stat[i] = mp(cv, t);
    cnt[stat[i]].insert(i);
    vcnt[cv].insert(i);
  }

  for (auto x: cnt) cs.insert(mp(x.s.size(), x.f));
  for (auto x: vcnt) vs.insert(mp(x.s.size(), x.f));

  while (1) {
    pii x = getc();
    if (x.f != -1) {
      rm(x);
      pii y = getv();
      if (y.f == -1) y = getc();
      if (y.f == -1) break;

      res.pb(mp(mp(y.f, x.f), mp(y.s, x.s)));
      rm(y);
    } else break;
  }

  cout << res.size() << '\n';
  for (auto x: res) {
    cout << ss[x.f.f] << " " << ss[x.f.s] << '\n';
    cout << ss[x.s.f] << " " << ss[x.s.s] << '\n';
  }
}

int main() {
  send help

  // usaco("file");

  int tc;
  tc = 1;
  // cin >> tc;
  for (int t = 0; t < tc; t++) solve(t);
}


#include <bits/stdc++.h>
#include <chrono>

using namespace std;
using namespace std::chrono;

// #pragma GCC target ("avx2")
// #pragma GCC optimization ("O3")
// #pragma GCC optimization ("unroll-loops")
// #pragma optimization_level 3
// #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define f0r(a, b) for (long long a = 0; a < (b); ++a)
#define f1r(a, b, c) for (long long a = (b); a < (c); ++a)
#define f0rd(a, b) for (long long a = (b); a >= 0; --a)
#define f1rd(a, b, c) for (long long a = (b); a >= (c); --a)
#define ms(arr, v) memset(arr, v, sizeof(arr))
#define pb push_back
#define send {ios_base::sync_with_stdio(false);}
#define help {cin.tie(NULL); cout.tie(NULL);}
#define fix(prec) {cout << setprecision(prec) << fixed;}
#define mp make_pair
#define f first
#define s second
#define presum(p, a, n) {p[0] = a[0]; for (int i = 1; i < (n); i++) p[i] = a[i] + p[i-1];}
#define all(v) v.begin(), v.end()
#define getunique(v) {sort(all(v)); v.erase(unique(all(v)), v.end());}
#define readgraph(list, edges) for (int i = 0; i < edges; i++) {int a, b; cin >> a >> b; a--; b--; list[a].pb(b); list[b].pb(a);}
#define ai(a, n) for (int ele = 0; ele < n; ele++) cin >> a[ele];
#define ain(a, lb, rb) for (int ele = lb; ele <= rb; ele++) cin >> a[ele];
#define ao(a, n) {for (int ele = 0; ele < (n); ele++) { if (ele) cout << " "; cout << a[ele]; } cout << '\n';}
#define aout(a, lb, rb) {for (int ele = (lb); ele <= (rb); ele++) { if (ele > (lb)) cout << " "; cout << a[ele]; } cout << '\n';}
typedef long long ll;
typedef double ld;
typedef long double lld;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vpi;
typedef vector<pll> vpl;

template<typename A> ostream& operator<<(ostream &cout, vector<A> const &v);
template<typename A, typename B> ostream& operator<<(ostream &cout, pair<A, B> const &p) { return cout << "(" << p.f << ", " << p.s << ")"; }
template<typename A> ostream& operator<<(ostream &cout, vector<A> const &v) {
  cout << "["; for(int i = 0; i < v.size(); i++) {if (i) cout << ", "; cout << v[i];} return cout << "]";
}
template<typename A, typename B> istream& operator>>(istream& cin, pair<A, B> &p) {
  cin >> p.first;
  return cin >> p.second;
}

mt19937 rng(steady_clock::now().time_since_epoch().count());
// mt19937 rng(61378913);
/* usage - just do rng() */

void usaco(string filename) {
  // #pragma message("be careful, freopen may be wrong")
	freopen((filename + ".in").c_str(), "r", stdin);
	freopen((filename + ".out").c_str(), "w", stdout);
}

const lld pi = 3.14159265358979323846;
// const ll mod = 1000000007;
// const ll mod = 998244353;
// ll mod;

ll n, m, k, q, l, r, x, y, z;
ll a[1000005];
ll b[1000005];
ll c[1000005];
string s, t;
ll ans = 0;

string ss[100005];
pair<ll, char> stat[100005];
map<pair<ll, char>, set<int> > cnt;
map<ll, set<int> > vcnt;
set<pair<int, pair<ll, char> > > cs;
set<pair<int, ll> > vs;

bool ivow(char a) {
  return a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u';
}

void rem(int x) {
  set<int>& a = cnt[stat[x]];
  set<int>& b = vcnt[stat[x].f];

  cs.erase(mp(a.size(), stat[x]));
  vs.erase(mp(b.size(), stat[x].f));

  a.erase(x);
  b.erase(x);

  if (a.size()) cs.insert(mp(a.size(), stat[x]));
  if (b.size()) vs.insert(mp(b.size(), stat[x].f));
}

void rm(pii x) {
  rem(x.f); rem(x.s);
}

pii getc() {
  if (!cs.size()) return mp(-1, -1);
  auto x = *cs.rbegin();
  if (x.f >= 2) {
    return mp(*cnt[x.s].begin(), *cnt[x.s].rbegin());
  }
  return mp(-1, -1);
}

pii getv() {
  if (!vs.size()) return mp(-1, -1);
  auto x = *vs.rbegin();
  if (x.f >= 2) {
    return mp(*vcnt[x.s].begin(), *vcnt[x.s].rbegin());
  }
  return mp(-1, -1);
}

pair<pii, pii> res[25005];
vpi fi, se;

void solve(int tc) {
  cin >> n;
  f0r(i, n) {
    cin >> s; ss[i] = s;
    ll cv = 0; char t;
    f0r(i, s.length()) {
      if (ivow(s[i])) {
        ++cv; t = s[i];
      }
    }

    stat[i] = mp(cv, t);
    cnt[stat[i]].insert(i);
    vcnt[cv].insert(i);
  }

  for (auto x: cnt) cs.insert(mp(x.s.size(), x.f));
  for (auto x: vcnt) vs.insert(mp(x.s.size(), x.f));

  while (1) {
    pii x = getc();
    if (x.f != -1) {
      rm(x);
      fi.pb(x);
    } else break;
  }

  while (1) {
    pii y = getv();
    if (y.f != -1) {
      rm(y);
      se.pb(y);
    } else break;
  }

  while (1) {
    pii x, y;
    if (!fi.size()) break;
    x = fi.back();
    fi.pop_back();
    if (se.size()) {
      y = se.back();
      se.pop_back();
    } else if (fi.size()) {
      y = fi.back();
      fi.pop_back();
    } else break;

    res[ans++] = mp(mp(y.f, x.f), mp(y.s, x.s));
  }

  printf("%lld\n", ans);
  f0r(i, ans) {
    pair<pii, pii> x = res[i];
    printf("%s %s\n", ss[x.f.f].c_str(), ss[x.f.s].c_str());
    printf("%s %s\n", ss[x.s.f].c_str(), ss[x.s.s].c_str());
  }
}

int main() {
  send help

  // usaco("file");

  int tc;
  tc = 1;
  // cin >> tc;
  for (int t = 0; t < tc; t++) solve(t);
}


#include <bits/stdc++.h>
#include <chrono>

using namespace std;
using namespace std::chrono;

// #pragma GCC target ("avx2")
// #pragma GCC optimization ("O3")
// #pragma GCC optimization ("unroll-loops")
// #pragma optimization_level 3
// #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define f0r(a, b) for (long long a = 0; a < (b); ++a)
#define f1r(a, b, c) for (long long a = (b); a < (c); ++a)
#define f0rd(a, b) for (long long a = (b); a >= 0; --a)
#define f1rd(a, b, c) for (long long a = (b); a >= (c); --a)
#define ms(arr, v) memset(arr, v, sizeof(arr))
#define pb push_back
#define send {ios_base::sync_with_stdio(false);}
#define help {cin.tie(NULL); cout.tie(NULL);}
#define fix(prec) {cout << setprecision(prec) << fixed;}
#define mp make_pair
#define f first
#define s second
#define presum(p, a, n) {p[0] = a[0]; for (int i = 1; i < (n); i++) p[i] = a[i] + p[i-1];}
#define all(v) v.begin(), v.end()
#define getunique(v) {sort(all(v)); v.erase(unique(all(v)), v.end());}
#define readgraph(list, edges) for (int i = 0; i < edges; i++) {int a, b; cin >> a >> b; a--; b--; list[a].pb(b); list[b].pb(a);}
#define ai(a, n) for (int ele = 0; ele < n; ele++) cin >> a[ele];
#define ain(a, lb, rb) for (int ele = lb; ele <= rb; ele++) cin >> a[ele];
#define ao(a, n) {for (int ele = 0; ele < (n); ele++) { if (ele) cout << " "; cout << a[ele]; } cout << '\n';}
#define aout(a, lb, rb) {for (int ele = (lb); ele <= (rb); ele++) { if (ele > (lb)) cout << " "; cout << a[ele]; } cout << '\n';}
typedef long long ll;
typedef double ld;
typedef long double lld;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vpi;
typedef vector<pll> vpl;

template<typename A> ostream& operator<<(ostream &cout, vector<A> const &v);
template<typename A, typename B> ostream& operator<<(ostream &cout, pair<A, B> const &p) { return cout << "(" << p.f << ", " << p.s << ")"; }
template<typename A> ostream& operator<<(ostream &cout, vector<A> const &v) {
  cout << "["; for(int i = 0; i < v.size(); i++) {if (i) cout << ", "; cout << v[i];} return cout << "]";
}
template<typename A, typename B> istream& operator>>(istream& cin, pair<A, B> &p) {
  cin >> p.first;
  return cin >> p.second;
}

mt19937 rng(steady_clock::now().time_since_epoch().count());
// mt19937 rng(61378913);
/* usage - just do rng() */

void usaco(string filename) {
  // #pragma message("be careful, freopen may be wrong")
	freopen((filename + ".in").c_str(), "r", stdin);
	freopen((filename + ".out").c_str(), "w", stdout);
}

const lld pi = 3.14159265358979323846;
// const ll mod = 1000000007;
// const ll mod = 998244353;
// ll mod;

ll n, m, k, q, l, r, x, y, z;
ll a[1000005];
ll b[1000005];
ll c[1000005];
string s, t;
ll ans = 0;

string ss[100005];
pair<ll, char> stat[100005];
map<pair<ll, char>, set<int> > cnt;
map<ll, set<int> > vcnt;
set<pair<int, pair<ll, char> > > cs;
set<pair<int, ll> > vs;

bool ivow(char a) {
  return a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u';
}

void rm(pii x) {
  set<int>& a = cnt[stat[x.f]];
  set<int>& b = vcnt[stat[x.f].f];
  cs.erase(mp(a.size(), stat[x.f]));
  vs.erase(mp(b.size(), stat[x.f].f));

  a.erase(x.f);
  b.erase(x.f);
  a.erase(x.s);
  b.erase(x.s);

  cs.insert(mp(a.size(), stat[x.f]));
  vs.insert(mp(b.size(), stat[x.f].f));
}

pii getc() {
  auto x = *cs.rbegin();
  if (x.f >= 2) {
    return mp(*cnt[x.s].begin(), *cnt[x.s].rbegin());
  }
  return mp(-1, -1);
}

pii getv() {
  auto x = *vs.rbegin();
  if (x.f >= 2) {
    return mp(*vcnt[x.s].begin(), *vcnt[x.s].rbegin());
  }
  return mp(-1, -1);
}

pair<pii, pii> res[25005];

void solve(int tc) {
  cin >> n;
  f0r(i, n) {
    cin >> s; ss[i] = s;
    ll cv = 0; char t;
    f0r(i, s.length()) {
      if (ivow(s[i])) {
        ++cv; t = s[i];
      }
    }

    stat[i] = mp(cv, t);
    cnt[stat[i]].insert(i);
    vcnt[cv].insert(i);
  }

  for (auto x: cnt) cs.insert(mp(x.s.size(), x.f));
  for (auto x: vcnt) vs.insert(mp(x.s.size(), x.f));

  while (1) {
    pii x = getc();
    if (x.f != -1) {
      rm(x);
      pii y = getv();
      if (y.f == -1) y = getc();
      if (y.f == -1) break;

      res[ans++] = mp(mp(y.f, x.f), mp(y.s, x.s));
      rm(y);
    } else break;
  }

  printf("%lld\n", ans);
  f0r(i, ans) {
    pair<pii, pii> x = res[i];
    printf("%s %s\n", ss[x.f.f].c_str(), ss[x.f.s].c_str());
    printf("%s %s\n", ss[x.s.f].c_str(), ss[x.s.s].c_str());
  }
}

int main() {
  send help

  // usaco("file");

  int tc;
  tc = 1;
  // cin >> tc;
  for (int t = 0; t < tc; t++) solve(t);
}


#include <bits/stdc++.h>
#include <chrono>

using namespace std;
using namespace std::chrono;

// #pragma GCC target ("avx2")
// #pragma GCC optimization ("O3")
// #pragma GCC optimization ("unroll-loops")
// #pragma optimization_level 3
// #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define f0r(a, b) for (long long a = 0; a < (b); ++a)
#define f1r(a, b, c) for (long long a = (b); a < (c); ++a)
#define f0rd(a, b) for (long long a = (b); a >= 0; --a)
#define f1rd(a, b, c) for (long long a = (b); a >= (c); --a)
#define ms(arr, v) memset(arr, v, sizeof(arr))
#define pb push_back
#define send {ios_base::sync_with_stdio(false);}
#define help {cin.tie(NULL); cout.tie(NULL);}
#define fix(prec) {cout << setprecision(prec) << fixed;}
#define mp make_pair
#define f first
#define s second
#define presum(p, a, n) {p[0] = a[0]; for (int i = 1; i < (n); i++) p[i] = a[i] + p[i-1];}
#define all(v) v.begin(), v.end()
#define getunique(v) {sort(all(v)); v.erase(unique(all(v)), v.end());}
#define readgraph(list, edges) for (int i = 0; i < edges; i++) {int a, b; cin >> a >> b; a--; b--; list[a].pb(b); list[b].pb(a);}
#define ai(a, n) for (int ele = 0; ele < n; ele++) cin >> a[ele];
#define ain(a, lb, rb) for (int ele = lb; ele <= rb; ele++) cin >> a[ele];
#define ao(a, n) {for (int ele = 0; ele < (n); ele++) { if (ele) cout << " "; cout << a[ele]; } cout << '\n';}
#define aout(a, lb, rb) {for (int ele = (lb); ele <= (rb); ele++) { if (ele > (lb)) cout << " "; cout << a[ele]; } cout << '\n';}
typedef long long ll;
typedef double ld;
typedef long double lld;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vpi;
typedef vector<pll> vpl;

template<typename A> ostream& operator<<(ostream &cout, vector<A> const &v);
template<typename A, typename B> ostream& operator<<(ostream &cout, pair<A, B> const &p) { return cout << "(" << p.f << ", " << p.s << ")"; }
template<typename A> ostream& operator<<(ostream &cout, vector<A> const &v) {
  cout << "["; for(int i = 0; i < v.size(); i++) {if (i) cout << ", "; cout << v[i];} return cout << "]";
}
template<typename A, typename B> istream& operator>>(istream& cin, pair<A, B> &p) {
  cin >> p.first;
  return cin >> p.second;
}

mt19937 rng(steady_clock::now().time_since_epoch().count());
// mt19937 rng(61378913);
/* usage - just do rng() */

void usaco(string filename) {
  // #pragma message("be careful, freopen may be wrong")
	freopen((filename + ".in").c_str(), "r", stdin);
	freopen((filename + ".out").c_str(), "w", stdout);
}

const lld pi = 3.14159265358979323846;
// const ll mod = 1000000007;
// const ll mod = 998244353;
// ll mod;

ll n, m, k, q, l, r, x, y, z;
ll a[1000005];
ll b[1000005];
ll c[1000005];
string s, t;
ll ans = 0;

string ss[100005];
pair<ll, char> stat[100005];
map<pair<ll, char>, set<int> > cnt;
map<ll, set<int> > vcnt;
set<pair<int, pair<ll, char> > > cs;
set<pair<int, ll> > vs;

bool ivow(char a) {
  return a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u';
}

void rem(int x) {
  set<int>& a = cnt[stat[x]];
  set<int>& b = vcnt[stat[x].f];

  cs.erase(mp(a.size(), stat[x]));
  vs.erase(mp(b.size(), stat[x].f));

  a.erase(x);
  b.erase(x);

  if (a.size()) cs.insert(mp(a.size(), stat[x]));
  if (b.size()) vs.insert(mp(b.size(), stat[x].f));
}

void rm(pii x) {
  rem(x.f); rem(x.s);
}

pii getc() {
  if (!cs.size()) return mp(-1, -1);
  auto x = *cs.rbegin();
  if (x.f >= 2) {
    return mp(*cnt[x.s].begin(), *cnt[x.s].rbegin());
  }
  return mp(-1, -1);
}

pii getv() {
  if (!vs.size()) return mp(-1, -1);
  auto x = *vs.rbegin();
  if (x.f >= 2) {
    return mp(*vcnt[x.s].begin(), *vcnt[x.s].rbegin());
  }
  return mp(-1, -1);
}

pair<pii, pii> res[25005];

void solve(int tc) {
  cin >> n;
  f0r(i, n) {
    cin >> s; ss[i] = s;
    ll cv = 0; char t;
    f0r(i, s.length()) {
      if (ivow(s[i])) {
        ++cv; t = s[i];
      }
    }

    stat[i] = mp(cv, t);
    cnt[stat[i]].insert(i);
    vcnt[cv].insert(i);
  }

  for (auto x: cnt) cs.insert(mp(x.s.size(), x.f));
  for (auto x: vcnt) vs.insert(mp(x.s.size(), x.f));

  while (1) {
    pii x = getc();
    if (x.f != -1) {
      rm(x);
      pii y = getv();
      if (y.f == -1) y = getc();
      if (y.f == -1) break;

      res[ans++] = mp(mp(y.f, x.f), mp(y.s, x.s));
      rm(y);
    } else break;
  }

  printf("%lld\n", ans);
  f0r(i, ans) {
    pair<pii, pii> x = res[i];
    printf("%s %s\n", ss[x.f.f].c_str(), ss[x.f.s].c_str());
    printf("%s %s\n", ss[x.s.f].c_str(), ss[x.s.s].c_str());
  }
}

int main() {
  send help

  // usaco("file");

  int tc;
  tc = 1;
  // cin >> tc;
  for (int t = 0; t < tc; t++) solve(t);
}


#include<iostream>
#include<algorithm>
#include<numeric>
#include<vector>
#include<set>
#include<map>
#include <string>
#define cinf(n,x) for(int i=0;i<(n);i++) cin >> x[i];
typedef long long int ll;
using namespace std;
int used[100001];
int main(){
	int n; cin >>n;
	vector<string> s(n);
	char last[100001];
	vector<pair<ll,ll> > v,v1;
	vector<pair<ll,ll> > S;
	for(int i=0;i<n;i++){
		cin >>s[i];
		ll cnt=0;
		for(int j=0;j<s[i].size();j++){
			if(s[i][j]=='a'||s[i][j]=='i'||s[i][j]=='u'||s[i][j]=='e'||s[i][j]=='o'){
				cnt++;
				last[i]=s[i][j];
			}
		}
		S.push_back(make_pair(cnt,i));
	}
	bool c=false;
	sort(S.begin(),S.end());
	for(int i=0;i<n;i++){
		int j=i+1;
		if(used[S[i].second]==1)continue;
		while(S[i].first==S[j].first){
			if(last[S[i].second]==last[S[j].second]&&used[S[i].second]==0&&used[S[j].second]==0){
				v1.push_back(make_pair(S[i].second,S[j].second));
				used[S[i].second]=1; used[S[j].second]=1;
				c=true;
				break;
			}
			j++;
		}
	}
	if(!c){
		cout << 0 << endl;
		return 0;
	}
	bool d=false;
	for(int i=0;i<n;i++){
		int j=i+1;
		if(used[S[i].second]==1)continue;
		while(S[i].first==S[j].first){
			if(used[S[j].second]==0){
				v.push_back(make_pair(S[i].second,S[j].second));
				used[S[i].second]=1; used[S[j].second]=1;
				d=true;
				break;
			}
			j++;
		}
	}
	if(!d){
		cout << (ll)v1.size()/2 << endl;
		for(int i=0;i<v1.size()/2;i++){
			cout << s[v1[i].first] << " " << s[v1[i+1].first] << endl;
			cout << s[v1[i].second] << " " << s[v1[i+1].second] << endl;
		}
		return 0;
	}
	ll ans=min((ll)v.size(),(ll)v1.size());
	bool a=false;
	ll copy=ans;
	if((ll)v1.size()-(ll)v.size()>1){
		ans+=(v1.size()-v.size())/2;
		a=true;
	}
	ll b=0;
	cout << max(ans,b) << endl;
	if(max(ans,b)==0){
		return 0;
	}
	for(int i=0;i<copy;i++){
		//printf("%s %s\n",s[v[i].first] ,s[v1[i].first]);
		//printf("%s %s\n",s[v[i].second] ,s[v1[i].second]);
		cout <<s[v[i].first] <<" " <<s[v1[i].first]<< "\n";
		cout << s[v[i].second] <<" " <<s[v1[i].second] << "\n";
	}
	if(a){for(int i=0;i<(v1.size()-v.size())/2;i++){
		//printf("%s %s\n",s[v1[v.size()+i*2].first] ,s[v1[v.size()+i*2+1].first]);
		//printf("%s %s\n",s[v1[v.size()+i*2].second] ,s[v1[v.size()+i*2+1].second]);
		cout << s[v1[v.size()+i*2].first]<<" " <<s[v1[v.size()+i*2+1].first] << "\n";
		cout << s[v1[v.size()+i*2].second] << " " <<s[v1[v.size()+i*2+1].second] << "\n";
		}
	}
}


#include<iostream>
#include<algorithm>
#include<numeric>
#include<vector>
#include<set>
#include<map>
#include <string>
#define cinf(n,x) for(int i=0;i<(n);i++) cin >> x[i];
typedef long long int ll;
using namespace std;
int used[100001];
int main(){
	int n; cin >>n;
	vector<string> s(n);
	char last[100001];
	vector<pair<int,int> > v,v1;
	vector<pair<int,int> > S;
	for(int i=0;i<n;i++){
		cin >>s[i];
		int cnt=0;
		for(int j=0;j<s[i].size();j++){
			if(s[i][j]=='a'||s[i][j]=='i'||s[i][j]=='u'||s[i][j]=='e'||s[i][j]=='o'){
				cnt++;
				last[i]=s[i][j];
			}
		}
		S.push_back(make_pair(cnt,i));
	}
	sort(S.begin(),S.end());
	for(int i=0;i<n;i++){
		int j=i+1;
		if(used[S[i].second]==1)continue;
		while(S[i].first==S[j].first){
			if(last[S[i].second]==last[S[j].second]&&used[S[i].second]==0&&used[S[j].second]==0){
				v1.push_back(make_pair(S[i].second,S[j].second));
				used[S[i].second]=1; used[S[j].second]=1;
				break;
			}
			j++;
		}
	}
	for(int i=0;i<n;i++){
		int j=i+1;
		if(used[S[i].second]==1)continue;
		while(S[i].first==S[j].first){
			if(used[S[j].second]==0){
				v.push_back(make_pair(S[i].second,S[j].second));
				used[S[i].second]=1; used[S[j].second]=1;
				break;
			}
			j++;
		}
	}
	int ans=min(v.size(),v1.size());
	bool a=false;
	int copy=ans;
	if(v1.size()-v.size()>1){
		ans+=(v1.size()-v.size())/2;
		a=true;
	}
	cout << max(ans,0) << endl;
	if(max(ans,0)==0){
		return 0;
	}
	for(int i=0;i<copy;i++){
		//printf("%s %s\n",s[v[i].first] ,s[v1[i].first]);
		//printf("%s %s\n",s[v[i].second] ,s[v1[i].second]);
		cout <<s[v[i].first] <<" " <<s[v1[i].first]<< endl;
		cout << s[v[i].second] <<" " <<s[v1[i].second] << endl;
	}
	if(a){for(int i=0;i<(v1.size()-v.size())/2;i++){
		//printf("%s %s\n",s[v1[v.size()+i*2].first] ,s[v1[v.size()+i*2+1].first]);
		//printf("%s %s\n",s[v1[v.size()+i*2].second] ,s[v1[v.size()+i*2+1].second]);
		cout << s[v1[v.size()+i*2].first]<<" " <<s[v1[v.size()+i*2+1].first] << endl;
		cout << s[v1[v.size()+i*2].second] << " " <<s[v1[v.size()+i*2+1].second] << endl;
		}
	}
}


#include<iostream>
#include<algorithm>
#include<numeric>
#include<vector>
#include<set>
#include<map>
#include <string>
#define cinf(n,x) for(int i=0;i<(n);i++) cin >> x[i];
typedef long long int ll;
using namespace std;
int used[100001];
int main(){
	int n; cin >>n;
	vector<string> s(n);
	char last[100001];
	vector<pair<ll,ll> > v,v1;
	vector<pair<ll,ll> > S;
	for(int i=0;i<n;i++){
		cin >>s[i];
		ll cnt=0;
		for(int j=0;j<s[i].size();j++){
			if(s[i][j]=='a'||s[i][j]=='i'||s[i][j]=='u'||s[i][j]=='e'||s[i][j]=='o'){
				cnt++;
				last[i]=s[i][j];
			}
		}
		S.push_back(make_pair(cnt,i));
	}
	sort(S.begin(),S.end());
	for(int i=0;i<n;i++){
		int j=i+1;
		if(used[S[i].second]==1)continue;
		while(S[i].first==S[j].first){
			if(last[S[i].second]==last[S[j].second]&&used[S[i].second]==0&&used[S[j].second]==0){
				v1.push_back(make_pair(S[i].second,S[j].second));
				used[S[i].second]=1; used[S[j].second]=1;
				break;
			}
			j++;
		}
	}
	for(int i=0;i<n;i++){
		int j=i+1;
		if(used[S[i].second]==1)continue;
		while(S[i].first==S[j].first){
			if(used[S[j].second]==0){
				v.push_back(make_pair(S[i].second,S[j].second));
				used[S[i].second]=1; used[S[j].second]=1;
				break;
			}
			j++;
		}
	}
	ll ans=min(v.size(),v1.size());
	bool a=false;
	ll copy=ans;
	if(v1.size()-v.size()>1){
		ans+=(v1.size()-v.size())/2;
		a=true;
	}
	ll b=0;
	cout << max(ans,b) << endl;
	if(max(ans,b)==0){
		return 0;
	}
	for(int i=0;i<copy;i++){
		//printf("%s %s\n",s[v[i].first] ,s[v1[i].first]);
		//printf("%s %s\n",s[v[i].second] ,s[v1[i].second]);
		cout <<s[v[i].first] <<" " <<s[v1[i].first]<< endl;
		cout << s[v[i].second] <<" " <<s[v1[i].second] << endl;
	}
	if(a){for(int i=0;i<(v1.size()-v.size())/2;i++){
		//printf("%s %s\n",s[v1[v.size()+i*2].first] ,s[v1[v.size()+i*2+1].first]);
		//printf("%s %s\n",s[v1[v.size()+i*2].second] ,s[v1[v.size()+i*2+1].second]);
		cout << s[v1[v.size()+i*2].first]<<" " <<s[v1[v.size()+i*2+1].first] << endl;
		cout << s[v1[v.size()+i*2].second] << " " <<s[v1[v.size()+i*2+1].second] << endl;
		}
	}
}


#include<iostream>
#include<algorithm>
#include<numeric>
#include<vector>
#include<set>
#include<map>
#include <string>
#define cinf(n,x) for(int i=0;i<(n);i++) cin >> x[i];
typedef long long int ll;
using namespace std;
int used[100001];
int main(){
	int n; cin >>n;
	vector<string> s(n);
	char last[100001];
	vector<pair<ll,ll> > v,v1;
	vector<pair<ll,ll> > S;
	for(int i=0;i<n;i++){
		cin >>s[i];
		ll cnt=0;
		for(int j=0;j<s[i].size();j++){
			if(s[i][j]=='a'||s[i][j]=='i'||s[i][j]=='u'||s[i][j]=='e'||s[i][j]=='o'){
				cnt++;
				last[i]=s[i][j];
			}
		}
		S.push_back(make_pair(cnt,i));
	}
	bool c=false;
	sort(S.begin(),S.end());
	for(int i=0;i<n;i++){
		int j=i+1;
		if(used[S[i].second]==1)continue;
		while(S[i].first==S[j].first){
			if(last[S[i].second]==last[S[j].second]&&used[S[i].second]==0&&used[S[j].second]==0&&j<n){
				v1.push_back(make_pair(S[i].second,S[j].second));
				used[S[i].second]=1; used[S[j].second]=1;
				c=true;
				break;
			}
			j++;
		}
	}
	if(!c){
		cout << 0 << endl;
		return 0;
	}
	bool d=false;
	for(int i=0;i<n;i++){
		int j=i+1;
		if(used[S[i].second]==1)continue;
		while(S[i].first==S[j].first&&j<n){
			if(used[S[j].second]==0){
				v.push_back(make_pair(S[i].second,S[j].second));
				used[S[i].second]=1; used[S[j].second]=1;
				d=true;
				break;
			}
			j++;
		}
	}
	if(!d){
		cout << (ll)v1.size()/2 << endl;
		for(int i=0;i<v1.size()/2;i++){
			cout << s[v1[i*2].first] << " " << s[v1[2*i+1].first] << endl;
			cout << s[v1[i*2].second] << " " << s[v1[2*i+1].second] << endl;
		}
		return 0;
	}
	ll ans=min((ll)v.size(),(ll)v1.size());
	bool a=false;
	ll copy=ans;
	if((ll)v1.size()-(ll)v.size()>1){
		ans+=(v1.size()-v.size())/2;
		a=true;
	}
	ll b=0;
	cout << max(ans,b) << endl;
	if(max(ans,b)==0){
		return 0;
	}
	for(int i=0;i<copy;i++){
		//printf("%s %s\n",s[v[i].first] ,s[v1[i].first]);
		//printf("%s %s\n",s[v[i].second] ,s[v1[i].second]);
		cout <<s[v[i].first] <<" " <<s[v1[i].first]<< "\n";
		cout << s[v[i].second] <<" " <<s[v1[i].second] << "\n";
	}
	if(a){for(int i=0;i<(v1.size()-v.size())/2;i++){
		//printf("%s %s\n",s[v1[v.size()+i*2].first] ,s[v1[v.size()+i*2+1].first]);
		//printf("%s %s\n",s[v1[v.size()+i*2].second] ,s[v1[v.size()+i*2+1].second]);
		cout << s[v1[v.size()+i*2].first]<<" " <<s[v1[v.size()+i*2+1].first] << "\n";
		cout << s[v1[v.size()+i*2].second] << " " <<s[v1[v.size()+i*2+1].second] << "\n";
		}
	}
}


#include<iostream>
#include<algorithm>
#include<numeric>
#include<vector>
#include<set>
#include<map>
#include <string>
#define cinf(n,x) for(int i=0;i<(n);i++) cin >> x[i];
typedef long long int ll;
using namespace std;
int used[100001];
int main(){
	int n; cin >>n;
	vector<string> s(n);
	char last[100001];
	vector<pair<ll,ll> > v,v1;
	vector<pair<ll,ll> > S;
	for(int i=0;i<n;i++){
		cin >>s[i];
		ll cnt=0;
		for(int j=0;j<s[i].size();j++){
			if(s[i][j]=='a'||s[i][j]=='i'||s[i][j]=='u'||s[i][j]=='e'||s[i][j]=='o'){
				cnt++;
				last[i]=s[i][j];
			}
		}
		S.push_back(make_pair(cnt,i));
	}
	bool c=false;
	sort(S.begin(),S.end());
	for(int i=0;i<n;i++){
		int j=i+1;
		if(used[S[i].second]==1)continue;
		while(S[i].first==S[j].first){
			if(last[S[i].second]==last[S[j].second]&&used[S[i].second]==0&&used[S[j].second]==0){
				v1.push_back(make_pair(S[i].second,S[j].second));
				used[S[i].second]=1; used[S[j].second]=1;
				c=true;
				break;
			}
			j++;
		}
	}
	if(!c){
		cout << 0 << endl;
		return 0;
	}
	bool d=false;
	for(int i=0;i<n;i++){
		int j=i+1;
		if(used[S[i].second]==1)continue;
		while(S[i].first==S[j].first){
			if(used[S[j].second]==0){
				v.push_back(make_pair(S[i].second,S[j].second));
				used[S[i].second]=1; used[S[j].second]=1;
				d=true;
				break;
			}
			j++;
		}
	}
	if(!d){
		cout << v1.size()/2 << endl;
		for(int i=0;i<v1.size()/2;i++){
			cout << s[v1[i].first] << " " << s[v1[i+1].first] << endl;
			cout << s[v1[i].second] << " " << s[v1[i+1].second] << endl;
		}
		return 0;
	}
	ll ans=min(v.size(),v1.size());
	bool a=false;
	ll copy=ans;
	if(v1.size()-v.size()>1){
		ans+=(v1.size()-v.size())/2;
		a=true;
	}
	ll b=0;
	cout << max(ans,b) << endl;
	if(max(ans,b)==0){
		return 0;
	}
	for(int i=0;i<copy;i++){
		//printf("%s %s\n",s[v[i].first] ,s[v1[i].first]);
		//printf("%s %s\n",s[v[i].second] ,s[v1[i].second]);
		cout <<s[v[i].first] <<" " <<s[v1[i].first]<< "\n";
		cout << s[v[i].second] <<" " <<s[v1[i].second] << "\n";
	}
	if(a){for(int i=0;i<(v1.size()-v.size())/2;i++){
		//printf("%s %s\n",s[v1[v.size()+i*2].first] ,s[v1[v.size()+i*2+1].first]);
		//printf("%s %s\n",s[v1[v.size()+i*2].second] ,s[v1[v.size()+i*2+1].second]);
		cout << s[v1[v.size()+i*2].first]<<" " <<s[v1[v.size()+i*2+1].first] << "\n";
		cout << s[v1[v.size()+i*2].second] << " " <<s[v1[v.size()+i*2+1].second] << "\n";
		}
	}
}


#include<iostream>
#include<algorithm>
#include<numeric>
#include<vector>
#include<set>
#include<map>
#include <string>
#define cinf(n,x) for(int i=0;i<(n);i++) cin >> x[i];
typedef long long int ll;
using namespace std;
int used[100001];
int main(){
	int n; cin >>n;
	vector<string> s(n);
	char last[100001];
	vector<pair<ll,ll> > v,v1;
	vector<pair<ll,ll> > S;
	for(int i=0;i<n;i++){
		cin >>s[i];
		ll cnt=0;
		for(int j=0;j<s[i].size();j++){
			if(s[i][j]=='a'||s[i][j]=='i'||s[i][j]=='u'||s[i][j]=='e'||s[i][j]=='o'){
				cnt++;
				last[i]=s[i][j];
			}
		}
		S.push_back(make_pair(cnt,i));
	}
	bool c=false;
	sort(S.begin(),S.end());
	for(int i=0;i<n;i++){
		int j=i+1;
		if(used[S[i].second]==1)continue;
		while(S[i].first==S[j].first){
			if(last[S[i].second]==last[S[j].second]&&used[S[i].second]==0&&used[S[j].second]==0){
				v1.push_back(make_pair(S[i].second,S[j].second));
				used[S[i].second]=1; used[S[j].second]=1;
				c=true;
				break;
			}
			j++;
		}
	}
	if(!c){
		cout << 0 << endl;
		return 0;
	}
	for(int i=0;i<n;i++){
		int j=i+1;
		if(used[S[i].second]==1)continue;
		while(S[i].first==S[j].first){
			if(used[S[j].second]==0){
				v.push_back(make_pair(S[i].second,S[j].second));
				used[S[i].second]=1; used[S[j].second]=1;
				break;
			}
			j++;
		}
	}
	ll ans=min(v.size(),v1.size());
	bool a=false;
	ll copy=ans;
	if(v1.size()-v.size()>1){
		ans+=(v1.size()-v.size())/2;
		a=true;
	}
	ll b=0;
	cout << max(ans,b) << endl;
	if(max(ans,b)==0){
		return 0;
	}
	for(int i=0;i<copy;i++){
		//printf("%s %s\n",s[v[i].first] ,s[v1[i].first]);
		//printf("%s %s\n",s[v[i].second] ,s[v1[i].second]);
		cout <<s[v[i].first] <<" " <<s[v1[i].first]<< endl;
		cout << s[v[i].second] <<" " <<s[v1[i].second] << endl;
	}
	if(a){for(int i=0;i<(v1.size()-v.size())/2;i++){
		//printf("%s %s\n",s[v1[v.size()+i*2].first] ,s[v1[v.size()+i*2+1].first]);
		//printf("%s %s\n",s[v1[v.size()+i*2].second] ,s[v1[v.size()+i*2+1].second]);
		cout << s[v1[v.size()+i*2].first]<<" " <<s[v1[v.size()+i*2+1].first] << endl;
		cout << s[v1[v.size()+i*2].second] << " " <<s[v1[v.size()+i*2+1].second] << endl;
		}
	}
}


#include<iostream>
#include<algorithm>
#include<numeric>
#include<vector>
#include<set>
#include<map>
#include <string>
#define cinf(n,x) for(int i=0;i<(n);i++) cin >> x[i];
typedef long long int ll;
using namespace std;
int used[100001];
int main(){
	int n; cin >>n;
	vector<string> s(n);
	char last[100001];
	vector<pair<int,int> > v,v1;
	vector<pair<int,int> > S;
	for(int i=0;i<n;i++){
		cin >>s[i];
		int cnt=0;
		for(int j=0;j<s[i].size();j++){
			if(s[i][j]=='a'||s[i][j]=='i'||s[i][j]=='u'||s[i][j]=='e'||s[i][j]=='o'){
				cnt++;
				last[i]=s[i][j];
			}
		}
		S.push_back(make_pair(cnt,i));
	}
	sort(S.begin(),S.end());
	for(int i=0;i<n;i++){
		int j=i+1;
		if(used[S[i].second]==1)continue;
		while(S[i].first==S[j].first){
			if(last[S[i].second]==last[S[j].second]&&used[S[i].second]==0&&used[S[j].second]==0){
				v1.push_back(make_pair(S[i].second,S[j].second));
				used[S[i].second]=1; used[S[j].second]=1;
				break;
			}
			j++;
		}
	}
	for(int i=0;i<n;i++){
		int j=i+1;
		if(used[S[i].second]==1)continue;
		while(S[i].first==S[j].first){
			if(used[S[j].second]==0){
				v.push_back(make_pair(S[i].second,S[j].second));
				used[S[i].second]=1; used[S[j].second]=1;
				break;
			}
			j++;
		}
	}
	int ans=min(v.size(),v1.size());
	bool a=false;
	int copy=ans;
	if(v1.size()-v.size()>1){
		ans+=(v1.size()-v.size())/2;
		a=true;
	}
	cout << max(ans,0) << endl;
	for(int i=0;i<copy;i++){
		//printf("%s %s\n",s[v[i].first] ,s[v1[i].first]);
		//printf("%s %s\n",s[v[i].second] ,s[v1[i].second]);
		cout <<s[v[i].first] <<" " <<s[v1[i].first]<< endl;
		cout << s[v[i].second] <<" " <<s[v1[i].second] << endl;
	}
	if(a){for(int i=0;i<(v1.size()-v.size())/2;i++){
		//printf("%s %s\n",s[v1[v.size()+i*2].first] ,s[v1[v.size()+i*2+1].first]);
		//printf("%s %s\n",s[v1[v.size()+i*2].second] ,s[v1[v.size()+i*2+1].second]);
		cout << s[v1[v.size()+i*2].first]<<" " <<s[v1[v.size()+i*2+1].first] << endl;
		cout << s[v1[v.size()+i*2].second] << " " <<s[v1[v.size()+i*2+1].second] << endl;
		}
	}
}


#include<iostream>
#include<algorithm>
#include<numeric>
#include<vector>
#include<set>
#include<map>
#include <string>
#define cinf(n,x) for(int i=0;i<(n);i++) cin >> x[i];
typedef long long int ll;
using namespace std;
int used[100001];
int main(){
	int n; cin >>n;
	vector<string> s(n);
	char last[100001];
	vector<pair<ll,ll> > v,v1;
	vector<pair<ll,ll> > S;
	for(int i=0;i<n;i++){
		cin >>s[i];
		ll cnt=0;
		for(int j=0;j<s[i].size();j++){
			if(s[i][j]=='a'||s[i][j]=='i'||s[i][j]=='u'||s[i][j]=='e'||s[i][j]=='o'){
				cnt++;
				last[i]=s[i][j];
			}
		}
		S.push_back(make_pair(cnt,i));
	}
	bool c=false;
	sort(S.begin(),S.end());
	for(int i=0;i<n;i++){
		int j=i+1;
		if(used[S[i].second]==1)continue;
		while(S[i].first==S[j].first){
			if(last[S[i].second]==last[S[j].second]&&used[S[i].second]==0&&used[S[j].second]==0){
				v1.push_back(make_pair(S[i].second,S[j].second));
				used[S[i].second]=1; used[S[j].second]=1;
				c=true;
				break;
			}
			j++;
		}
	}
	if(!c){
		cout << 0 << endl;
		return 0;
	}
	bool d=false;
	for(int i=0;i<n;i++){
		int j=i+1;
		if(used[S[i].second]==1)continue;
		while(S[i].first==S[j].first){
			if(used[S[j].second]==0){
				v.push_back(make_pair(S[i].second,S[j].second));
				used[S[i].second]=1; used[S[j].second]=1;
				d=true;
				break;
			}
			j++;
		}
	}
	if(!d){
		cout << v1.size()/2 << endl;
		for(int i=0;i<v1.size()/2;i++){
			cout << s[v1[i].first] << " " << s[v1[i+1].first] << endl;
			cout << s[v1[i].second] << " " << s[v1[i+1].second] << endl;
		}
		return 0;
	}
	ll ans=min(v.size(),v1.size());
	bool a=false;
	ll copy=ans;
	if(v1.size()-v.size()>1){
		ans+=(v1.size()-v.size())/2;
		a=true;
	}
	ll b=0;
	cout << max(ans,b) << endl;
	if(max(ans,b)==0){
		return 0;
	}
	for(int i=0;i<copy;i++){
		//printf("%s %s\n",s[v[i].first] ,s[v1[i].first]);
		//printf("%s %s\n",s[v[i].second] ,s[v1[i].second]);
		cout <<s[v[i].first] <<" " <<s[v1[i].first]<< endl;
		cout << s[v[i].second] <<" " <<s[v1[i].second] << endl;
	}
	if(a){for(int i=0;i<(v1.size()-v.size())/2;i++){
		//printf("%s %s\n",s[v1[v.size()+i*2].first] ,s[v1[v.size()+i*2+1].first]);
		//printf("%s %s\n",s[v1[v.size()+i*2].second] ,s[v1[v.size()+i*2+1].second]);
		cout << s[v1[v.size()+i*2].first]<<" " <<s[v1[v.size()+i*2+1].first] << endl;
		cout << s[v1[v.size()+i*2].second] << " " <<s[v1[v.size()+i*2+1].second] << endl;
		}
	}
}


#include<iostream>
#include<algorithm>
#include<numeric>
#include<vector>
#include<set>
#include<map>
#include <string>
#define cinf(n,x) for(int i=0;i<(n);i++) cin >> x[i];
typedef long long int ll;
using namespace std;
int used[100001];
int main(){
	int n; cin >>n;
	vector<string> s(n);
	char last[100001];
	vector<pair<ll,ll> > v,v1;
	vector<pair<ll,ll> > S;
	for(int i=0;i<n;i++){
		cin >>s[i];
		ll cnt=0;
		for(int j=0;j<s[i].size();j++){
			if(s[i][j]=='a'||s[i][j]=='i'||s[i][j]=='u'||s[i][j]=='e'||s[i][j]=='o'){
				cnt++;
				last[i]=s[i][j];
			}
		}
		S.push_back(make_pair(cnt,i));
	}
	sort(S.begin(),S.end());
	for(int i=0;i<n;i++){
		int j=i+1;
		if(used[S[i].second]==1)continue;
		while(S[i].first==S[j].first){
			if(last[S[i].second]==last[S[j].second]&&used[S[i].second]==0&&used[S[j].second]==0){
				v1.push_back(make_pair(S[i].second,S[j].second));
				used[S[i].second]=1; used[S[j].second]=1;
				break;
			}
			j++;
		}
	}
	for(int i=0;i<n;i++){
		int j=i+1;
		if(used[S[i].second]==1)continue;
		while(S[i].first==S[j].first){
			if(used[S[j].second]==0){
				v.push_back(make_pair(S[i].second,S[j].second));
				used[S[i].second]=1; used[S[j].second]=1;
				break;
			}
			j++;
		}
	}
	ll ans=min(v.size(),v1.size());
	bool a=false;
	ll copy=ans;
	if(v1.size()-v.size()>1){
		ans+=(v1.size()-v.size())/2;
		a=true;
	}
	cout << max(ans,0) << endl;
	ll b=0;
	if(max(ans,b)==0){
		return 0;
	}
	for(int i=0;i<copy;i++){
		//printf("%s %s\n",s[v[i].first] ,s[v1[i].first]);
		//printf("%s %s\n",s[v[i].second] ,s[v1[i].second]);
		cout <<s[v[i].first] <<" " <<s[v1[i].first]<< endl;
		cout << s[v[i].second] <<" " <<s[v1[i].second] << endl;
	}
	if(a){for(int i=0;i<(v1.size()-v.size())/2;i++){
		//printf("%s %s\n",s[v1[v.size()+i*2].first] ,s[v1[v.size()+i*2+1].first]);
		//printf("%s %s\n",s[v1[v.size()+i*2].second] ,s[v1[v.size()+i*2+1].second]);
		cout << s[v1[v.size()+i*2].first]<<" " <<s[v1[v.size()+i*2+1].first] << endl;
		cout << s[v1[v.size()+i*2].second] << " " <<s[v1[v.size()+i*2+1].second] << endl;
		}
	}
}


#include<iostream>
#include<algorithm>
#include<numeric>
#include<vector>
#include<set>
#include<map>
#include <string>
#define cinf(n,x) for(int i=0;i<(n);i++) cin >> x[i];
typedef long long int ll;
using namespace std;
int used[100001];
int main(){
	int n; cin >>n;
	vector<string> s(n);
	char last[100001];
	vector<pair<ll,ll> > v,v1;
	vector<pair<ll,ll> > S;
	for(int i=0;i<n;i++){
		cin >>s[i];
		ll cnt=0;
		for(int j=0;j<s[i].size();j++){
			if(s[i][j]=='a'||s[i][j]=='i'||s[i][j]=='u'||s[i][j]=='e'||s[i][j]=='o'){
				cnt++;
				last[i]=s[i][j];
			}
		}
		S.push_back(make_pair(cnt,i));
	}
	bool c=false;
	sort(S.begin(),S.end());
	for(int i=0;i<n;i++){
		int j=i+1;
		if(used[S[i].second]==1)continue;
		while(S[i].first==S[j].first){
			if(last[S[i].second]==last[S[j].second]&&used[S[i].second]==0&&used[S[j].second]==0){
				v1.push_back(make_pair(S[i].second,S[j].second));
				used[S[i].second]=1; used[S[j].second]=1;
				c=true;
				break;
			}
			j++;
		}
	}
	if(!c){
		cout << 0 << endl;
		return 0;
	}
	bool d=false;
	for(int i=0;i<n;i++){
		int j=i+1;
		if(used[S[i].second]==1)continue;
		while(S[i].first==S[j].first){
			if(used[S[j].second]==0){
				v.push_back(make_pair(S[i].second,S[j].second));
				used[S[i].second]=1; used[S[j].second]=1;
				d=true;
				break;
			}
			j++;
		}
	}
	if(!d){
		cout << v1.size()/2 << endl;
		for(int i=0;i<v1.size();i++){
			cout << s[v1[i].first] << " " << s[v1[i+1].first] << endl;
			cout << s[v1[i].second] << " " << s[v1[i+1].second] << endl;
		}
		return 0;
	}
	ll ans=min(v.size(),v1.size());
	bool a=false;
	ll copy=ans;
	if(v1.size()-v.size()>1){
		ans+=(v1.size()-v.size())/2;
		a=true;
	}
	ll b=0;
	cout << max(ans,b) << endl;
	if(max(ans,b)==0){
		return 0;
	}
	for(int i=0;i<copy;i++){
		//printf("%s %s\n",s[v[i].first] ,s[v1[i].first]);
		//printf("%s %s\n",s[v[i].second] ,s[v1[i].second]);
		cout <<s[v[i].first] <<" " <<s[v1[i].first]<< endl;
		cout << s[v[i].second] <<" " <<s[v1[i].second] << endl;
	}
	if(a){for(int i=0;i<(v1.size()-v.size())/2;i++){
		//printf("%s %s\n",s[v1[v.size()+i*2].first] ,s[v1[v.size()+i*2+1].first]);
		//printf("%s %s\n",s[v1[v.size()+i*2].second] ,s[v1[v.size()+i*2+1].second]);
		cout << s[v1[v.size()+i*2].first]<<" " <<s[v1[v.size()+i*2+1].first] << endl;
		cout << s[v1[v.size()+i*2].second] << " " <<s[v1[v.size()+i*2+1].second] << endl;
		}
	}
}


#include<iostream>
#include<algorithm>
#include<numeric>
#include<vector>
#include<set>
#include<map>
#include <string>
#define cinf(n,x) for(int i=0;i<(n);i++) cin >> x[i];
typedef long long int ll;
using namespace std;
int used[100001];
int main(){
	int n; cin >>n;
	vector<string> s(n);
	char last[100001];
	vector<pair<ll,ll> > v,v1;
	vector<pair<ll,ll> > S;
	for(int i=0;i<n;i++){
		cin >>s[i];
		ll cnt=0;
		for(int j=0;j<s[i].size();j++){
			if(s[i][j]=='a'||s[i][j]=='i'||s[i][j]=='u'||s[i][j]=='e'||s[i][j]=='o'){
				cnt++;
				last[i]=s[i][j];
			}
		}
		S.push_back(make_pair(cnt,i));
	}
	sort(S.begin(),S.end());
	for(int i=0;i<n;i++){
		int j=i+1;
		if(used[S[i].second]==1)continue;
		while(S[i].first==S[j].first){
			if(last[S[i].second]==last[S[j].second]&&used[S[i].second]==0&&used[S[j].second]==0){
				v1.push_back(make_pair(S[i].second,S[j].second));
				used[S[i].second]=1; used[S[j].second]=1;
				break;
			}
			j++;
		}
	}
	for(int i=0;i<n;i++){
		int j=i+1;
		if(used[S[i].second]==1)continue;
		while(S[i].first==S[j].first){
			if(used[S[j].second]==0){
				v.push_back(make_pair(S[i].second,S[j].second));
				used[S[i].second]=1; used[S[j].second]=1;
				break;
			}
			j++;
		}
	}
	ll ans=min(v.size(),v1.size());
	bool a=false;
	ll copy=ans;
	if(v1.size()-v.size()>1){
		ans+=(v1.size()-v.size())/2;
		a=true;
	}
	cout << max(ans,0) << endl;
	if(max(ans,0)==0){
		return 0;
	}
	for(int i=0;i<copy;i++){
		//printf("%s %s\n",s[v[i].first] ,s[v1[i].first]);
		//printf("%s %s\n",s[v[i].second] ,s[v1[i].second]);
		cout <<s[v[i].first] <<" " <<s[v1[i].first]<< endl;
		cout << s[v[i].second] <<" " <<s[v1[i].second] << endl;
	}
	if(a){for(int i=0;i<(v1.size()-v.size())/2;i++){
		//printf("%s %s\n",s[v1[v.size()+i*2].first] ,s[v1[v.size()+i*2+1].first]);
		//printf("%s %s\n",s[v1[v.size()+i*2].second] ,s[v1[v.size()+i*2+1].second]);
		cout << s[v1[v.size()+i*2].first]<<" " <<s[v1[v.size()+i*2+1].first] << endl;
		cout << s[v1[v.size()+i*2].second] << " " <<s[v1[v.size()+i*2+1].second] << endl;
		}
	}
}


#include"bits/stdc++.h"
using namespace std;
typedef long long int ll;
const int N = 1e5 + 1;
map < pair < ll , char >  , vector < string > >mp;
map < ll , vector <string > > mpp;
vector < string > v , vv;
ll n,j,x,y;
string s[N];
char vo[5] = {'a','e','i','o','u'};
void lv(string ss)
{
    ll cnt = 0 ;
    char ch = {' '};
    for(int k = 0; k < ss.size(); k++) {
        for(int x = 0; x < 5; x++) {
            if(ss[k] == vo[x]) cnt++ , ch = ss[k];
        }
    }
    mp[{ cnt , ch }].push_back(ss);
}

int main()
{
     ios_base::sync_with_stdio(0);cin.tie(NULL);cout.tie(NULL);
        cin >> n;
        for(j = 0; j < n; j++) {
                cin >> s[j];
                lv(s[j]);
        }
        /*for(auto i : mp){
            cout << i.first.first << " " << i.first.second << " " << i.second.size() << "\n";
        }*/

        for(auto i : mp) {
            while(i.second.size() >= 2) {
               v.push_back(i.second[i.second.size() - 1]);
               i.second.pop_back();
               v.push_back(i.second[i.second.size() - 1]);
               i.second.pop_back();
               }
                if(i.second.size() > 0) {
                    mpp[i.first.first].push_back(i.second[0]);
                    i.second.pop_back();
                }
        }
        for(auto i : mpp) {
          while(i.second.size() >= 2) {
               vv.push_back(i.second[i.second.size() - 1]);
               i.second.pop_back();
               vv.push_back(i.second[i.second.size() - 1]);
               i.second.pop_back();
           }
        }
        /*for(int i = 0; i < v.size(); i++) cout << v[i] << " ";
        cout << "\n";
        for(int i = 0; i < vv.size(); i++) cout << vv[i] << " ";*/
         x = 0;
         if(v.size() > vv.size()) x = ( v.size() - vv.size() );
         y = min(v.size() , vv.size()) ;
         cout << y/2 + x/4 << "\n";
        for(j = 0; j < y; j++)
          cout << vv[j] <<" "<< v[j]<<"\n";
        if(x != 0) {
        for(j = y ; j + 2 < v.size(); j++)
            cout << v[j] << " " << v[j + 2] << "\n";
        }
    return 0;
}


#include"bits/stdc++.h"
using namespace std;
typedef long long int ll;
const int N = 1e5 + 1;
map < pair < ll , char >  , vector < string > >mp;
map < ll , vector <string > > mpp;
vector < string > v , vv,ans1,ans2;
ll n,j,x,y;
string s[N];
char vo[5] = {'a','e','i','o','u'};
void lv(string ss)
{
    ll cnt = 0 ;
    char ch = {' '};
    for(int k = 0; k < ss.size(); k++) {
        for(int x = 0; x < 5; x++) {
            if(ss[k] == vo[x]) cnt++ , ch = ss[k];
        }
    }
    mp[{ cnt , ch }].push_back(ss);
}

int main()
{
     ios_base::sync_with_stdio(0);cin.tie(NULL);cout.tie(NULL);
        cin >> n;
        for(j = 0; j < n; j++) {
                cin >> s[j];
                lv(s[j]);
        }
        /*for(auto i : mp){
            cout << i.first.first << " " << i.first.second << " " << i.second.size() << "\n";
        }*/

        for(auto i : mp) {
            while(i.second.size() >= 2) {
               v.push_back(i.second[i.second.size() - 1]);
               i.second.pop_back();
               v.push_back(i.second[i.second.size() - 1]);
               i.second.pop_back();
               }
                if(i.second.size() > 0) {
                    mpp[i.first.first].push_back(i.second[0]);
                    i.second.pop_back();
                }
        }
        for(auto i : mpp) {
          while(i.second.size() >= 2) {
               vv.push_back(i.second[i.second.size() - 1]);
               i.second.pop_back();
               vv.push_back(i.second[i.second.size() - 1]);
               i.second.pop_back();
           }
        }
        /*for(int i = 0; i < v.size(); i++) cout << v[i] << " ";
        cout << "\n";
        for(int i = 0; i < vv.size(); i++) cout << vv[i] << " ";
        cout <<"-------\n";*/
        while(!v.empty() && !vv.empty()) {
         ans1.push_back(vv[vv.size() - 1]);
         vv.pop_back();
         ans2.push_back(v[v.size() - 1]);
         v.pop_back();
        }
        if(v.size() >= 2) {
        ll lf = 0 , rt = v.size() - 1;
        while( lf < rt) {
            ans1.push_back(v[lf]);
            lf++;
            ans2.push_back(v[rt]);
            rt--;
        }
        }
        cout << ans1.size() / 2 << "\n";
        for(j = 0; j  < ans1.size(); j++)
            cout << ans1[j]<< " " << ans2[j] << "\n";
    return 0;
}


from collections import defaultdict

def solve(n, m, an, ms):
    if n == m:
        return sum(an)

    return -1

if __name__ == '__main__':
    n, m = tuple(map(int, input().split()))
    an = list(map(int, input().split()))
    ms = []
    for _ in range(m):
        ms.append(list(map(int, input().split())))
    print(solve(n, m, an, ms))


n, m = map(int, input().split())

prices = list(map(int, input().split()))

matches = [[]] * m

matches = [[0 for _ in range(n)] for _ in range(n)]

for _ in range(m):
    a, b = map(lambda x: int(x) - 1, input().split())

    matches[a][b] = 1
    matches[b][a] = 1

MAX_MIN_COST = 3 * 10**6
min_cost = MAX_MIN_COST + 1

for i in range(n):
    for j in range(i+1, n):
        for k in range(j+1, n):
            if matches[i][j] == 1 and \
               matches[i][k] == 1 and \
               matches[j][k] == 1:
                   min_cost = min([min_cost, prices[i] + \
                                             prices[j] + \
                                             prices[k]])

if min_cost == MAX_MIN_COST + 1:
    print("-1")
else:
    print(min_cost)


n,m=gets.split.map(&:to_i)
a=gets.split.map(&:to_i)
g=Array.new(n){Array.new(n,0)}
m.times{
        p,q=gets.split.map(&:to_i)
        g[p-1][q-1]=g[q-1][p-1]=1
}
ans=9999999999
0.upto(n-1){|i|
        (i+1).upto(n-1){|j|
                if g[i][j]==0 then
                        next
                end
                (j+1).upto(n-1){|k|
                        if g[i][k]==0 || g[j][k]==0 then
                                next
                        end
                        ans=[ans,a[i]+a[j]+a[k]].min
                }
        }
}
puts (ans>=999999999)?-1:ans


n, m = gets.split("\s").map(&:to_i)
cost = gets.split("\s").map(&:to_i)
arr = Array.new(111) { Array.new }
m.times do
	u, v = gets.split("\s").map(&:to_i)
	arr[u] << v
	arr[v] << u
end

res = 1e10
for i in 1..n
	for j in (i+1)..n
		for k in (j+1)..n
			res = [res, cost[i-1]+cost[j-1]+cost[k-1]].min if arr[i].include?(j) && arr[j].include?(k) && arr[k].include?(i)
		end
	end
end

res = -1 if res == 1e10
puts res


sn, sm = gets.chop.split(/\s+/)

count = sn.to_i
countRelation = sm.to_i

costs = Array.new(0)
scosts = gets.chop.split(/\s+/)
(0..count-1).each { |i|
  costs[i] = scosts[i].to_i
}

relations = Array.new()
(0..count-1).each { |i|
  relations[i] = Array.new()
  (0..count-1).each { |j|
    relations[i][j] = false
  }
}

(0..countRelation-1).each { |i|
  su, sv = gets.chop.split(/\s+/)
  u = su.to_i - 1;
  v = sv.to_i - 1;
  relations[u][v] = true
  relations[v][u] = true
}

solves = Array.new(0)

#(0..count-2).each { |row|
##  (row..count-2).each { |col|
#    if (relations[row][col] == true and relations[row][col+1] == true and relations[row+1][col+1] == true)
#      solves[solves.length] =  costs[row] + costs[col] + costs[col+1]
#    end
#  }
#}

(0..count-1).each { |i|
  (0..count-1).each { |j|
    (0..count-1).each { |k|
      if (relations[i][j] == true and relations[j][k] == true and relations[i][k] == true)
        solves[solves.length] =  costs[i] + costs[j] + costs[k]
      end
    }
  }
}

if (solves.length > 0)
  puts solves.min
else
  puts "-1"
end


sn, sm = gets.chop.split(/\s+/)

count = sn.to_i
countRelation = sm.to_i

costs = Array.new(0)
scosts = gets.chop.split(/\s+/)
(0..count-1).each { |i|
  costs[i] = scosts[i].to_i
}

relations = Array.new()
(0..count-1).each { |i|
  relations[i] = Array.new()
  (0..count-1).each { |j|
    relations[i][j] = false
  }
}

(0..countRelation-1).each { |i|
  su, sv = gets.chop.split(/\s+/)
  u = su.to_i - 1;
  v = sv.to_i - 1;
  relations[u][v] = true
  relations[v][u] = true
}

solves = Array.new(0)

(0..count-2).each { |row|
  (row..count-2).each { |col|
    if (relations[row][col] == true and relations[row][col+1] == true and relations[row+1][col+1] == true)
      solves[solves.length] =  costs[row] + costs[col] + costs[col+1]
    end
  }
}

if (solves.length > 0)
  puts solves.min
else
  puts "-1"
end