// Author: Wojciech 'Ardavel' Szałapski
#define DEBUG 0

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

typedef unsigned long long int uLint;
typedef long long int Lint;
typedef short int sint;
typedef long double ld;
typedef pair< int, int > PII;
typedef pair< PII, int > PPI;
typedef vector< int > VI;
typedef vector< ld > VD;
typedef vector< string > VS;
typedef vector< PII > VPII;
typedef vector< VI > VVI;
typedef queue< int > QI;
typedef queue< PII > QPII;

const int PRIME = 1000 * 1000 * 1000 + 7;
const int MULTIPLIER = 523;
const int INFI = (1 << 30) - 1;
const ld INF = 2 * 1e9 + 1;
const ld EPS = 1e-9;
const ld PI = 3.141592653589793238462643383279502884L;
const int DIM = 2;

#define X coord[0]
#define Y coord[1]

#define VAR(v, n) __typeof(n) v = (n)
#define REP(a, b) for(int a = 0;a < (b);++a)
#define FOR(a, b, c) for(int a = (b);a <= (c);++a)
#define FORD(a, b, c) for(int a = (b);a >= (c);--a)
#define FOREACH(it, s) for(VAR(it, (s).begin());it != (s).end();++it)
#define SIZE(x) (int)(x).size()
#define PB push_back
#define PF push_front
#define MP make_pair

const int MAX_N = 123456;

int n, m;

VI graph[MAX_N];
bool attacked[MAX_N];
bool cutoff[MAX_N];
int s[MAX_N];
int dist[MAX_N];
int p[MAX_N];

VI humans;
int firstRoot;

bool cuttingDfs(int v, int parent) {
    bool haveHumans = attacked[v];
    REP(i, SIZE(graph[v])) {
        int x = graph[v][i];
        if (x != parent) {
            if (!cuttingDfs(x, v)) {
                cutoff[x] = true;
            } else {
                haveHumans = true;
            }
        }
    }

    return haveHumans;
}

int sizingDfs(int v, int parent) {
    s[v] = 1;
    REP(i, SIZE(graph[v])) {
        int x = graph[v][i];
        if (x != parent) {
            if (!cutoff[x]) {
                s[v] += sizingDfs(x, v);
            }
        }
    }

    return s[v];
}

void distDfs(int v, int parent) {
    p[v] = parent;

    if (parent == -1) {
        dist[v] = 0;
    } else {
        dist[v] = dist[parent] + 1;
    }

    REP(i, SIZE(graph[v])) {
        int x = graph[v][i];
        if (x != parent) {
            if (!cutoff[x]) {
                distDfs(x, v);
            }
        }
    }
}

int main() {
    ios_base::sync_with_stdio(0);

    cin >> n >> m;

    REP(i, n - 1) {
        int a, b;
        cin >> a >> b;
        --a;
        --b;

        graph[a].PB(b);
        graph[b].PB(a);
    }

    REP(i, m) {
        int x;
        cin >> x;
        --x;
        humans.PB(x);

        attacked[x] = true;
    }

    firstRoot = humans[0];

    cuttingDfs(firstRoot, -1);

    sizingDfs(firstRoot, -1);

    distDfs(firstRoot, -1);

    int mostDistant = firstRoot;
    REP(i, n) {
        if ((dist[i] > dist[mostDistant]) || (dist[i] == dist[mostDistant] && i < mostDistant)) {
            mostDistant = i;
        }
    }

    distDfs(mostDistant, -1);
    int maxDist = 0;
    REP(i, n) {
        if (dist[i] > maxDist || (dist[i] == maxDist && i < mostDistant)) {
            mostDistant = i;
            maxDist = dist[i];
        }
    }

    int secondSide = mostDistant;
    int secondDistance = dist[secondSide];

    int center1 = secondSide;
    for (int i = 0; i < secondDistance / 2; ++i) {
        center1 = p[center1];
    }

    int center2 = p[center1];

    distDfs(center1, -1);
    int farthest = 0;
    REP(i, n) {
        if (dist[i] > dist[farthest] || (dist[i] == dist[farthest] && i < farthest)) {
            farthest = i;
        }
    }

    int farthest2 = 0;
    if (center2 != -1) {
        distDfs(center2, -1);
        REP(i, n) {
            if (dist[i] > dist[farthest2] || (dist[i] == dist[farthest2] && i < farthest2)) {
                farthest2 = i;
            }
        }
    }

    if (dist[farthest2] > dist[farthest] || (dist[farthest2] == dist[farthest] && farthest2 < farthest)) {
        farthest = farthest2;
    }

    distDfs(farthest, -1);
    int best = farthest;
    REP(i, n) {
        if (dist[i] > dist[best] || (dist[i] == dist[best] && i < best)) {
            best = i;
        }
    }

    if (humans.size() > 1) {
        cout << min(best, farthest) + 1 << "\n";
    } else {
        cout << humans[0] + 1 << "\n";
    }
    cout << 2 * s[firstRoot] - 2 - maxDist;

    return 0;
}


#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
struct Node{
	int s,t,next;
}e[250010];
int head[130010],cnt;
void addedge(int s,int t)
{
	e[cnt].s=s;e[cnt].t=t;e[cnt].next=head[s];head[s]=cnt++;
	e[cnt].s=t;e[cnt].t=s;e[cnt].next=head[t];head[t]=cnt++;
}
bool pd[130010],lable[130010];
int dis[130010];
int n,m,u,v,pos,ans,tmp;
void dfs(int node,int lastfa)
{
	pd[node]=lable[node];
	for (int i=head[node];i!=-1;i=e[i].next)
		if (e[i].t!=lastfa)
		{
			dfs(e[i].t,node);
			if (pd[e[i].t])
				ans+=2;
			pd[node]|=pd[e[i].t];
		}
}
void dfs2(int node,int lastfa,int sum)
{
	dis[node]=sum;
	for (int i=head[node];i!=-1;i=e[i].next)
		if (e[i].t!=lastfa)
			dfs2(e[i].t,node,sum+1);
}
int main()
{
	scanf("%d%d",&n,&m);
	memset(head,0xff,sizeof(head));
	cnt=0;
	for (int i=1;i<n;i++)
	{
		scanf("%d%d",&u,&v);
		addedge(u,v);
	}
	for (int i=1;i<=m;i++)
	{
		scanf("%d",&u);
		lable[u]=1;
	}
	dfs(u,u);
	dis[0]=-1;
	dfs2(u,u,0);
	for (int i=1;i<=n;i++)
		if (lable[i]&&dis[i]>dis[pos])
			pos=i;
	tmp=pos;
	dfs2(pos,pos,0);
	pos=0;
	for (int i=1;i<=n;i++)
		if (lable[i]&&dis[i]>dis[pos])
			pos=i;
	ans=ans-dis[pos];
	pos=min(pos,tmp);
	printf("%d\n%d\n",pos,ans);
	return 0;
}


#include<cstdio>
#include<cstring>
using namespace std;
struct Node{
	int s,t,next;
}e[250010];
int head[130010],cnt;
void addedge(int s,int t)
{
	e[cnt].s=s;e[cnt].t=t;e[cnt].next=head[s];head[s]=cnt++;
	e[cnt].s=t;e[cnt].t=s;e[cnt].next=head[t];head[t]=cnt++;
}
bool pd[130010],lable[130010];
int dis[130010];
int n,m,u,v,pos,ans;
void dfs(int node,int lastfa)
{
	pd[node]=lable[node];
	for (int i=head[node];i!=-1;i=e[i].next)
		if (e[i].t!=lastfa)
		{
			dfs(e[i].t,node);
			if (pd[e[i].t])
				ans+=2;
			pd[node]|=pd[e[i].t];
		}
}
void dfs2(int node,int lastfa,int sum)
{
	dis[node]=sum;
	for (int i=head[node];i!=-1;i=e[i].next)
		if (e[i].t!=lastfa)
			dfs2(e[i].t,node,sum+1);
}
int main()
{
	scanf("%d%d",&n,&m);
	memset(head,0xff,sizeof(head));
	cnt=0;
	for (int i=1;i<n;i++)
	{
		scanf("%d%d",&u,&v);
		addedge(u,v);
	}
	for (int i=1;i<=m;i++)
	{
		scanf("%d",&u);
		lable[u]=1;
	}
	dfs(u,u);
	dfs2(u,u,0);
	pos=1;
	for (int i=1;i<=n;i++)
		if (lable[i]&&dis[i]>dis[pos])
			pos=i;
	printf("%d\n",pos);
	dfs2(pos,pos,0);
	for (int i=1;i<=n;i++)
		if (lable[i]&&dis[i]>dis[pos])
			pos=i;
	printf("%d\n",ans-dis[pos]);
	return 0;
}


#include<cstdio>
#include<cstring>
using namespace std;
struct Node{
	int s,t,next;
}e[250010];
int head[130010],cnt;
void addedge(int s,int t)
{
	e[cnt].s=s;e[cnt].t=t;e[cnt].next=head[s];head[s]=cnt++;
	e[cnt].s=t;e[cnt].t=s;e[cnt].next=head[t];head[t]=cnt++;
}
bool pd[130010],lable[130010];
int dis[130010];
int n,m,u,v,pos,ans;
void dfs(int node,int lastfa)
{
	pd[node]=lable[node];
	for (int i=head[node];i!=-1;i=e[i].next)
		if (e[i].t!=lastfa)
		{
			dfs(e[i].t,node);
			if (pd[e[i].t])
				ans+=2;
			pd[node]|=pd[e[i].t];
		}
}
void dfs2(int node,int lastfa,int sum)
{
	dis[node]=sum;
	for (int i=head[node];i!=-1;i=e[i].next)
		if (e[i].t!=lastfa)
			dfs2(e[i].t,node,sum+1);
}
int main()
{
	scanf("%d%d",&n,&m);
	memset(head,0xff,sizeof(head));
	cnt=0;
	for (int i=1;i<n;i++)
	{
		scanf("%d%d",&u,&v);
		addedge(u,v);
	}
	for (int i=1;i<=m;i++)
	{
		scanf("%d",&u);
		lable[u]=1;
	}
	dfs(u,u);
	dfs2(u,u,0);
	pos=u;
	for (int i=n;i>=1;i--)
		if (lable[i]&&dis[i]>=dis[pos])
			pos=i;
	printf("%d\n",pos);
	dfs2(pos,pos,0);
	for (int i=1;i<=n;i++)
		if (lable[i]&&dis[i]>dis[pos])
			pos=i;
	printf("%d\n",ans-dis[pos]);
	return 0;
}


#include<cstdio>
#include<cstring>
using namespace std;
struct Node{
	int s,t,next;
}e[250010];
int head[130010],cnt;
void addedge(int s,int t)
{
	e[cnt].s=s;e[cnt].t=t;e[cnt].next=head[s];head[s]=cnt++;
	e[cnt].s=t;e[cnt].t=s;e[cnt].next=head[t];head[t]=cnt++;
}
bool pd[130010],lable[130010];
int dis[130010];
int n,m,u,v,pos,ans;
void dfs(int node,int lastfa)
{
	pd[node]=lable[node];
	for (int i=head[node];i!=-1;i=e[i].next)
		if (e[i].t!=lastfa)
		{
			dfs(e[i].t,node);
			if (pd[e[i].t])
				ans+=2;
			pd[node]|=pd[e[i].t];
		}
}
void dfs2(int node,int lastfa,int sum)
{
	dis[node]=sum;
	for (int i=head[node];i!=-1;i=e[i].next)
		if (e[i].t!=lastfa)
			dfs2(e[i].t,node,sum+1);
}
int main()
{
	scanf("%d%d",&n,&m);
	memset(head,0xff,sizeof(head));
	cnt=0;
	for (int i=1;i<n;i++)
	{
		scanf("%d%d",&u,&v);
		addedge(u,v);
	}
	for (int i=1;i<=m;i++)
	{
		scanf("%d",&u);
		lable[u]=1;
	}
	dfs(u,u);
	dfs2(u,u,0);
	for (int i=1;i<=n;i++)
		if (lable[i]&&dis[i]>dis[pos])
			pos=i;
	printf("%d\n",pos);
	dfs2(pos,pos,0);
	for (int i=1;i<=n;i++)
		if (lable[i]&&dis[i]>dis[pos])
			pos=i;
	printf("%d\n",ans-dis[pos]);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <ii> vii;
typedef vector <vii> vvii;
#define endl '\n'
#define PB push_back
#define MP make_pair
#define OO (2000000000)         // ToDo
#define EPS (1e-9)              // ToDo
#define MOD (1000000007)        // ToDo
#define all(v) ((v).begin()),((v).end())
#define DEBUG(x) cout<< #x <<" = "<<"\""<< (x) <<"\""<<endl
#define FASTIO ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
void read_file(bool outToFile = true){
#ifdef LOCAL_TEST
    freopen("in.in", "rt", stdin);
    if(outToFile)
    freopen("out.out", "wt", stdout);
#endif
}
//
int n, m;
vvi G;
const int MAXN = 200000+9;
bool is[MAXN];
//
int dp1[MAXN];
void DFS1(int u=0, int p=-1){

    dp1[u] = 0;

    int sz = G[u].size();
    for(int i=0; i<sz; i++)
    {
        int v = G[u][i];
        if(v == p) continue;

        DFS1(v, u);
        if(dp1[v] == 0 && !is[v]) continue;

        dp1[u] += dp1[v] + 2;
    }

}
//
int dp2[MAXN];
void DFS2(int u=0, int p=-1, int up=0){

    dp2[u] = dp1[u];
    if(p == -1);
    else
    {
        if(up == 0 && !is[p]);
        else dp2[u] += up + 2;
    }

    int sz = G[u].size();
    for(int i=0; i<sz; i++)
    {
        int v = G[u][i];
        if(v == p) continue;

        int cost = dp2[u];
        if(dp1[v] == 0 && !is[v]);
        else cost -= 2 + dp1[v];

        DFS2(v, u, cost);
    }

}
//
int dp3[MAXN];
void DFS3(int u=0, int p=-1){

    dp3[u] = is[u]? 0 : -OO;

    int sz = G[u].size();
    for(int i=0; i<sz; i++)
    {
        int v = G[u][i];
        if(v == p) continue;

        DFS3(v, u);
        if(dp1[v] == 0 && !is[v])
        {
            assert(dp3[v] == -OO);
            continue;
        }

        dp3[u] = max(dp3[u], 1 + dp3[v]);
    }

}
//
int dp4[MAXN];
void DFS4(int u=0, int p=-1, int up=-OO){

    dp4[u] = max(dp3[u], up + 1);

    int sz = G[u].size();
    int mxr[sz];
    for(int i=sz-1; i>=0; i--)
    {
        int v = G[u][i];
        if(v == p)
        {
            mxr[i] = -OO;
        }
        else
            mxr[i] = dp3[v];

        if(i+1 <= sz-1)
            mxr[i] = max(mxr[i], mxr[i+1]);
    }

    int mx = -OO;
    for(int i=0; i<sz; i++)
    {
        int v = G[u][i];
        if(v == p) continue;

        int nw = mx+1;
        if(i+1 <= sz-1)
            nw = max(nw, mxr[i+1]+1);

        nw = max(nw, up+1);

        if(is[u]) nw = max(nw, 0);

        DFS4(v, u, nw);
        mx = max(mx, dp3[v]);
    }
}
//
int main()
{
    read_file();
    while(scanf("%d%d", &n, &m) != -1)
    {
        memset(is, 0, sizeof is);
        G.assign(n, vi());
        for(int i=0; i<n-1; i++)
        {
            int u, v;
            scanf("%d%d", &u, &v);
            u--, v--;
            G[u].PB(v);
            G[v].PB(u);
        }
        for(int i=0; i<m; i++)
        {
            int x;
            scanf("%d", &x);
            x--;
            is[x] = 1;
        }

        DFS1();
        DFS2();
        DFS3();
        DFS4();

        int ans = -1, ansl = OO;
        for(int i=0; i<n; i++)
        {
            int nw = dp2[i] - dp4[i];

            assert(nw >= 0);

            if(nw < ansl)
            {
                ans = i;
                ansl = nw;
            }
        }

        assert(ans != -1);
        assert(is[ans]);

        for(int i=0; i<n; i++)
        {
            if(!is[i]) continue;
            assert(dp2[i] == dp2[ans]);
        }

        printf("%d\n%d\n\n", ans+1, ansl);
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <ii> vii;
typedef vector <vii> vvii;
#define endl '\n'
#define PB push_back
#define MP make_pair
#define OO (2000000000)         // ToDo
#define EPS (1e-9)              // ToDo
#define MOD (1000000007)        // ToDo
#define all(v) ((v).begin()),((v).end())
#define DEBUG(x) cout<< #x <<" = "<<"\""<< (x) <<"\""<<endl
#define FASTIO ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
void read_file(bool outToFile = true){
#ifdef LOCAL_TEST
    freopen("in.in", "rt", stdin);
    if(outToFile)
    freopen("out.out", "wt", stdout);
#endif
}
//
int n, m;
vvi G;
const int MAXN = 200000+9;
bool is[MAXN];
int sub[MAXN];
int root;
int yet;
int dp1[MAXN], dp2[MAXN];
//
void DFS0(int u=0, int p=-1){

    sub[u] = is[u];
    int cnt = 0;

    int sz = G[u].size();
    for(int i=0; i<sz; i++)
    {
        int v = G[u][i];
        if(v == p) continue;

        DFS0(v, u);
        sub[u] += sub[v];
        if(sub[v]) cnt++;
    }

    int val = m - sub[u];
    if(val) cnt++;

    if(yet && cnt <= 1 && is[u])
    {
        root = min(root, u);
    }
}
void DFS(int u=0, int p=-1){

    dp1[u] = 0;

    int sz = G[u].size();
    for(int i=0; i<sz; i++)
    {
        int v = G[u][i];
        if(v == p) continue;

        DFS(v, u);

        if(sub[v])
            dp1[u] += 2 + dp1[v];
    }

    dp2[u] = OO;
    for(int i=0; i<sz; i++)
    {
        int v = G[u][i];
        if(v == p) continue;

        if(sub[v])
        {
            int nw = dp1[u] - 2 - dp1[v];
            nw += 1 + dp2[v];
            dp2[u] = min(dp2[u], nw);
        }
    }

    if(dp2[u] == OO) dp2[u] = 0;
}
//
int main()
{
    read_file();
    while(scanf("%d%d", &n, &m) != -1)
    {
        memset(is, 0, sizeof is);
        G.assign(n, vi());
        for(int i=0; i<n-1; i++)
        {
            int u, v;
            scanf("%d%d", &u, &v);
            u--, v--;
            G[u].PB(v);
            G[v].PB(u);
        }
        for(int i=0; i<m; i++)
        {
            int x;
            scanf("%d", &x);
            x--;
            is[x] = 1;
        }

        root = OO;
        yet = 1;
        DFS0();
        yet = 0;
        assert(root != OO);
        DFS0(root);

        DFS(root);

        int ans = dp2[root];
        printf("%d\n%d\n\n", root+1, ans);
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <ii> vii;
typedef vector <vii> vvii;
#define endl '\n'
#define PB push_back
#define MP make_pair
#define OO (1000000000)         // ToDo
#define EPS (1e-9)              // ToDo
#define MOD (1000000007)        // ToDo
#define all(v) ((v).begin()),((v).end())
#define DEBUG(x) cout<< #x <<" = "<<"\""<< (x) <<"\""<<endl
#define FASTIO ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
void read_file(bool outToFile = true){
#ifdef LOCAL_TEST
    freopen("in.in", "rt", stdin);
    if(outToFile)
    freopen("out.out", "wt", stdout);
#endif
}
//
int n, m;
const int MAXN = 123456+9;
int is[MAXN];
int has[MAXN];
vvi G;
int root;
//
int DFS(int u=root, int p=-1){

    has[u] = is[u];
    int ret = 0;
    for(int i=0, sz=G[u].size(); i<sz; i++)
    {
        int v = G[u][i];
        if(v == p) continue;
        int nw = DFS(v, u);
        nw += 2;

        if(has[v])
            ret += nw, has[u] = 1;
    }

    return ret;
}
ii DFS2(int u=root, int p=-1){

    ii ret = MP(0, u);
    has[u] = is[u];
    for(int i=0,sz=G[u].size(); i<sz; i++)
    {
        int v = G[u][i];
        if(v == p) continue;

        ii nw = DFS2(v, u);
        if(!has[v]) continue;
        nw.first++;

        has[u] = 1;
        if(ret.first < nw.first)
            ret = nw;
        else if(ret.first == nw.first)
            ret.second = min(ret.second, nw.second);
    }

    return ret;
}
//
int main()
{
    read_file();
    while(scanf("%d%d", &n, &m) != -1)
    {
        G.assign(n, vi());
        for(int i=0; i<n-1; i++)
        {
            int u, v;
            scanf("%d%d", &u, &v);
            u--, v--;
            G[u].PB(v);
            G[v].PB(u);
        }

        memset(is, 0, sizeof is);
        for(int i=0; i<m; i++)
        {
            int x;
            scanf("%d", &x);
            x--;
            is[x] = 1;
            root = x;
        }

        int ans = DFS();
        //DEBUG(ans);

        int a = DFS2(root).second;
        //DEBUG(a);
        ii tmp = DFS2(a);
        int b = tmp.second;
        ans -= tmp.first;
        int ans2 = min(a, b);

        printf("%d\n%d\n", ans2+1, ans);
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <ii> vii;
typedef vector <vii> vvii;
#define endl '\n'
#define PB push_back
#define MP make_pair
#define OO (1000000000)         // ToDo
#define EPS (1e-9)              // ToDo
#define MOD (1000000007)        // ToDo
#define all(v) ((v).begin()),((v).end())
#define DEBUG(x) cout<< #x <<" = "<<"\""<< (x) <<"\""<<endl
#define FASTIO ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
void read_file(bool outToFile = true){
#ifdef LOCAL_TEST
    freopen("in.in", "rt", stdin);
    if(outToFile)
    freopen("out.out", "wt", stdout);
#endif
}
//
int n, m;
const int MAXN = 123456+9;
int is[MAXN];
int has[MAXN], dp[MAXN];
vvi G;
int root;
//
void DFS(int u=root, int p=-1){

    has[u] = is[u];
    dp[u] = 0;
    for(int i=0, sz=G[u].size(); i<sz; i++)
    {
        int v = G[u][i];
        if(v == p) continue;
        DFS(v, u);

        if(has[v])
            dp[u] += 2 + dp[v], has[u] = 1;
    }
}
ii DFS2(int u=root, int p=-1){

    ii ret = MP(0, u);
    has[u] = is[u];
    for(int i=0,sz=G[u].size(); i<sz; i++)
    {
        int v = G[u][i];
        if(v == p) continue;

        ii nw = DFS2(v, u);
        if(!has[v]) continue;
        nw.first++;

        has[u] = 1;
        if(ret.first < nw.first)
            ret = nw;
        else if(ret.first == nw.first)
            ret.second = min(ret.second, nw.second);
    }

    return ret;
}
//
int main()
{
    read_file();
    while(scanf("%d%d", &n, &m) != -1)
    {
        G.assign(n, vi());
        for(int i=0; i<n-1; i++)
        {
            int u, v;
            scanf("%d%d", &u, &v);
            u--, v--;
            G[u].PB(v);
            G[v].PB(u);
        }

        memset(is, 0, sizeof is);
        for(int i=0; i<m; i++)
        {
            int x;
            scanf("%d", &x);
            x--;
            is[x] = 1;
            root = x;
        }

        DFS();

        int ans = dp[root];
        //DEBUG(ans);

        int a = DFS2(root).second;
        //DEBUG(a);
        ii tmp = DFS2(a);
        int b = tmp.second;
        ans -= tmp.first;
        int ans2 = min(a, b);

        printf("%d\n%d\n", ans2+1, ans);
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <ii> vii;
typedef vector <vii> vvii;
#define endl '\n'
#define PB push_back
#define MP make_pair
#define OO (1000000000)         // ToDo
#define EPS (1e-9)              // ToDo
#define MOD (1000000007)        // ToDo
#define all(v) ((v).begin()),((v).end())
#define DEBUG(x) cout<< #x <<" = "<<"\""<< (x) <<"\""<<endl
#define FASTIO ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
void read_file(bool outToFile = true){
#ifdef LOCAL_TEST
    freopen("in.in", "rt", stdin);
    if(outToFile)
    freopen("out.out", "wt", stdout);
#endif
}
//
int n, m;
const int MAXN = 12345+9;
int is[MAXN];
int has[MAXN], dp[MAXN];
vvi G;
int root;
//
void DFS(int u=root, int p=-1){

    has[u] = is[u];
    dp[u] = 0;
    for(int i=0, sz=G[u].size(); i<sz; i++)
    {
        int v = G[u][i];
        if(v == p) continue;
        DFS(v, u);

        if(has[v])
            dp[u] += 2 + dp[v], has[u] = 1;
    }
}
ii DFS2(int u=root, int p=-1){

    ii ret = MP(0, u);
    has[u] = is[u];
    for(int i=0,sz=G[u].size(); i<sz; i++)
    {
        int v = G[u][i];
        if(v == p) continue;

        ii nw = DFS2(v, u);
        if(!has[v]) continue;
        nw.first++;

        has[u] = 1;
        if(ret.first < nw.first)
            ret = nw;
        else if(ret.first == nw.first)
            ret.second = min(ret.second, nw.second);
    }

    return ret;
}
//
int main()
{
    read_file();
    while(scanf("%d%d", &n, &m) != -1)
    {
        G.assign(n, vi());
        for(int i=0; i<n-1; i++)
        {
            int u, v;
            scanf("%d%d", &u, &v);
            u--, v--;
            G[u].PB(v);
            G[v].PB(u);
        }

        memset(is, 0, sizeof is);
        for(int i=0; i<m; i++)
        {
            int x;
            scanf("%d", &x);
            x--;
            is[x] = 1;
            root = x;
        }

        DFS();

        int ans = dp[root];
        //DEBUG(ans);

        int a = DFS2(root).second;
        //DEBUG(a);
        ii tmp = DFS2(a);
        int b = tmp.second;
        ans -= tmp.first;
        int ans2 = min(a, b);

        printf("%d\n%d\n", ans2+1, ans);
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <ii> vii;
typedef vector <vii> vvii;
#define endl '\n'
#define PB push_back
#define MP make_pair
#define OO (2000000000)         // ToDo
#define EPS (1e-9)              // ToDo
#define MOD (1000000007)        // ToDo
#define all(v) ((v).begin()),((v).end())
#define DEBUG(x) cout<< #x <<" = "<<"\""<< (x) <<"\""<<endl
#define FASTIO ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
void read_file(bool outToFile = true){
#ifdef LOCAL_TEST
    freopen("in.in", "rt", stdin);
    if(outToFile)
    freopen("out.out", "wt", stdout);
#endif
}
//
int n, m;
vvi G;
const int MAXN = 200000+9;
bool is[MAXN];
int sub[MAXN];
int root;
int yet;
int dp1[MAXN], dp2[MAXN];
//
void DFS0(int u=0, int p=-1){

    sub[u] = is[u];
    int cnt = 0;

    int sz = G[u].size();
    for(int i=0; i<sz; i++)
    {
        int v = G[u][i];
        if(v == p) continue;

        DFS0(v, u);
        sub[u] += sub[v];
        if(sub[v]) cnt++;
    }

    int val = m - sub[u];
    if(val) cnt++;

    if(yet && cnt <= 1 && is[u])
    {
        root = min(root, u);
    }
}
void DFS(int u=0, int p=-1){

    dp1[u] = 0;

    int sz = G[u].size();
    for(int i=0; i<sz; i++)
    {
        int v = G[u][i];
        if(v == p) continue;

        DFS(v, u);

        if(sub[v])
            dp1[u] += 2 + dp1[v];
    }

    dp2[u] = dp1[u];
    for(int i=0; i<sz; i++)
    {
        int v = G[u][i];
        if(v == p) continue;

        if(sub[v])
        {
            int nw = dp1[u] - 2 - dp1[v];
            assert(nw >= 0);
            nw += 1 + dp2[v];
            dp2[u] = min(dp2[u], nw);
        }
    }
}
//
int main()
{
    read_file();
    while(scanf("%d%d", &n, &m) != -1)
    {
        memset(is, 0, sizeof is);
        G.assign(n, vi());
        for(int i=0; i<n-1; i++)
        {
            int u, v;
            scanf("%d%d", &u, &v);
            u--, v--;
            G[u].PB(v);
            G[v].PB(u);
        }
        for(int i=0; i<m; i++)
        {
            int x;
            scanf("%d", &x);
            x--;
            is[x] = 1;
        }

        root = OO;
        yet = 1;
        DFS0();
        yet = 0;
        assert(root != OO);
        DFS0(root);

        DFS(root);

        int ans = dp2[root];
        printf("%d\n%d\n\n", root+1, ans);
    }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <ii> vii;
typedef vector <vii> vvii;
#define endl '\n'
#define PB push_back
#define MP make_pair
#define OO (2000000000)         // ToDo
#define EPS (1e-9)              // ToDo
#define MOD (1000000007)        // ToDo
#define all(v) ((v).begin()),((v).end())
#define DEBUG(x) cout<< #x <<" = "<<"\""<< (x) <<"\""<<endl
#define FASTIO ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
void read_file(bool outToFile = true){
#ifdef LOCAL_TEST
    freopen("in.in", "rt", stdin);
    if(outToFile)
    freopen("out.out", "wt", stdout);
#endif
}
//
int n, m;
vvi G;
const int MAXN = 200000+9;
bool is[MAXN];
//
int dp1[MAXN];
void DFS1(int u=0, int p=-1){

    dp1[u] = 0;

    int sz = G[u].size();
    for(int i=0; i<sz; i++)
    {
        int v = G[u][i];
        if(v == p) continue;

        DFS1(v, u);
        if(dp1[v] == 0 && !is[v]) continue;

        dp1[u] += dp1[v] + 2;
    }

}
//
int dp2[MAXN];
void DFS2(int u=0, int p=-1, int up=0){

    dp2[u] = dp1[u];
    if(p == -1);
    else
    {
        if(up == 0 && !is[p]);
        else dp2[u] += up + 2;
    }

    int sz = G[u].size();
    for(int i=0; i<sz; i++)
    {
        int v = G[u][i];
        if(v == p) continue;

        int cost = dp2[u];
        if(dp1[v] == 0 && !is[v]);
        else cost -= 2 + dp1[v];

        DFS2(v, u, cost);
    }

}
//
int dp3[MAXN];
void DFS3(int u=0, int p=-1){

    dp3[u] = is[u]? 0 : -OO;

    int sz = G[u].size();
    for(int i=0; i<sz; i++)
    {
        int v = G[u][i];
        if(v == p) continue;

        DFS3(v, u);
        if(dp1[v] == 0 && !is[v])
        {
            assert(dp3[v] == -OO);
            continue;
        }

        dp3[u] = max(dp3[u], 1 + dp3[v]);
    }

}
//
int dp4[MAXN];
void DFS4(int u=0, int p=-1, int up=-OO){

    dp4[u] = max(dp3[u], up + 1);

    int sz = G[u].size();
    int mxr[sz];
    for(int i=sz-1; i>=0; i--)
    {
        int v = G[u][i];
        if(v == p)
        {
            mxr[i] = -OO;
        }
        else
            mxr[i] = dp3[v];

        if(i+1 <= sz-1)
            mxr[i] = max(mxr[i], mxr[i+1]);
    }

    int mx = -OO;
    for(int i=0; i<sz; i++)
    {
        int v = G[u][i];
        if(v == p) continue;

        int nw = mx+1;
        if(i+1 <= sz-1)
            nw = max(nw, mxr[i+1]+1);

        nw = max(nw, up+1);

        if(is[u]) nw = max(nw, 0);

        DFS4(v, u, nw);
        mx = max(mx, dp3[v]);
    }
}
//
int main()
{
    read_file();
    while(scanf("%d%d", &n, &m) != -1)
    {
        memset(is, 0, sizeof is);
        G.assign(n, vi());
        for(int i=0; i<n-1; i++)
        {
            int u, v;
            scanf("%d%d", &u, &v);
            u--, v--;
            G[u].PB(v);
            G[v].PB(u);
        }
        for(int i=0; i<m; i++)
        {
            int x;
            scanf("%d", &x);
            x--;
            is[x] = 1;
        }

        DFS1();
        DFS2();
        DFS3();
        DFS4();

        int ans = -1, ansl = OO;
        for(int i=0; i<n; i++)
        {
            int nw = dp2[i] - dp4[i];

            assert(nw >= 0);

            if(nw < ansl)
            {
                ans = i;
                ansl = nw;
            }
        }

        assert(ans != -1);
        printf("%d\n%d\n\n", ans+1, ansl);
    }
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(false);cin.tie(0);
using namespace std;
#define pb push_back
#define pob pop_back
#define pf push_front
#define pof pop_front
#define mp make_pair
#define all(a) a.begin(),a.end()
#define bitcnt(x) __builtin_popcountll(x)
#define MOD 1000000007
#define MAXN 100005
#define BASE 31
#define BLOCK 250
typedef unsigned long long int uint64;
typedef long long int int64;

int ans=1e9,ml=0;

vector<int>v[123459];
int mark[123459];

void dfs(int nod,int par,int levl){
	if(mark[nod]){
		if(levl>ml){
			ml=levl;
			ans=nod;
		}
		else if(ml==levl){
			ans=min(ans,nod);
		}
	}
	for(int i=0;i<v[nod].size();i++){
		int to=v[nod][i];
		if(to==par)
		continue;
		dfs(to,nod,levl+1);
	}
}
int req=0;

bool go(int nod,int par){
	bool ret=false;
	for(int i=0;i<v[nod].size();i++){
		int to =v[nod][i];
		if(to==par)
		continue;
		bool val=go(to,nod);
		if(val)
		req++;
		ret|=val;
	}
	ret|=(mark[nod]==1);
	return ret;
}

int main(){
	int n,m,x,y,i;
	scanf("%d%d",&n,&m);

	for(i=1;i<n;i++){
		scanf("%d%d",&x,&y);
		v[x].pb(y);
		v[y].pb(x);
	}
	for(i=1;i<=m;i++){
		scanf("%d",&x);
		mark[x]=1;
	}

	ans=x;
	int cost=1e9;
	dfs(x,-1,0);
	/*
	dfs(ans,-1,0);
	printf("%d\n",ans);
	*/
	for(i=1;i<=n;i++){
		if(mark[i]){
			req=0;
			go(i,-1);
			req=2*req;
			req-=ml;
			if(req<cost){
				cost=req;
				ans=i;
			}
		}
	}
	printf("%d\n",ans);
	printf("%d\n",req);
	return 0;
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(false);cin.tie(0);
using namespace std;
#define pb push_back
#define pob pop_back
#define pf push_front
#define pof pop_front
#define mp make_pair
#define all(a) a.begin(),a.end()
#define bitcnt(x) __builtin_popcountll(x)
#define MOD 1000000007
#define MAXN 100005
#define BASE 31
#define BLOCK 250
typedef unsigned long long int uint64;
typedef long long int int64;

int ans=1e9,ml=0;

vector<int>v[123459];
int mark[123459];

void dfs(int nod,int par,int levl){
	if(mark[nod]){
		if(levl>ml){
			ml=levl;
			ans=nod;
		}
		else if(ml==levl){
			ans=min(ans,nod);
		}
	}
	for(int i=0;i<v[nod].size();i++){
		int to=v[nod][i];
		if(to==par)
		continue;
		dfs(to,nod,levl+1);
	}
}
int req=0;

bool go(int nod,int par){
	bool ret=false;
	for(int i=0;i<v[nod].size();i++){
		int to =v[nod][i];
		if(to==par)
		continue;
		bool val=go(to,nod);
		if(val)
		req++;
		ret|=val;
	}
	ret|=(mark[nod]==1);
	return ret;
}

int main(){
	int n,m,x,y,i;
	scanf("%d%d",&n,&m);

	for(i=1;i<n;i++){
		scanf("%d%d",&x,&y);
		v[x].pb(y);
		v[y].pb(x);
	}
	for(i=1;i<=m;i++){
		scanf("%d",&x);
		mark[x]=1;
	}
	ans=x;
	dfs(x,-1,0);
	dfs(ans,-1,0);
	printf("%d\n",ans);
	go(ans,-1);
	req=2*req;
	req-=ml;
	printf("%d\n",req);
	return 0;
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(false);cin.tie(0);
using namespace std;
#define pb push_back
#define pob pop_back
#define pf push_front
#define pof pop_front
#define mp make_pair
#define all(a) a.begin(),a.end()
#define bitcnt(x) __builtin_popcountll(x)
#define MOD 1000000007
#define MAXN 100005
#define BASE 31
#define BLOCK 250
typedef unsigned long long int uint64;
typedef long long int int64;

int ans=1e9,ml=0;

vector<int>v[123459];
int mark[123459];
int lev[123459];

void dfs(int nod,int par,int levl){
	lev[nod]=levl;
	for(int i=0;i<v[nod].size();i++){
		int to=v[nod][i];
		if(to==par)
		continue;
		dfs(to,nod,levl+1);
	}
}
int req=0;

bool go(int nod,int par,int levl){
	bool ret=false;
	if(mark[nod])
	ml=max(ml,levl);

	for(int i=0;i<v[nod].size();i++){
		int to =v[nod][i];
		if(to==par)
		continue;
		bool val=go(to,nod,levl+1);
		if(val)
		req++;
		ret|=val;
	}
	ret|=(mark[nod]==1);
	return ret;
}

int main(){
	int n,m,x,y,i;
	scanf("%d%d",&n,&m);

	for(i=1;i<n;i++){
		scanf("%d%d",&x,&y);
		v[x].pb(y);
		v[y].pb(x);
	}
	for(i=1;i<=m;i++){
		scanf("%d",&x);
		mark[x]=1;
	}
	dfs(1,-1,0);
	int nod=1e9,clev=0;
	for(i=1;i<=n;i++){
		if(mark[i]){
			if(lev[i]>clev){
				clev=lev[i];
				nod=i;
			}
			else if(lev[i]==clev){
				nod=min(nod,i);
			}
		}
	}
	dfs(nod,-1,0);
	clev=0;
	int nod1=1e9;
	for(i=1;i<=n;i++){
		if(mark[i]){
			if(lev[i]>clev){
				clev=lev[i];
				nod1=i;
			}
			else if(lev[i]==clev){
				nod1=min(nod1,i);
			}
		}
	}
	nod=min(nod,nod1);
	go(nod,-1,0);
	printf("%d\n",nod);
	req=2*req;
	req-=ml;
	printf("%d\n",req);
	return 0;
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(false);cin.tie(0);
using namespace std;
#define pb push_back
#define pob pop_back
#define pf push_front
#define pof pop_front
#define mp make_pair
#define all(a) a.begin(),a.end()
#define bitcnt(x) __builtin_popcountll(x)
#define MOD 1000000007
#define MAXN 100005
#define BASE 31
#define BLOCK 250
typedef unsigned long long int uint64;
typedef long long int int64;

int ans=1e9,ml=0;

vector<int>v[123459];
int mark[123459];

void dfs(int nod,int par,int levl){
	if(mark[nod]){
		if(levl>ml){
			ml=levl;
			ans=nod;
		}
		else if(ml==levl){
			ans=min(ans,nod);
		}
	}
	for(int i=0;i<v[nod].size();i++){
		int to=v[nod][i];
		if(to==par)
		continue;
		dfs(to,nod,levl+1);
	}
}
int req=0;

bool go(int nod,int par){
	bool ret=false;
	for(int i=0;i<v[nod].size();i++){
		int to =v[nod][i];
		if(to==par)
		continue;
		bool val=go(to,nod);
		if(val)
		req++;
		ret|=val;
	}
	ret|=(mark[nod]==1);
	return ret;
}

int main(){
	int n,m,x,y,i;
	scanf("%d%d",&n,&m);

	for(i=1;i<n;i++){
		scanf("%d%d",&x,&y);
		v[x].pb(y);
		v[y].pb(x);
	}
	for(i=1;i<=m;i++){
		scanf("%d",&x);
		mark[x]=1;
	}
	ans=1;
	dfs(1,-1,0);
	dfs(ans,-1,0);
	printf("%d\n",ans);
	go(ans,-1);
	req=2*req;
	req-=ml;
	printf("%d\n",req);
	return 0;
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(false);cin.tie(0);
using namespace std;
#define pb push_back
#define pob pop_back
#define pf push_front
#define pof pop_front
#define mp make_pair
#define all(a) a.begin(),a.end()
#define bitcnt(x) __builtin_popcountll(x)
#define MOD 1000000007
#define MAXN 100005
#define BASE 31
#define BLOCK 250
typedef unsigned long long int uint64;
typedef long long int int64;

int ans=1e9,ml=0;

vector<int>v[123459];
int mark[123459];
int lev[123459];

void dfs(int nod,int par,int levl){
	lev[nod]=levl;
	for(int i=0;i<v[nod].size();i++){
		int to=v[nod][i];
		if(to==par)
		continue;
		dfs(to,nod,levl+1);
	}
}
int req=0;

bool go(int nod,int par,int levl){
	bool ret=false;
	if(mark[nod])
	ml=max(ml,levl);

	for(int i=0;i<v[nod].size();i++){
		int to =v[nod][i];
		if(to==par)
		continue;
		bool val=go(to,nod,levl+1);
		if(val)
		req++;
		ret|=val;
	}
	ret|=(mark[nod]==1);
	return ret;
}

int main(){
	int n,m,x,y,i;
	scanf("%d%d",&n,&m);

	for(i=1;i<n;i++){
		scanf("%d%d",&x,&y);
		v[x].pb(y);
		v[y].pb(x);
	}
	for(i=1;i<=m;i++){
		scanf("%d",&x);
		mark[x]=1;
	}
	dfs(x,-1,0);
	int nod=1e9,clev=0;
	for(i=1;i<=n;i++){
		if(mark[i]){
			if(lev[i]>clev){
				clev=lev[i];
				nod=i;
			}
			else if(lev[i]==clev){
				nod=min(nod,i);
			}
		}
	}
	dfs(nod,-1,0);
	clev=0;
	int nod1=1e9;
	for(i=1;i<=n;i++){
		if(mark[i]){
			if(lev[i]>clev){
				clev=lev[i];
				nod1=i;
			}
			else if(lev[i]==clev){
				nod1=min(nod1,i);
			}
		}
	}
	nod=min(nod,nod1);
	go(nod,-1,0);
	printf("%d\n",nod);
	req=2*req;
	req-=ml;
	printf("%d\n",req);
	return 0;
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(false);cin.tie(0);
using namespace std;
#define pb push_back
#define pob pop_back
#define pf push_front
#define pof pop_front
#define mp make_pair
#define all(a) a.begin(),a.end()
#define bitcnt(x) __builtin_popcountll(x)
#define MOD 1000000007
#define MAXN 100005
#define BASE 31
#define BLOCK 250
typedef unsigned long long int uint64;
typedef long long int int64;

int ans=1e9,ml=0;

vector<int>v[123459];
int mark[123459];

void dfs(int nod,int par,int levl){
	if(mark[nod]){
		if(levl>ml){
			ml=levl;
			ans=nod;
		}
		else if(ml==levl){
			ans=min(ans,nod);
		}
	}
	for(int i=0;i<v[nod].size();i++){
		int to=v[nod][i];
		if(to==par)
		continue;
		dfs(to,nod,levl+1);
	}
}
int req=0;

bool go(int nod,int par){
	bool ret=false;
	for(int i=0;i<v[nod].size();i++){
		int to =v[nod][i];
		if(to==par)
		continue;
		bool val=go(to,nod);
		if(val)
		req++;
		ret|=val;
	}
	ret|=(mark[nod]==1);
	return ret;
}

int main(){
	int n,m,x,y,i;
	scanf("%d%d",&n,&m);

	for(i=1;i<n;i++){
		scanf("%d%d",&x,&y);
		v[x].pb(y);
		v[y].pb(x);
	}
	for(i=1;i<=m;i++){
		scanf("%d",&x);
		mark[x]=1;
	}
	dfs(x,-1,0);
	int ans1=ans;
	dfs(ans,-1,0);
	ans=min(ans1,ans);
	printf("%d\n",ans);
	go(ans,-1);
	req=2*req;
	req-=ml;
	printf("%d\n",req);
	return 0;
}


#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <cmath>
#include <vector>
#include <iomanip>
#include <queue>
using namespace std;
const double eps = 1e-9;
const long long mod=1000000007;
const double pi=3.14159265359;
const int MAXN=500000;
vector<int> g[222222];
vector<int> v;
string s;
int n,m;
bool bad[222222];
bool gogo[2222222];

int go(int st){
	int res=0;
	gogo[st]=true;
	bool ok=true;
	for(int i=0;i<g[st].size();i++){
		if(!gogo[g[st][i]]){
			ok=false;
			int val=go(g[st][i]);
			res = res + val + 1;
		}
	}
	if(ok){
		if(bad[st]) res=0;
		else res=-1;
	}
	return res;
}

int main(){
	//freopen("in","r",stdin);
	cin>>n>>m;
	int x,y;
	for(int i=0;i<n-1;i++){
		cin>>x>>y;
		g[x-1].push_back(y-1);
		g[y-1].push_back(x-1);
	}
	int lol;
	int s;

	int max=0;
	int real;
	for(int i=0;i<m;i++){
		cin>>lol;
		s=lol-1;
		real=lol-1;
		bad[lol-1]=true;
	}
	int wat=go(s);
	int dal=s;

	queue<int> q;
	q.push (s);
	vector<bool> used (n);
	vector<int> d (n), p (n);
	used[s] = true;
	p[s] = -1;

	while (!q.empty()) {
		int v = q.front();
		q.pop();
		for (size_t i=0; i<g[v].size(); ++i) {
			int to = g[v][i];
			if (!used[to]) {
				used[to] = true;
				q.push (to);
				d[to] = d[v] + 1;
				if(max<d[to]&&bad[to]){
					max=d[to];
					dal=to;
				}
				if(max==d[to]&&bad[to]){
					dal=to;
				}
				p[to] = v;
			}
		}
	}
	s=dal;
	max=0;

	queue<int> q1;
	q1.push (s);
	vector<bool> used1 (n);
	vector<int> d1 (n), p1 (n);
	used1[s] = true;
	p1[s] = -1;
	while (!q1.empty()) {
		int v = q1.front();
		q1.pop();
		for (size_t i=0; i<g[v].size(); ++i) {
			int to = g[v][i];
			if (!used1[to]) {
				used1[to] = true;
				q1.push (to);
				d1[to] = d1[v] + 1;
				if(max<d1[to]&&bad[to]){
					max=d1[to];
					dal=to;
				}
				if((max==d1[to]&&bad[to])&& to<dal){
					dal=to;
				}
				p1[to] = v;
			}
		}
	}
	//cout<<d[]
	if(m==1){
		cout<<real+1<<endl;
		cout<<0<<endl;
		return 0;
	}
	cout<<min(s+1,dal+1)<<endl;
	cout<<wat-max<<endl;
	return 0;
}


#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <cmath>
#include <vector>
#include <iomanip>
#include <queue>
using namespace std;
const double eps = 1e-9;
const long long mod=1000000007;
const double pi=3.14159265359;
const int MAXN=500000;
vector<int> g[222222];
vector<int> v;
string s;
int n,m;
bool bad[222222];
bool gogo[2222222];

int go(int st){
	int res=-1;
	gogo[st]=true;
	bool ok=true;
	bool ook=false;
	for(size_t i=0;i<g[st].size();++i){
		if(!gogo[g[st][i]]){
			ok=false;
			int val=go(g[st][i]);
			res = res + val + 1;
			if(val>-1){
				ook=true;
			}
		}
	}
	if(ook||bad[st]){
		res++;
	}
	return res;
}

int main(){
	//freopen("in","r",stdin);
	cin>>n>>m;
	int x,y;
	for(int i=0;i<n-1;i++){
		cin>>x>>y;
		g[x-1].push_back(y-1);
		g[y-1].push_back(x-1);
	}
	int lol;
	int s;

	int max=0;
	int real;
	for(int i=0;i<m;i++){
		cin>>lol;
		s=lol-1;
		real=lol-1;
		bad[lol-1]=true;
	}
	//cout<<s<<endl;
	int wat=go(s);

	int dal=s;
	queue<int> q;
	q.push (s);
	vector<bool> used (n);
	vector<int> d (n), p (n);
	used[s] = true;
	p[s] = -1;

	while (!q.empty()) {
		int v = q.front();
		q.pop();
		for (size_t i=0; i<g[v].size(); ++i) {
			int to = g[v][i];
			if (!used[to]) {
				used[to] = true;
				q.push (to);
				d[to] = d[v] + 1;
				if(max<d[to]&&bad[to]){
					max=d[to];
					dal=to;
				}
				if((max==d[to]&&bad[to])&& to<dal){
					dal=to;
				}
				p[to] = v;
			}
		}
	}
	s=dal;
	max=0;

	queue<int> q1;
	q1.push (s);
	vector<bool> used1 (n);
	vector<int> d1 (n), p1 (n);
	used1[s] = true;
	p1[s] = -1;
	while (!q1.empty()) {
		int v = q1.front();
		q1.pop();
		for (size_t i=0; i<g[v].size(); ++i) {
			int to = g[v][i];
			if (!used1[to]) {
				used1[to] = true;
				q1.push (to);
				d1[to] = d1[v] + 1;
				if(max<d1[to]&&bad[to]){
					max=d1[to];
					dal=to;
				}
				if((max==d1[to]&&bad[to])&& to<dal){
					dal=to;
				}
				p1[to] = v;
			}
		}
	}

	//cout<<d[]
	if(m==1){
		cout<<real+1<<endl;
		cout<<0<<endl;
		return 0;
	}
	cout<<min(s+1,dal+1)<<endl;
	cout<<2*wat-max<<endl;
	//if(2*wat-max==92) cout<<max<<endl;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

template <class T,class U>
void maximize(T &lhs,U rhs){
    if(lhs < rhs)lhs = rhs;
}
template <class T,class U>
void minimize(T &lhs,U rhs){
    if(lhs > rhs)lhs = rhs;
}
template < class T,class U >
void maximize(T &lhs,const initializer_list < U > &rhs){
    U max_rhs = max(rhs);
    if(lhs < max_rhs){
        lhs = max_rhs;
    }
}
template < class T,class U >
void minimize(T &lhs,const initializer_list < U > &rhs){
    U min_rhs = min(rhs);
    if(lhs > min_rhs){
        lhs = min_rhs;
    }
}
template <class T>
T tabs(T x){
    return (x < (T)0 ? -x : x);
}

#define len(c) (int)((c).size())
#define llong long long
#define MASK(i) ((1LL) << (i))
#define BIT(x,i) (((x) >> (i)) & 1)
#define file_name "test"    /// FILE NAME HERE!!!

/* ================================= END OF TEMPLATE ================================= */

/* ================================= DEBUG ================================= */

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

#define rand __rand
mt19937 generator(chrono::system_clock::now().time_since_epoch().count());
template <class T = int>
T rand(T range = numeric_limits <T> :: max()){
    return (T) (generator() % range);
}

/* ================================= DEBUG ================================= */
namespace Task{

    const int maxC = 26;
    const int maxLw = 1000;
    int n,m;
    string text;
    vector < int > f;
    string word_len[maxLw + 10];

    class AhoCorasick{
        public:
           vector < vector < int > > to;
           vector < int > suffLinks;
           vector < bitset < maxLw + 10 > > hasLength;
        public:
           AhoCorasick(const vector < string > &pat){
               int maxLen = 0;
               for_each(pat.begin(),pat.end(),[&](const string &str){
                       maxLen += len(str);
               });
               suffLinks.resize(maxLen + 2,0);
               to.resize(maxLen + 2,vector < int > (maxC,0));
               hasLength.resize(maxLen + 2,bitset < maxLw + 10 > () );
               int cur = 0;
               for(const string &str : pat){
                   int u = 0;
                   for(char ch : str){
                       int c = ch - 'a';
                       if(!to[u][c]){
                           to[u][c] = ++cur;
                       }
                       u = to[u][c];
                   }
                   hasLength[u][len(str)] = 1;
               }
           }

           void pushLinks(){
               queue < int > q;
               q.emplace(0);
               while(!q.empty()){
                   int v = q.front(); q.pop();
                   int u = suffLinks[v];
                   for(int c = 0;c < maxC;++c){
                       if(to[v][c]){
                           q.emplace(to[v][c]);
                           suffLinks[to[v][c]] = v ? to[u][c] : 0;
                           hasLength[to[v][c]] |= hasLength[to[u][c]];
                       } else {
                           to[v][c] = to[u][c];
                       }
                   }
               }
           }

           void computeDP(const string &text,vector < int > &dp){
               int cur = 0;
               dp[0] = 1;
               for(int i = 0;i < len(text);++i){
                   int c = text[i] - 'a';
                   cur = to[cur][c];
                   if(cur){
                       for(int j = 1;j <= maxLw;++j){
                           if(hasLength[cur][j] and i + 1 >= j){
                               dp[i + 1] |= dp[i + 1 - j];
                           }
                       }
                   }
               }
           }
    };
    AhoCorasick *aho;

    void solve(){
        cin>>n>>text>>m;
        f.resize(n + 2,0);
        auto trans = [&](string &str){
            for(char &c : str){
                c = tolower(c);
            }
            reverse(str.begin(),str.end());
        };
        vector < string > pat;
        map < string,string > ma;
        for(int i = 1;i <= m;++i){
            string word,w_tmp;
            cin>>word; w_tmp = word;
            trans(word);
            pat.emplace_back(word);
            ma[word] = w_tmp;
        }
        aho = new AhoCorasick(pat);
        aho -> pushLinks();
        aho -> computeDP(text,f);
        int cur = n;
        vector < string > ans;
        while(cur){
            for(int l = 1;l <= maxLw;++l){
                if(cur - l >= 0 and f[cur - l]){
                    string str = "";
                    for(int j = cur - l;j <= cur - 1;++j){
                        str += text[j];
                    }
                    cur -= l;
                    ans.emplace_back(ma[str]);
                    break;
                }
            }
        }
        reverse(ans.begin(),ans.end());
        for_each(ans.begin(),ans.end(),[&](const string &res){cout<<res<<' ';});
        cout<<'\n';
    }
}

int main(int argc, char** argv){
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    #ifndef ONLINE_JUDGE
    freopen(file_name".inp","r",stdin);
    //freopen(file_name".out","w",stdout);
    #endif // ONLINE_JUDGE
    Task::solve();
}


#include <bits/stdc++.h>

using namespace std;

template <class T,class U>
void maximize(T &lhs,U rhs){
    if(lhs < rhs)lhs = rhs;
}
template <class T,class U>
void minimize(T &lhs,U rhs){
    if(lhs > rhs)lhs = rhs;
}
template < class T,class U >
void maximize(T &lhs,const initializer_list < U > &rhs){
    U max_rhs = max(rhs);
    if(lhs < max_rhs){
        lhs = max_rhs;
    }
}
template < class T,class U >
void minimize(T &lhs,const initializer_list < U > &rhs){
    U min_rhs = min(rhs);
    if(lhs > min_rhs){
        lhs = min_rhs;
    }
}
template <class T>
T tabs(T x){
    return (x < (T)0 ? -x : x);
}

#define len(c) (int)((c).size())
#define llong long long
#define MASK(i) ((1LL) << (i))
#define BIT(x,i) (((x) >> (i)) & 1)
#define file_name "test"    /// FILE NAME HERE!!!

/* ================================= END OF TEMPLATE ================================= */

/* ================================= DEBUG ================================= */

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

#define rand __rand
mt19937 generator(chrono::system_clock::now().time_since_epoch().count());
template <class T = int>
T rand(T range = numeric_limits <T> :: max()){
    return (T) (generator() % range);
}

/* ================================= DEBUG ================================= */
namespace Task{

    const int maxC = 26;
    const int maxLw = 1000;
    int n,m;
    string text;
    vector < int > f;
    string word_len[maxLw + 10];

    class AhoCorasick{
        public:
           vector < vector < int > > to;
           vector < int > suffLinks;
           vector < bitset < maxLw + 10 > > hasLength;
        public:
           AhoCorasick(const vector < string > &pat){
               int maxLen = 0;
               for_each(pat.begin(),pat.end(),[&](const string &str){
                       maxLen += len(str);
               });
               suffLinks.resize(maxLen + 2,0);
               to.resize(maxLen + 2,vector < int > (maxC,0));
               hasLength.resize(maxLen + 2,bitset < maxLw + 10 > () );
               int cur = 0;
               for(const string &str : pat){
                   int u = 0;
                   for(char ch : str){
                       int c = ch - 'a';
                       if(!to[u][c]){
                           to[u][c] = ++cur;
                       }
                       u = to[u][c];
                   }
                   hasLength[u][len(str)] = 1;
               }
           }

           void pushLinks(){
               queue < int > q;
               q.emplace(0);
               while(!q.empty()){
                   int v = q.front(); q.pop();
                   int u = suffLinks[v];
                   for(int c = 0;c < maxC;++c){
                       if(to[v][c]){
                           q.emplace(to[v][c]);
                           suffLinks[to[v][c]] = v ? to[u][c] : 0;
                           hasLength[to[v][c]] |= hasLength[to[u][c]];
                       } else {
                           to[v][c] = to[u][c];
                       }
                   }
               }
           }

           void computeDP(const string &text,vector < int > &dp){
               int cur = 0;
               dp[0] = 1;
               for(int i = 0;i < len(text);++i){
                   int c = text[i] - 'a';
                   cur = to[cur][c];
                   if(cur){
                       for(int j = 1;j <= maxLw;++j){
                           if(hasLength[cur][j] and i + 1 >= j){
                               dp[i + 1] |= dp[i + 1 - j];
                           }
                       }
                   }
               }
           }
    };
    AhoCorasick *aho;

    void solve(){
        cin>>n>>text>>m;
        f.resize(n + 2,0);
        auto trans = [&](string &str){
            for(char &c : str){
                c = tolower(c);
            }
            reverse(str.begin(),str.end());
        };
        vector < string > pat;
        map < string,string > ma;
        for(int i = 1;i <= m;++i){
            string word,w_tmp;
            cin>>word; w_tmp = word;
            trans(word);
            pat.emplace_back(word);
            ma[word] = w_tmp;
        }
        aho = new AhoCorasick(pat);
        aho -> pushLinks();
        aho -> computeDP(text,f);
        int cur = n;
        vector < string > ans;
        while(cur){
            for(int l = 1;l <= maxLw;++l){
                if(cur - l >= 0 and f[cur - l]){
                    ans.emplace_back(ma[text.substr(cur - l,l)]);
                    cur -= l;
                    break;
                }
            }
        }
        reverse(ans.begin(),ans.end());
        for_each(ans.begin(),ans.end(),[&](const string &res){cout<<res<<' ';});
        cout<<'\n';
    }
}

int main(int argc, char** argv){
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    #ifndef ONLINE_JUDGE
    freopen(file_name".inp","r",stdin);
    //freopen(file_name".out","w",stdout);
    #endif // ONLINE_JUDGE
    Task::solve();
}


#include <bits/stdc++.h>

using namespace std;

template <class T,class U>
void maximize(T &lhs,U rhs){
    if(lhs < rhs)lhs = rhs;
}
template <class T,class U>
void minimize(T &lhs,U rhs){
    if(lhs > rhs)lhs = rhs;
}
template < class T,class U >
void maximize(T &lhs,const initializer_list < U > &rhs){
    U max_rhs = max(rhs);
    if(lhs < max_rhs){
        lhs = max_rhs;
    }
}
template < class T,class U >
void minimize(T &lhs,const initializer_list < U > &rhs){
    U min_rhs = min(rhs);
    if(lhs > min_rhs){
        lhs = min_rhs;
    }
}
template <class T>
T tabs(T x){
    return (x < (T)0 ? -x : x);
}

#define len(c) (int)((c).size())
#define llong long long
#define MASK(i) ((1LL) << (i))
#define BIT(x,i) (((x) >> (i)) & 1)
#define file_name "test"    /// FILE NAME HERE!!!

/* ================================= END OF TEMPLATE ================================= */

/* ================================= DEBUG ================================= */

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

#define rand __rand
mt19937 generator(chrono::system_clock::now().time_since_epoch().count());
template <class T = int>
T rand(T range = numeric_limits <T> :: max()){
    return (T) (generator() % range);
}

/* ================================= DEBUG ================================= */
namespace Task{

    const int maxC = 26;
    const int maxLw = 1000;
    int n,m;
    string text;
    vector < int > f;
    string word_len[maxLw + 10];

    class AhoCorasick{
        public:
           vector < vector < int > > to;
           vector < int > suffLinks;
           vector < bitset < maxLw + 10 > > hasLength;
        public:
           AhoCorasick(const vector < string > &pat){
               int maxLen = 0;
               for_each(pat.begin(),pat.end(),[&](const string &str){
                       maxLen += len(str);
               });
               suffLinks.resize(maxLen + 2,0);
               to.resize(maxLen + 2,vector < int > (maxC,0));
               hasLength.resize(maxLen + 2,bitset < maxLw + 10 > () );
               int cur = 0;
               for(const string &str : pat){
                   int u = 0;
                   for(char ch : str){
                       int c = ch - 'a';
                       if(!to[u][c]){
                           to[u][c] = ++cur;
                       }
                       u = to[u][c];
                   }
                   hasLength[u][len(str)] = 1;
               }
           }

           void pushLinks(){
               queue < int > q;
               q.emplace(0);
               while(!q.empty()){
                   int v = q.front(); q.pop();
                   int u = suffLinks[v];
                   for(int c = 0;c < maxC;++c){
                       if(to[v][c]){
                           q.emplace(to[v][c]);
                           suffLinks[to[v][c]] = v ? to[u][c] : 0;
                           hasLength[to[v][c]] |= hasLength[to[u][c]];
                       } else {
                           to[v][c] = to[u][c];
                       }
                   }
               }
           }

           vector < int > computeDP(const string &text,vector < int > &dp){
               int cur = 0;
               dp[0] = 1;
               vector < int > prev(len(dp) + 2,0);
               for(int i = 0;i < len(text);++i){
                   int c = text[i] - 'a';
                   cur = to[cur][c];
                   if(cur){
                       /*if(hasLength[cur].any()){
                           debug(cur,i);
                       }*/
                       for(int j = 1;j <= maxLw;++j){
                           if(hasLength[cur][j] and i + 1 >= j){
                               //debug(i,j);
                               if(dp[i + 1 - j]){
                                   dp[i + 1] |= dp[i + 1 - j];
                                   prev[i + 1] = j;
                               }
                           }
                       }
                   }
               }
               return prev;
           }
    };
    AhoCorasick *aho;

    void solve(){
        cin>>n>>text>>m;
        f.resize(n + 2,0);
        auto trans = [&](string &str){
            for(char &c : str){
                c = tolower(c);
            }
            reverse(str.begin(),str.end());
        };
        vector < string > pat;
        map < string,string > ma;
        for(int i = 1;i <= m;++i){
            string word,w_tmp;
            cin>>word; w_tmp = word;
            trans(word);
            pat.emplace_back(word);
            ma[word] = w_tmp;
        }
        aho = new AhoCorasick(pat);
        aho -> pushLinks();
        vector < int > prev = aho -> computeDP(text,f);
        int cur = n;
        vector < string > ans;
        //debug(f);
        while(cur){
            //debug(cur,prev[cur]);
            ans.emplace_back(ma[text.substr(cur - prev[cur],prev[cur])]);
            cur -= prev[cur];
        }
        reverse(ans.begin(),ans.end());
        for_each(ans.begin(),ans.end(),[&](const string &res){cout<<res<<' ';});
        cout<<'\n';
    }
}

int main(int argc, char** argv){
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    #ifndef ONLINE_JUDGE
    freopen(file_name".inp","r",stdin);
    //freopen(file_name".out","w",stdout);
    #endif // ONLINE_JUDGE
    Task::solve();
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e4 + 500;
int m, n, nxt[N]; //luu[N];

string a, b, luu[N];
unordered_map<ll, string> tu;
vector<string> res;

struct DoubleHash
{
    vector<ll> H1, H2, p1, p2;
    ll base1 = 311, base2 = 313, mod1 = 1e9 + 8277, mod2 = 1e9 + 9277;
    void init(string s)
    {
        int n = s.size();
        p1.resize(n + 2, 1), p2.resize(n + 2, 1), H1.resize(n + 2, 0), H2.resize(n + 2, 0);
        for (int i = 1; i <= n; i++)
        {
            p1[i] = p1[i - 1] * base1 % mod1;
            p2[i] = p2[i - 1] * base2 % mod2;
            H1[i] = (H1[i - 1] * base1 + tolower(s[i - 1])) % mod1;
            H2[i] = (H2[i - 1] * base2 + tolower(s[i - 1])) % mod2;
        }
    }
    ll getHash(int u, int v)
    {
        ll t1 = (H1[v] - H1[u - 1] * p1[v - u + 1] + mod1 * mod1) % mod1;
        ll t2 = (H2[v] - H2[u - 1] * p2[v - u + 1] + mod2 * mod2) % mod2;
        return t1 * 1e9 + t2;
    }
} Ta, Tb;

bool solve(int u)
{
    if (u >= n)
        return 1;
    if (nxt[u] != -1)
        return 1;
    for (int i = u; i < n; i++)
    {
        ll x = Ta.getHash(u + 1, i + 1);
        if (tu.count(x))
        {
            bool ok = solve(i + 1);
            if (ok)
                nxt[u] = i + 1, luu[u] = tu[x];
        }
    }
    return 1;
}

int main()
{
    //freopen("z.inp", "r", stdin);
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin >> n >> a >> m;
    reverse(a.begin(), a.end());
    Ta.init(a);
    for (int i = 1; i <= m; i++)
    {
        cin >> b;
        Tb.init(b);
        ll x = Tb.getHash(1, b.size());
        tu[x] = b;
    }
    fill(nxt, nxt + N, -1);
    solve(0);
    int u = 0;
    while (u < n)
    {
        res.push_back(luu[u]);
        u = nxt[u];
    }
    reverse(res.begin(), res.end());
    for (auto v : res)
        cout << v << " ";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e4 + 500;
int m, n, nxt[N];

string a, b, luu[N];
unordered_map<ll, bool> HM;
unordered_map<ll, string> tu;

struct DoubleHash
{
    vector<ll> H1, H2, p1, p2;
    ll base1 = 311, base2 = 313, mod1 = 1e9 + 8277, mod2 = 1e9 + 9277;
    void init(string s)
    {
        int n = s.size();
        p1.resize(n + 2, 1), p2.resize(n + 2, 1), H1.resize(n + 2, 0), H2.resize(n + 2, 0);
        for (int i = 1; i <= n; i++)
        {
            p1[i] = p1[i - 1] * base1 % mod1;
            p2[i] = p2[i - 1] * base2 % mod2;
            H1[i] = (H1[i - 1] * base1 + tolower(s[i - 1])) % mod1;
            H2[i] = (H2[i - 1] * base2 + tolower(s[i - 1])) % mod2;
        }
    }
    ll getHash(int u, int v)
    {
        ll t1 = (H1[v] - H1[u - 1] * p1[v - u + 1] + mod1 * mod1) % mod1;
        ll t2 = (H2[v] - H2[u - 1] * p2[v - u + 1] + mod2 * mod2) % mod2;
        return t1 * 1e9 + t2;
    }
} Ta, Tb;

vector<string> res;
void solve(int u)
{
    if (u >= n)
    {
        reverse(res.begin(), res.end());
        for (auto v : res)
            cout << v << " ";
        exit(0);
    }
    for (int i = u; i < n; i++)
        if (i - u + 1 <= 1000)
        {
            ll x = Ta.getHash(u + 1, i + 1);
            if (HM.count(x))
            {
                res.push_back(tu[x]);
                solve(i + 1);
                res.pop_back();
            }
        }
}

int main()
{
    //freopen("z.inp", "r", stdin);
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin >> n >> a >> m;
    reverse(a.begin(), a.end());
    Ta.init(a);
    for (int i = 1; i <= m; i++)
    {
        cin >> b;
        Tb.init(b);
        ll x = Tb.getHash(1, b.size());
        HM[x] = 1;
        tu[x] = b;
    }
    fill(nxt, nxt + N, -1);
    solve(0);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e4 + 500;
long long m, n, dp[N];
string a, b;
unordered_map<ll, string> tu;

struct DoubleHash
{
    vector<ll> H1, H2, p1, p2;
    ll base1 = 311, base2 = 313, mod1 = 1e9 + 8277, mod2 = 1e9 + 9277;
    void init(string s)
    {
        int n = s.size();
        p1.resize(n + 2, 1), p2.resize(n + 2, 1), H1.resize(n + 2, 0), H2.resize(n + 2, 0);
        for (int i = 1; i <= n; i++)
        {
            p1[i] = p1[i - 1] * base1 % mod1;
            p2[i] = p2[i - 1] * base2 % mod2;
            H1[i] = (H1[i - 1] * base1 + tolower(s[i - 1])) % mod1;
            H2[i] = (H2[i - 1] * base2 + tolower(s[i - 1])) % mod2;
        }
    }
    ll getHash(int u, int v)
    {
        ll t1 = (H1[v] - H1[u - 1] * p1[v - u + 1] + mod1 * mod1) % mod1;
        ll t2 = (H2[v] - H2[u - 1] * p2[v - u + 1] + mod2 * mod2) % mod2;
        return t1 * 1e9 + t2;
    }
} Ta, Tb;

int main()
{
    //freopen("z.inp", "r", stdin);
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin >> n >> a >> m;
    reverse(a.begin(), a.end());
    Ta.init(a);
    for (int i = 1; i <= m; i++)
    {
        cin >> b;
        Tb.init(b);
        ll x = Tb.getHash(1, b.size());
        tu[x] = b;
    }
    fill(dp, dp + N, 0);
    dp[n] = 1;
    for (int i = n - 1; i >= 0; i--)
        for (int j = i; j < n && j - i + 1 <= 1000; j++)
        {
            ll curH = Ta.getHash(i + 1, j + 1);
            if (dp[j + 1] && tu.count(curH))
            {
                dp[i] = curH;
                break;
            }
        }
    //in ket qua
    vector<string> res;
    for (int i = 0; i < n; i += tu[dp[i]].size())
        res.emplace_back(tu[dp[i]]);
    reverse(res.begin(), res.end());
    for (auto v : res)
        cout << v << " ";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e4 + 500;
int m, n, nxt[N];

string a, b, luu[N];
unordered_map<ll, bool> HM;
unordered_map<ll, string> tu;

struct DoubleHash
{
    vector<ll> H1, H2, p1, p2;
    ll base1 = 311, base2 = 313, mod1 = 1e9 + 8277, mod2 = 1e9 + 9277;
    void init(string s)
    {
        int n = s.size();
        p1.resize(n + 2, 1), p2.resize(n + 2, 1), H1.resize(n + 2, 0), H2.resize(n + 2, 0);
        for (int i = 1; i <= n; i++)
        {
            p1[i] = p1[i - 1] * base1 % mod1;
            p2[i] = p2[i - 1] * base2 % mod2;
            H1[i] = (H1[i - 1] * base1 + tolower(s[i - 1])) % mod1;
            H2[i] = (H2[i - 1] * base2 + tolower(s[i - 1])) % mod2;
        }
    }
    ll getHash(int u, int v)
    {
        ll t1 = (H1[v] - H1[u - 1] * p1[v - u + 1] + mod1 * mod1) % mod1;
        ll t2 = (H2[v] - H2[u - 1] * p2[v - u + 1] + mod2 * mod2) % mod2;
        return t1 * 1e9 + t2;
    }
} Ta, Tb;

vector<string> res;
void solve(int u)
{
    if (u >= n)
    {
        reverse(res.begin(), res.end());
        for (auto v : res)
            cout << v << " ";
        exit(0);
    }
    for (int i = u; i < n; i++)
    {
        ll x = Ta.getHash(u + 1, i + 1);
        if (HM.count(x))
        {
            res.push_back(tu[x]);
            solve(i + 1);
            res.pop_back();
        }
    }
}

int main()
{
    //freopen("z.inp", "r", stdin);
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin >> n >> a >> m;
    reverse(a.begin(), a.end());
    Ta.init(a);
    for (int i = 1; i <= m; i++)
    {
        cin >> b;
        Tb.init(b);
        ll x = Tb.getHash(1, b.size());
        HM[x] = 1;
        tu[x] = b;
    }
    fill(nxt, nxt + N, -1);
    solve(0);
    return 0;
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e4 + 5;
int n, m, root, dp[N];
string s[10 * N], r;

struct trie
{
    int Leaf = 0, child[26] = {0};
};
vector<trie> T;

void addword(string s, int id)
{
    int x = root;
    for (int i = 0; i < s.size(); i++)
    {
        int w = tolower(s[i]) - 97;
        if (T[x].child[w] == 0)
            T[x].child[w] = T.size(), T.emplace_back();
        x = T[x].child[w];
    }
    T[x].Leaf = id;
}

int main()
{
    //freopen("z.inp", "r", stdin);
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    root = 0;
    T.emplace_back();

    cin >> n >> r;
    cin >> m;
    for (int i = 1; i <= m; i++)
    {
        cin >> s[i];
        addword(s[i], i);
    }
    r = "%" + r;
    dp[0] = 1;
    for (int i = 1; i <= n; i++)
    {
        int x = root;
        for (int j = i; j >= 1; j--)
        {
            if (T[x].child[r[j] - 'a'] == 0)
                break;
            x = T[x].child[r[j] - 'a'];
            if (T[x].Leaf && dp[j - 1])
            {
                dp[i] = T[x].Leaf;
                break;
            }
        }
    }
    for (int i = 1; i <= n; i++)
        if (dp[i])
            cout << s[dp[i]] << " ";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
/*---define tricks---*/
#define ALL(v) v.begin(),v.end()
#define UN(v) sort(ALL(v)),v.erase(unique(ALL(v)),v.end())
#define FILL(x,y) memset(x,y,sizeof(x))
#define EACH(v,it) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define FIO ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define revsort(b,e) sort(b,e),reverse(b,e)
/*---define types---*/
typedef long long ll;
typedef unsigned int uint;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<pii> vii;
/*---define variables---*/
const int inf=(1<<29);
int n,k;
string rhyme[2505][4];
int sch[4];
/*---define function---*/

string sub(string s,int k)
{
	string res="";
	int t=k;
	for(int i=s.size()-1;i>=0;--i)
	{
		res=s[i]+res;
		if(s[i]=='a'||s[i]=='e'||s[i]=='i'||s[i]=='o'||s[i]=='u')
		{
			--t;
			if(t==0)
			{
				break;
			}
		}
	}
	if(t!=0)
	{
		return "";
	}
	return res;
}

/*---main code---*/
int main()
{
	FIO;
	cin>>n>>k;
	bool f=1;
	for(int i=0;i<n;++i)
	{
		for(int j=0;j<4;++j)
		{
			string s;
			cin>>s;
			rhyme[i][j]=sub(s,k);
			if(rhyme[i][j]=="")
			{
				f=0;
			}
		}
	}
	if(f==0)
	{
		cout<<"NO\n";
		exit(0);
	}
	for(int i=0;i<n;++i)
	{
		vi sc;
		int cnt=-1;
		map<string,int> mmp;
		for(int j=0;j<4;++j)
		{
			if(mmp.count(rhyme[i][j]))
			{
				sc.push_back(mmp[rhyme[i][j]]);
			}
			else
			{
				mmp[rhyme[i][j]]=++cnt;
				sc.push_back(cnt);
			}
		}
		string s;
		for(int j=0;j<4;++j)
		{
			s=s+char(sc[j]+'a');
		}
		if(s=="aaaa")
		{
			sch[0]++,sch[1]++,sch[2]++,sch[3]++;
		}
		else if(s=="aabb")
		{
			sch[1]++;
		}
		else if(s=="abab")
		{
			sch[2]++;
		}
		else if(s=="abba")
		{
			sch[3]++;
		}
	}
	int ans=100;
	for(int i=0;i<4;++i)
	{
		if(sch[i]==n)
		{
			ans=i;
			break;
		}
	}
	if(ans==0)
	{
		cout<<"aaaa\n";
	}
	else if(ans==1)
	{
		cout<<"aabb\n";
	}
	else if(ans==2)
	{
		cout<<"abab\n";
	}
	else if(ans==3)
	{
		cout<<"abba\n";
	}
	else
	{
		cout<<"NO\n";
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
/*---define tricks---*/
#define ALL(v) v.begin(),v.end()
#define UN(v) sort(ALL(v)),v.erase(unique(ALL(v)),v.end())
#define FILL(x,y) memset(x,y,sizeof(x))
#define EACH(v,it) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define FIO ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define revsort(b,e) sort(b,e),reverse(b,e)
/*---define types---*/
typedef long long ll;
typedef unsigned int uint;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<pii> vii;
/*---define variables---*/
const int inf=(1<<29);
int n,k;
string str[2505][4],rhy[2505];
int sch[4];
/*---define function---*/

string sub(string s,int k)//��׺
{
	string res="";
	int t=k;
	for(int i=s.size()-1;i>=0;--i)
	{
		res=s[i]+res;
		if(s[i]=='a'||s[i]=='e'||s[i]=='i'||s[i]=='o'||s[i]=='u')
		{
			--t;
			if(t==0)
			{
				break;
			}
		}
	}
	if(t!=0)
	{
		return "";
	}
	return res;
}

string find_rhy(int i)
{
	if(str[i][0]==str[i][1]&&str[i][1]==str[i][2]&&str[i][0]==str[i][3])
	{
		return "aaaa";
	}
	if(str[i][0]==str[i][1]&&str[i][2]==str[i][3])
	{
		return "aabb";
	}
	if(str[i][0]==str[i][2]&&str[i][1]==str[i][3])
	{
		return "abab";
	}
	if(str[i][0]==str[i][3]&&str[i][1]==str[i][2])
	{
		return "abba";
	}
	return "NO";
}

/*---main code---*/
int main()
{
	FIO;
	cin>>n>>k;
	bool f=1;
/*---------ȡ��׺------------*/
	for(int i=0;i<n;++i)
	{
		for(int j=0;j<4;++j)
		{
			string s;
			cin>>s;
			str[i][j]=sub(s,k);
			if(str[i][j]=="")
			{
				f=0;
			}
		}
	}
	if(f==0)
	{
		cout<<"NO\n";
		exit(0);
	}
/*---------������---------*/
	for(int i=0;i<n;++i)
	{
		rhy[i]=find_rhy(i);
	}
/*----------�ϲ�---------*/
	string ans=rhy[0];
	for(int i=1;i<n;++i)
	{
		if(ans=="aaaa")
		{
			ans=rhy[i];
		}
		else if(ans==rhy[i]||rhy[i]=="aaaa")
		{
			;
		}
		else
		{
			ans="NO";
		}
	}
	cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
string str[4*2501],x,y;
int n,m,i,j,k,l,a,b;
bool check1()
{
    for(i=0;i<l;i++)
    {
        if(str[i].size()<k)
            return true;
    }
    return false;
}

bool check(int a,int b)
{
    if(str[a].substr(0,k)==str[b].substr(0,k))
        return true;
    return false;
}
int main()
{

    cin>>n>>k;
    l=4*n;
    getchar();
    for(i=0;i<l;i++)
    {
        getline(cin,x);
        for(j=0;x[j];j++)
        {
            if(x[j]=='a' || x[j]=='e' || x[j]=='i' || x[j]=='o' || x[j]=='u')
            {
                str[i]+=x[j];
            }
        }
    }
    if(check1())
    {
        cout<<"NO"<<endl;
        return 0;
    }
    /// CHECK AAAA
    int ck = 0;
    for(i=0;i<l;i+=4)
    {
        if(check(i,i+1) && check(i,i+2) && check(i,i+3))
        {
            ck++;
        }
        else
            break;
    }
    if(ck==n)
    {
        cout<<"aaaa"<<endl;
        return 0;
    }

    ///CHECK AABB
    ck=0;
    for(i=0;i<l;i+=4)
    {
        if(check(i,i+1) && check(i+2,i+3))
        {
            ck++;
        }
        else
            break;
    }
    if(ck==n)
    {
        cout<<"aabb"<<endl;
        return 0;
    }

    ///CHECK ABAB
    ck=0;
    for(i=0;i<l;i+=4)
    {
        if(check(i,i+2) && check(i+1,i+3))
        {
            ck++;
        }
        else
            break;
    }
    if(ck==n)
    {
        cout<<"aabb"<<endl;
        return 0;
    }

    ///CHECK ABBA
    ck=0;
    for(i=0;i<l;i+=4)
    {
        if(check(i,i+3) && check(i+1,i+2))
        {
            ck++;
        }
        else
            break;
    }
    if(ck==n)
    {
        cout<<"aabb"<<endl;
        return 0;
    }
    ///etokkhon poreo jodi na yes hoi taile r ki kobo?
    cout<<"NO"<<endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
string str[4*2501],x,y;
int n,m,i,j,k,l;
vector<int>v;
bool check(int a,int b,int c)
{
    //cout<<a<<" "<<b<<endl;
    //cout<<str[a].substr(0,c)<<" "<<str[b].substr(0,c)<<endl;
    if(str[a].substr(0,c)==str[b].substr(0,c))
        return true;
    return false;
}
int main()
{

    cin>>n>>k;
    l=4*n;
    getchar();
    int vl=0;
    for(i=0; i<l; i++)
    {
        getline(cin,x);
        int sz = x.size();
        j=sz-1;
        vl=0;
        for(; j>=0; j--)
        {
            str[i]+=x[j];
            if(x[j]=='a' || x[j]=='e' || x[j]=='i' || x[j]=='o' || x[j]=='u')
            {
                vl++;
            }
            if(vl==k)
            {
                v.push_back(sz-j);
                break;
            }
        }
        if(vl != k)
        {
            cout<<"NO"<<endl;
            return 0;
        }
        //cout<<i<<": "<<str[i]<<" "<<v[i]<<endl;
    }

    /// CHECK AAAA
    int ck = 0;
    for(i=0; i<l; i+=4)
    {
        if(v[i]==v[i+1] && v[i]==v[i+2] && v[i]==v[i+3])
        {
            if(check(i,i+1,v[i]) && check(i,i+2,v[i]) && check(i,i+3,v[i]))
            {
                ck++;
            }
            else
                break;
        }
        else
            break;
    }
    if(ck==n)
    {
        cout<<"aaaa"<<endl;
        return 0;
    }

    ///CHECK AABB
    ck=0;
    for(i=0; i<l; i+=4)
    {
        if(v[i]==v[i+1] && v[i+2]==v[i+3])
        {
            if(check(i,i+1,v[i]) && check(i+2,i+3,v[i+2]))
            {
                ck++;
            }
            else
                break;
        }
        else
            break;
    }
    if(ck==n)
    {
        cout<<"aabb"<<endl;
        return 0;
    }

    ///CHECK ABAB
    ck=0;
    for(i=0; i<l; i+=4)
    {
        if(v[i]==v[i+2] && v[i+1]==v[i+3])
        {
            if(check(i,i+2,v[i]) && check(i+1,i+3,v[i+1]))
            {
                ck++;
            }
            else
                break;
        }
        else
            break;
    }
    if(ck==n)
    {
        cout<<"abab"<<endl;
        return 0;
    }

    ///CHECK ABBA
    ck=0;
    for(i=0; i<l; i+=4)
    {

        if(v[i]==v[i+3] && v[i+2]==v[i+1])
        {
            if(check(i,i+3,v[i]) && check(i+2,i+1,v[i+2]))
            {
                ck++;
            }
            else
                break;
        }
        else
            break;
    }
    //cout<<ck<<endl;
    if(ck==n)
    {
        cout<<"abba"<<endl;
        return 0;
    }
    ///etokkhon poreo jodi na yes hoi taile r ki kobo?
    cout<<"NO"<<endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
int main(){
	int n,k,aaaa=0,aabb=0,abab=0,abba=0,cont;
	string s,a[4];
	cin>>n>>k;
	for(int i=0;i<n;i++){
		for(int j=0;j<4;j++){
			cin>>s;
			cont=0;
			for(int l=s.size()-1;l>=0;--l){
				if(s[l]=='a'||s[l]=='e'||s[l]=='i'||s[l]=='o'||s[l]=='u')cont++;
				if(cont==k){
					a[j]=s.substr(l);
					break;
				}
			}
		}
		if(a[0]==a[1]&&a[1]==a[2]&&a[2]==a[3])aaaa++;
		else if(a[0]==a[1]&&a[2]==a[3])aabb++;
		else if(a[0]==a[2]&&a[1]==a[3])abab++;
		else if(a[0]==a[3]&&a[1]==a[2])abba++;
		else{
			cout<<"NO";
			return 0;
		}
	}
	if((abab>0&&aabb>0)||(abab>0&&abba>0)||(abba>0&&aabb>0)){
		cout<<"NO";
		return 0;
	}
	else if(aabb>0)cout<<"aabb";
	else if(abab>0)cout<<"abab";
	else if(abba>0)cout<<"abba";
	else cout<<"aaaa";
}


#include <bits/stdc++.h>
using namespace std;
const string tp[4]={"aaaa","aabb","abab","abba"};
int n,m,k;
string w[10000];
int main()
{
cin>>n>>k;
int bad=0;
for(int i=0;i<n;i++){
	string s;
	cin>>s;
	w[i]="";
	int l=0;
	while(l<k&&sz(s)){
		char c=s[sz(s)-1];
		w[i]+=c;
		s.ease(sz(s)-1);
		if(c=='a'||c=='i'||c=='e'||c=='o'||c=='u')l++;
	}
	if(l<k)bad=1;
}
if(!bad)
for(int t=0;t<4;t++)
{
	int ok2=1;
	for(int i=0;i<n;i+=4){
		int ok=1;
		for(int p=0;p<4&&ok;p++)
		for(int q=p+1;q<4&&ok;q++)
		if(tp[t][p]==tp[t][p]&&w[i+p]!=w[i+q])
		ok=0;
		if(!ok)(ok2=0;break;)
	}
	if(ok2){
		cout<<tp[t]<<endl;
		re 0;
	}
}
cout<<"NO"<<endl;
return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n,m;
string ans;
bool f=false;
inline bool yuan(char c){return (c=='a'||c=='i'||c=='e'||c=='u'||c=='o');}
string change(string s)
{
	string res="";
	reverse(s.begin(),s.end());
	int ji=m;
	for(int i=0;i<s.size();i++)
	{
		res+=s[i];
		if(yuan(s[i]))ji--;
		if(ji==0)break;
	}
	return res;
}
inline bool check(string s)
{
	int ji=0;
	for(int i=0;i<s.size();i++)
		if(yuan(s[i]))
			ji++;
	return ji==m;
}
string push_set(string a,string b,string c,string d)
{
	a=change(a);
	b=change(b);
	c=change(c);
	d=change(d);
	if(!check(a)||!check(b)||!check(c)||!check(d))return "NO";
	string s;
	if(a==b&&b==c&&c==d)s="aaaa";
	else if(a==b&&c==d&&a!=d)s="aabb";
	else if(a==c&&b==d&&a!=d)s="abab";
	else if(a==d&&b==c&&a!=b)s="abba";
	else s="NO";
	return s;
}
int main()
{
	cin>>n>>m;
	for(int i=0;i<n;i++)
	{
		string a,b,c,d;
		cin>>a>>b>>c>>d;
		string s=push_set(a,b,c,d);
		if(s=="NO")
		{
			cout<<"NO\n";
			return 0;
		}
		if(!f)
		{
			ans=s;
			f=true;
		}
		else
		{
			if(ans!=s&&ans!="aaaa")
			{
				cout<<"NO\n";
				return 0;
			}
			ans=s;
		}
	}
	cout<<ans<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
string s[2550],ans;
int n,k;
int cnt=0;
bool flag[3];
int main(){
	cin>>n>>k;
	n*=4;
	for(int i=0;i<n;i++){
		cin>>s[i];
		cnt=0;
		for(int j=s[i].size();j>=0;j--){
			if(s[i][j]=='a'||s[i][j]=='e'||s[i][j]=='i'||s[i][j]=='o'||s[i][j]=='u'){
				cnt++;
				if(cnt==k){
					s[i]=s[i].substr(j,s[i].size()-j);
				}
			}
		}
	}
	memset(flag,1,sizeof(flag));
	for(int i=0;i<n;i+=4){
		if(s[i]!=s[i+1]||s[i+2]!=s[i+3]) flag[0]=false;
		if(s[i]!=s[i+2]||s[i+1]!=s[i+3]) flag[1]=false;
		if(s[i]!=s[i+3]||s[i+1]!=s[i+2]) flag[2]=false;
	}
	if(flag[0]&&flag[1]) ans="aaaa";
	else if(flag[0]) ans="aabb";
	else if(flag[1]) ans="abab";
	else if(flag[2]) ans="abba";
	else ans="NO";
	cout<<ans<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n,k;
int main() {
	freopen("lesson.in","r",stdin);
	freopen("lesson.out","w",stdout);
	cin>>n>>k;
	int ans=0;
	for(int i=0; i<n; i++) {
		string a[4];
		int rhyme=0;
		for(int j=0; j<4; j++) {
			string s;
			cin>>s;
			int cnt=0;
			for(int h=s.size()-1; h>=0; h--) {
				if(s[h]=='a'||s[h]=='e'||s[h]=='i'||s[h]=='o'||s[h]=='u') {
					cnt++;
					if(cnt==k) {
						a[j]=s.substr(h);
						break;
					}
				}
			}
			if(cnt<k) {
				cout<<"NO";
				return 0;
			}
		}
		if(a[0]==a[1]&&a[2]==a[3]&&a[0]==a[2]) rhyme=1;	//aaaa
		else if(a[0]==a[1]&&a[2]==a[3]&&a[0]!=a[2]) rhyme=2;	//aabb
		else if(a[0]==a[2]&&a[1]==a[3]&&a[0]!=a[1]) rhyme=3;	//abab
		else if(a[0]==a[3]&&a[2]==a[1]&&a[0]!=a[1]) rhyme=4;	//abba
		else {
			cout<<"NO";
			return 0;
		}
		if(i==0) ans=rhyme;
		else {
			if(ans!=rhyme&&ans!=1&&rhyme!=1) {
				cout<<"NO";
				return 0;
			} else if(ans=1) {
				ans=rhyme;
			}
		}
	}
	if(ans==1) cout<<"aaaa";
	if(ans==2) cout<<"aabb";
	if(ans==3) cout<<"abab";
	if(ans==4) cout<<"abba";
	fclose(stdin);
	fclose(stdout);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
inline bool yuan(char c){return (c=='a'||c=='o'||c=='e'||c=='i'||c=='u');}
string s,a[N];
int n,m;
int main()
{
	cin>>n>>m;
	for(int i=0;i<n*4;i++)
	{
		cin>>s;
		int cnt=0,ji=0;
		for(int j=s.size()-1;j>=0;j--)
		{
			ji++;
			if(yuan(s[j]))
				cnt++;
			if(cnt==m)break;
		}
		a[i]=s.substr(s.size()-ji,ji);
	}
	bool aabb,abba,abab;
	aabb=abba=abab=true;
	for(int i=0;i<n*4;i+=4)
	{
		aabb=(aabb&&a[i]==a[i+1]&&a[i+2]==a[i+3]);
		abba=(abba&&a[i]==a[i+3]&&a[i+1]==a[i+2]);
		abab=(abab&&a[i]==a[i+2]&&a[i+1]==a[i+3]);
	}
	if(aabb&&abba&&abab)cout<<"aaaa";
	else if(aabb)cout<<"aabb";
	else if(abba)cout<<"abba";
	else if(abab)cout<<"abab";
	else cout<<"NO\n";
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n,K;
string s[4];
bool isy(char c)
{
	if(c=='a'||c=='e'||c=='i'||c=='o'||c=='u')return 1;
	return 0;
}
bool ryime(int a,int b)
{
	int rk=K;
	for(int ai=s[a].size()-1,bi=s[b].size()-1;ai>=0,bi>=0;ai--,bi--)
	{
		if(s[a][ai]!=s[b][bi])
		{
			return false;
		}
		if(isy(s[a][ai]))
		{
			rk--;
		}
		if(rk==0)
		{
			return true;
		}
	}
	return false;
}
int zt[3000];
string o[4]={"aaaa","aabb","abab","abba"};
int main(){
	cin>>n>>K;
	for(int k=0;k<n;k++)
	{
		cin>>s[0]>>s[1]>>s[2]>>s[3];
		bool ab=ryime(0,1),cd=ryime(2,3),ad=ryime(0,3),bc=ryime(1,2),ac=ryime(0,2),bd=ryime(1,3);
		if(ab&&bc&&cd)zt[k]=0;
		else if(ab&&cd)zt[k]=1;
		else if(ac&&bd)zt[k]=2;
		else if(ad&&bc)zt[k]=3;
		else {
			for(int j=k+1;j<n;j++) cin>>s[0]>>s[1]>>s[2]>>s[3];
			cout<<"NO"<<endl;
			return 0;
		}
		if(!k)continue;
		if(!zt[k])
		{
			if(k)zt[k]=zt[k-1];
			continue;
		}
		if(zt[k-1]&&zt[k-1]!=zt[k])
		{
			for(int j=k+1;j<n;j++) cin>>s[0]>>s[1]>>s[2]>>s[3];
			cout<<"NO"<<endl;
			return 0;
		}
	}
	cout<<o[zt[n-1]];
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n,k;
bool rh[2500][4];
string eme[]={"aabb","abab","abba","aaaa"};
string s,vo="aeiou";
string c[4];
int main()
{
	cin>>n>>k;
	for(int i=0;i<n;i++)
	{
		bool novo=0;
		for(int v=0;v<4;v++)
		{
			cin>>s;
			int la=k;
			c[v]="";
			for(int l=s.size()-1;l>=0;l--)
			{
				if(vo.find(s[l])!=-1)la--;
				if(la==0)
				{
					c[v]=s.substr(l);
					break;
				}
			 }
			if(c[v]=="")
			{
				novo=1;
				break;
			}
		 }
		if(novo)continue;
		int rir=0;
		if(c[0]==c[1]&&c[2]==c[3])
		{
			rir++;
			rh[i][0]=1;
		 }
		if(c[0]==c[2]&&c[1]==c[3])
		{
			rir++;
			rh[i][1]=1;
		 }
		if(c[0]==c[3]&&c[1]==c[2])
		{
			rir++;
			rh[i][2]=1;
		 }
		if(rir>=2)rh[i][3]=1;
	}
	for(int i=3;i>=0;i--)
	{
		int lo;
		for(lo=0;lo<n;lo++)
		{
			if(!rh[lo][i])break;
		}
		if(lo==n)
		{
			cout<<eme[i];
			return 0;
		}
	}
	cout<<"NO";
	return 0;
}


/*
	Name: Literature Lesson
	Author: Jimmy2017
	Date: 04/22/18
*/
#include<iostream>
#include<string>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<pair<int,int>,int> piii;
typedef vector<int> vi;
const int INF=1e9+7;
string ans[2500];
int n,k;
string r[5];
string solve(string a,string b,string c,string d){
	if(a==b&&b==c&&c==d)
	return "aaaa";
	if(a==c&&b==d)
	return "abab";
	if(a==b&&c==d)
	return "aabb";
	if(a==d&&b==c)
	return "abba";
	return "NO";
}
string ans1;
int main(){
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=4;j++){
			string s;
			cin>>s;
			int check=k;
			string ry;
			int len=s.length()-1 ;
			while(check!=0){
				if(len<0){
					cout<<"NO";
					return 0;
				}
				ry+=s[len];
				if(s[len]=='a'||s[len]=='e'||s[len]=='i'||s[len]=='o'||s[len]=='u')
					check--;
				len--;
			}
			r[j]=ry;
		}
		ans[i]=solve(r[1],r[2],r[3],r[4]);
		if(i==1){
		ans1=ans[i];
	}
		else{
			if(ans1=="aaaa")
			ans1=ans[i];
			else if(ans[i]!=ans1&&ans[i]!="aaaa"){
				cout<<"NO"<<endl;
				return 0;
			}
		}
	}
	cout<<ans1;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
bool syll[256];
set<string> res;
void nope()
{
	cout<<"NO"<<endl;
	exit(0);
}
int main()
{
	syll['a']=syll['e']=syll['i']=syll['o']=syll['u']=true;
	int n,k;
	cin>>n>>k;
	for (int i=0;i<n;i++)
	{
		string suf[4];
		for (int j=0;j<4;j++)
		{
			string s;
			cin>>s;
			int p=s.length(),c=0;
			while (p>0&&c<k)
			{
				p--;
				if (syll[s[p]]) c++;
			}
			if (c<k) nope();
			suf[j]=s.substr(p);
		}
		if (suf[0]==suf[1])
			{
				if (suf[2]==suf[3])
				{
					if (suf[1]==suf[2]) res.insert("aaaa");
					else res.insert("aabb");
				}
				else nope();
			}
			else if (suf[0]==suf[2])
			{
				if (suf[1]==suf[3]) res.insert("abab");
				else nope();
			}
			else if (suf[0]==suf[3]&&suf[1]==suf[2]) res.insert("abba");
			else nope();
	}
	if (res.size()>1)
	{
		if (res.size()==2&&*res.begin()=="aaaa") res.erase(res.begin());
		else nope();
	}
	if (res.size()<1) exit(321);
	cout<<*res.begin()<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n,m;
set<string>st;
string ans;
bool f=false;
inline bool yuan(char c){return (c=='a'||c=='i'||c=='e'||c=='u'||c=='o');}
string change(string s)
{
	string res="";
	reverse(s.begin(),s.end());
	int ji=m;
	for(int i=0;i<s.size();i++)
	{
		res+=s[i];
		if(yuan(s[i]))ji--;
		if(ji==0)break;
	}
	return res;
}
string push_set(string a,string b,string c,string d)
{
	a=change(a);
	b=change(b);
	c=change(c);
	d=change(d);
	string s;
	if(a==b&&b==c&&c==d)s="aaaa";
	else if(a==b&&c==d&&a!=d)s="aabb";
	else if(a==c&&b==d&&a!=d)s="abab";
	else if(a==d&&b==c&&a!=b)s="abba";
	else s="NO";
	return s;
}
int main()
{
	cin>>n>>m;
	for(int i=0;i<n;i++)
	{
		string a,b,c,d;
		cin>>a>>b>>c>>d;
		string s=push_set(a,b,c,d);
		if(!f)
		{
			ans=s;
			f=true;
		}
		else
		{
			if((ans!=s&&ans!="aaaa")||s=="NO")
			{
				cout<<"NO\n";
				return 0;
			}
			ans=s;
		}
	}
	cout<<ans<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

int n, k;

string judge(string s[]){
	string at[5];
	int pos, k1=k;
	for(int i=1; i<=4; i++){
		pos = s[i].size()-1;
		while(k1!=0 && pos!=0){
			if(s[i][pos]=='a' || s[i][pos]=='e' || s[i][pos]=='i' || s[i][pos]=='o' || s[i][pos]=='u') k1--;
			pos--;
		}
		if(k1!=0) return "NO";
		at[i] = s[i].substr(pos, s[i].size()-pos);
	}
	int a[5]={2, 2, 2, 2, 2};
	for(int i=1; i<=4; i++)
	   for(int j=i+1; j<=4; j++)
	      if(at[i]==at[j]){
	      	  int f=0;
	      	  for(int k=1; k<=4; k++) if(a[k]==f){f++;break;}
	      	  if(f>1) return "NO";
	      	  a[i] = f;a[j] = f;
		  }
	string ans="";
	for(int i=1; i<=4; i++) ans += (char)(a[i]+'a');
	return ans;
}

int main(){
	cin >> n >> k;
	string a[n+1][5], b[n+1];
	string ti[5];
	for(int i=1; i<=n; i++)
	   for(int j=1; j<=4; j++)
	      cin >> a[i][j];
	for(int i=1; i<=n; i++){
		for(int j=1; j<=4; j++)
		   ti[j] = a[i][j];
		if(judge(ti)=="NO"){
			cout << "NO";
			return 0;
		}
		b[i] = judge(ti);
	}
	int sj=0;
	string answer;
	for(int i=1; i<=n; i++){
		if(b[i]!="aaaa"){
			answer = b[i];
			sj++;
	    }
	}
	if(sj>1) cout << "NO";
	else cout << answer;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int maxl=4;
set<string> res;
int n,k;
string suf[4];
bool syll[128];
void nope(){
    cout<<"NO\n";
    exit(0);
}
int main(){
    // freopen("testdata.in","r",stdin);
    syll['a']=syll['e']=syll['i']=syll['o']=syll['u']=true;
    cin>>n>>k;
    for(int i=0;i<n;i++){
        for(int j=0;j<maxl;j++){
            string str;
            cin>>str;
            int p=str.size(),c=0;
            while(c<k&&p>0){
                p--;
                if(syll[str[p]])c++;
            }
            if(c<k)nope();
            suf[j]=str.substr(p);
        }
        if(suf[0]==suf[1]){
            if(suf[2]==suf[3]){
                if(suf[2]==suf[3])res.insert("aaaa");
                else res.insert("aabb");
            }else nope();
        }else if(suf[0]==suf[2]){
            if(suf[1]==suf[3]){
                res.insert("abab");
            }else nope();
        }else if(suf[0]==suf[3]&&suf[1]==suf[2]){
            res.insert("abba");
        }else nope();
    }
    if(res.size()>1){
        if(res.size()==2&&*res.begin()=="aaaa")res.erase(res.begin());
        else nope();
    }
    cout<<*res.begin()<<endl;
    return 0;
}


// luogu-judger-enable-o2
#include <bits/stdc++.h>
using namespace std;
const string tp[4]={"aaaa","aabb","abab","abba"};
const int N=1e4+10;
int n,k;
string w[N];
int main() {
    cin>>n>>k;
    n*=4;
    int bad=0;
    for(int i=0;i<n;i++) {
        string s;
        cin>>s;
        w[i]="";
        int l=0;
        while(l<k && s.size()) {
            char c=s[s.size()-1];
            w[i]+=c;
            s.erase(s.size()-1);
            if(c=='a' || c=='e' || c=='i' || c=='o' || c=='u') l++;
        }
        if(l<k) bad=1;
    }
    if(!bad) {
        for(int t=0;t<4;t++) {
            int ok2=1;
            for(int i=0;i<n;i+=4) {
                int ok=1;
                for(int p=0;p<4 && ok;p++) {
                    for(int q=p+1;q<4 && ok; q++) {
                        if(tp[t][p]==tp[t][q] && w[i+p]!=w[i+q]) {
                            ok=0;
                        }
                    }
                }
                if(!ok) {
                    ok2=0;
                    break;
                }
            }
            if(ok2) {
                cout<<tp[t]<<endl;
                system("pause");
                return 0;
            }
        }
    }
    cout<<"NO"<<endl;
    system("pause");
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n,m;
set<string>st;
string ans;
bool f=false;
inline bool yuan(char c){return (c=='a'||c=='i'||c=='e'||c=='u'||c=='o');}
string change(string s)
{
	string res="";
	reverse(s.begin(),s.end());
	int ji=m;
	for(int i=0;i<s.size();i++)
	{
		res+=s[i];
		if(yuan(s[i]))ji--;
		if(ji==0)break;
	}
	return res;
}
string push_set(string a,string b,string c,string d)
{
	a=change(a);
	b=change(b);
	c=change(c);
	d=change(d);
	string s;
	if(a==b&&b==c&&c==d)s="aaaa";
	else if(a==b&&c==d&&a!=d)s="aabb";
	else if(a==c&&b==d&&a!=d)s="abab";
	else if(a==d&&b==c&&a!=b)s="abba";
	else s="NO";
	return s;
}
int main()
{
	cin>>n>>m;
	for(int i=0;i<n;i++)
	{
		string a,b,c,d;
		cin>>a>>b>>c>>d;
		string s=push_set(a,b,c,d);
		if(!f)
		{
			ans=s;
			f=true;
		}
		else
		{
			if((ans!=s&&ans!="aaaa")||ans=="NO")
			{
				cout<<"NO\n";
				return 0;
			}
			ans=s;
		}
	}
	cout<<ans<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n,k;
string ans[3000];
char a[10]={'a','e','i','o','u'};
int func(string s,string p){
	int k2=k;
	int x=-1;
	for(int i=s.size()-1;i>=0;i--)
		for(int j=0;j<5;j++)
			if(s[i]==a[j]){
				k2--;
				if(k2==0){
					x=i;
					break;
				}
			}
	if(x!=-1){
		string s2=s.substr(s.size()-x-1,x+1);
		string p2=p.substr(p.size()-x-1,x+1);
		if(s2==p2)
			return 1;
		else
			return 0;
	}
	else
		return 0;
}
int main()
{
	cin>>n>>k;
	for(int i=0;i<n;i++){
		string a,b,c,d;
		cin>>a>>b>>c>>d;
		if(func(a,b)&&func(b,c)&&func(c,d))
			ans[i]="aaaa";
		else
			if(func(a,b)&&func(c,d))
				ans[i]="aabb";
			else
				if(func(a,c)&&func(b,d))
					ans[i]="abab";
				else
					if(func(a,d)&&func(b,c))
						ans[i]="abba";
					else
						ans[i]="NO";
	}
	string cnt="";
	for(int i=0;i<n;i++)
		if(ans[i]=="NO"){
			cout<<ans[i]<<endl;
			return 0;
		}
	for(int i=0;i<n;i++)
		if(ans[i]!="aaaa"){
			cnt=ans[i];
			break;
		}
	if(cnt==""){
		cout<<"aaaa"<<endl;
		return 0;
	}
	for(int i=0;i<n;i++)
		if(ans[i]!=cnt&&ans[i]!="aaaa"){
			cout<<"NO"<<endl;
			return 0;
		}
	cout<<cnt<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n,k;
string ans[3000];
char a[10]={'a','e','i','o','u'};
int func(string s,string p){
	int k2=k;
	int x=-1;
	for(int i=s.size()-1;i>=0;i--)
		for(int j=0;j<5;j++)
			if(s[i]==a[j]){
				k2--;
				if(k2==0){
					x=i;
					break;
				}
			}
	if(x!=-1&&(s.size()-x)<p.size()){
		x=s.size()-x;
		string s2=s.substr(s.size()-x,x);
		string p2=p.substr(p.size()-x,x);
		if(s2==p2)
			return 1;
		else
			return 0;
	}
	else
		return 0;
}
int main()
{
	cin>>n>>k;
	for(int i=0;i<n;i++){
		string a,b,c,d;
		cin>>a>>b>>c>>d;
		if(func(a,b)&&func(b,c)&&func(c,d))
			ans[i]="aaaa";
		else
			if(func(a,b)&&func(c,d))
				ans[i]="aabb";
			else
				if(func(a,c)&&func(b,d))
					ans[i]="abab";
				else
					if(func(a,d)&&func(b,c))
						ans[i]="abba";
					else
						ans[i]="NO";
	}
	string cnt="";
	for(int i=0;i<n;i++)
		if(ans[i]=="NO"){
			cout<<ans[i]<<endl;
			return 0;
		}
	for(int i=0;i<n;i++)
		if(ans[i]!="aaaa"){
			cnt=ans[i];
			break;
		}
	if(cnt==""){
		cout<<"aaaa"<<endl;
		return 0;
	}
	for(int i=0;i<n;i++)
		if(ans[i]!=cnt&&ans[i]!="aaaa"){
			cout<<"NO"<<endl;
			return 0;
		}
	cout<<cnt<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n,k;
string ans[3000];
char a[10]={'a','e','i','o','u'};
int func(string s,string p){
	int k2=k;
	int x=-1;
	for(int i=s.size()-1;i>=0;i--)
		for(int j=0;j<5;j++)
			if(s[i]==a[j]){
				k2--;
				if(k2==0){
					x=i;
					break;
				}
			}
	if(x!=-1){
		x=s.size()-x;
		string s2=s.substr(s.size()-x,x);
		string p2=p.substr(p.size()-x,x);
		if(s2==p2)
			return 1;
		else
			return 0;
	}
	else
		return 0;
}
int main()
{
	cin>>n>>k;
	for(int i=0;i<n;i++){
		string a,b,c,d;
		cin>>a>>b>>c>>d;
		if(func(a,b)&&func(b,c)&&func(c,d))
			ans[i]="aaaa";
		else
			if(func(a,b)&&func(c,d))
				ans[i]="aabb";
			else
				if(func(a,c)&&func(b,d))
					ans[i]="abab";
				else
					if(func(a,d)&&func(b,c))
						ans[i]="abba";
					else
						ans[i]="NO";
	}
	string cnt="";
	for(int i=0;i<n;i++)
		if(ans[i]=="NO"){
			cout<<ans[i]<<endl;
			return 0;
		}
	for(int i=0;i<n;i++)
		if(ans[i]!="aaaa"){
			cnt=ans[i];
			break;
		}
	if(cnt==""){
		cout<<"aaaa"<<endl;
		return 0;
	}
	for(int i=0;i<n;i++)
		if(ans[i]!=cnt&&ans[i]!="aaaa"){
			cout<<"NO"<<endl;
			return 0;
		}
	cout<<cnt<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n,k;
string ans[3000];
char a[10]={'a','e','i','o','u'};
int func(string s,string p){
	int k2=k;
	int x;
	for(int i=s.size()-1;i>=0;i--)
		for(int j=0;j<5;j++)
			if(s[i]==a[j]){
				k2--;
				if(k2==0){
					x=i;
					break;
				}
			}
	string s2=s.substr(s.size()-x,x);
	string p2=p.substr(p.size()-x,x);
	if(s2==p2)
		return 1;
	else
		return 0;
}
int main()
{
	cin>>n>>k;
	for(int i=0;i<n;i++){
		string a,b,c,d;
		cin>>a>>b>>c>>d;
		if(func(a,b)&&func(b,c)&&func(c,d))
			ans[i]="aaaa";
		else
			if(func(a,b)&&func(c,d))
				ans[i]="aabb";
			else
				if(func(a,c)&&func(b,d))
					ans[i]="abab";
				else
					if(func(a,d)&&func(b,c))
						ans[i]="abba";
					else
						ans[i]="NO";
	}
	string cnt="";
	for(int i=0;i<n;i++)
		if(ans[i]=="NO"){
			cout<<ans[i]<<endl;
			return 0;
		}
	for(int i=0;i<n;i++)
		if(ans[i]!="aaaa"){
			cnt=ans[i];
			break;
		}
	if(cnt==""){
		cout<<"aaaa"<<endl;
		return 0;
	}
	for(int i=0;i<n;i++)
		if(ans[i]!=cnt&&ans[i]!="aaaa"){
			cout<<"NO"<<endl;
			return 0;
		}
	cout<<cnt<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n,k;
string ans[3000];
char a[10]={'a','e','i','o','u'};
int func(string s,string p){
	int k2=k;
	int x=-1;
	for(int i=s.size()-1;i>=0;i--)
		for(int j=0;j<5;j++)
			if(s[i]==a[j]){
				k2--;
				if(k2==0){
					x=i;
					break;
				}
			}
	if(x!=-1&&(s.size()-x)<=p.size()){
		x=s.size()-x;
		string s2=s.substr(s.size()-x,x);
		string p2=p.substr(p.size()-x,x);
		if(s2==p2)
			return 1;
		else
			return 0;
	}
	else
		return 0;
}
int main()
{
	cin>>n>>k;
	for(int i=0;i<n;i++){
		string a,b,c,d;
		cin>>a>>b>>c>>d;
		if(func(a,b)&&func(b,c)&&func(c,d))
			ans[i]="aaaa";
		else
			if(func(a,b)&&func(c,d))
				ans[i]="aabb";
			else
				if(func(a,c)&&func(b,d))
					ans[i]="abab";
				else
					if(func(a,d)&&func(b,c))
						ans[i]="abba";
					else
						ans[i]="NO";
	}
	string cnt="";
	for(int i=0;i<n;i++)
		if(ans[i]=="NO"){
			cout<<ans[i]<<endl;
			return 0;
		}
	for(int i=0;i<n;i++)
		if(ans[i]!="aaaa"){
			cnt=ans[i];
			break;
		}
	if(cnt==""){
		cout<<"aaaa"<<endl;
		return 0;
	}
	for(int i=0;i<n;i++)
		if(ans[i]!=cnt&&ans[i]!="aaaa"){
			cout<<"NO"<<endl;
			return 0;
		}
	cout<<cnt<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n,k;
string s[4],ans="aaaa";
string qua;
char vowel[5]={'a','e','i','o','u'};
bool isVowel(char x){
	for(int i=0;i<5;i++){
		if(vowel[i]==x) return true;
	}
	return false;
}
string rhyme(){
	string ret="abbb";
	string a,b;
	int mc=0,mi=0;
	int cnt=0,p=s[0].length()-1;
	while(cnt!=k&&p>=0){
		a+=s[0][p];
		if(isVowel(s[0][p])) cnt++;
		p--;
	}
	if(cnt!=k) return ret;
	for(int i=1;i<4;i++){
		cnt=0,p=s[i].length()-1;
		while(cnt!=k&&p>=0){
			b+=s[i][p];
			if(isVowel(s[i][p])) cnt++;
			p--;
		}
		if(cnt!=k) continue;
		if(a==b){
			mc++;
			mi=i;
		}
	}
	if(mc==1){
		ret[mi]='a';
	}
	else if(mc==3){
		ret="aaaa";
	}
	return ret;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		for(int j=0;j<4;j++) cin>>s[j];
		qua=rhyme();
		if(ans!=qua){
			if(ans=="aaaa") ans=qua;
			else if(qua=="aaaa") continue;
			else{
				cout<<"NO\n";
				return 0;
			}
		}
	}
	cout<<ans<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n,k;
string s[4],ans="aaaa";
string qua;
char vowel[5]={'a','e','i','o','u'};
bool isVowel(char x){
	for(int i=0;i<5;i++){
		if(vowel[i]==x) return true;
	}
	return false;
}
string rhyme(){
	string ret="abbb";
	string a,b;
	int mc=0,mi=0;
	int cnt=0,p=s[0].length()-1;
	while(cnt!=k&&p>=0){
		a+=s[0][p];
		if(isVowel(s[0][p])) cnt++;
		p--;
	}
	if(cnt!=k) return ret;
	for(int i=1;i<4;i++){
		cnt=0,p=s[i].length()-1;
		while(cnt!=k&&p>=0){
			b+=s[i][p];
			if(isVowel(s[i][p])) cnt++;
			p--;
		}
		if(cnt!=k) continue;
		if(a==b){
			mc++;
			mi=i;
		}
	}
	if(mc==1){
		ret[mi]='a';
	}
	else if(mc==3){
		ret="aaaa";
	}
	return ret;
}
int main(){
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		for(int j=0;j<4;j++) cin>>s[j];
		qua=rhyme();
		if(ans!=qua){
			if(ans=="aaaa") ans=qua;
			else if(qua=="aaaa") continue;
			else{
				cout<<"NO\n";
				return 0;
			}
		}
	}
	cout<<ans<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n,k;
string s[4];
string ans="aaaa";
string tmp;
char vowel[5]={'a','e','i','o','u'};
bool flag;
void input(){
	for(int i=0;i<4;i++) cin>>s[i];
}
bool isVowel(char x){
	for(int i=0;i<5;i++){
		if(x==vowel[i]) return true;
	}
	return false;
}
void fix(int x){
	int cnt=0,p=s[x].length()-1;
	while(p>=0){
		if(isVowel(s[x][p])) cnt++;
		if(cnt==k){
			s[x]=s[x].substr(p);
		}
		p--;
	}
	if(cnt<k) flag=false;
}
void judge(){
	if(!flag) tmp="NO";
	else if(s[0]==s[1]&&s[1]==s[2]&&s[2]==s[3]) tmp="aaaa";
	else if(s[0]==s[1]&&s[2]==s[3]) tmp="aabb";
	else if(s[0]==s[2]&&s[1]==s[3]) tmp="abab";
	else if(s[0]==s[3]&&s[1]==s[2]) tmp="abba";
	else tmp="NO";
}
void update(){
	if(ans=="aaaa") ans=tmp;
	else if(tmp=="aaaa"||ans==tmp);
	else ans="NO";
}
void qua(){
	tmp="";
	flag=true;
	input();
	for(int i=0;i<4;i++) fix(i);
	judge();
	update();
}
int main(){
	ios::sync_with_stdio(false);
	cin>>n>>k;
	for(int i=1;i<=n;i++) qua();
	cout<<ans<<endl;
	return 0;
}