#pragma comment(linker, "/STACK:16777216")
#include <iostream>
#include <climits>
#include <fstream>
#include <cstring>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <iomanip>
#include <cstdio>
#include <ctime>
#include <functional>
#include <iterator>
#include <complex>
#include <queue>
#include <cassert>
#include <sstream>
#include <cstdlib>

#define PROBLEM_ID ""

using namespace std;

double pi = acos((double) -1);
const int MOD = 1000000007;
const int INF = 2147483647;
const long long LLONG_INF = 9223372036854775807LL;

int get_index(char a) {
    if ('a' <= a && a <= 'z') {
        return a - 'a';
    }
    else if ('A' <= a && a <= 'Z') {
        return 26 + (a - 'A');
    }
    else if ('0' <= a && a <= '9') {
        return 52 + (a - '0');
    }
    else {
        return -1;
    }
}

int get_char(int ind) {
    if (ind < 26)
        return 'a' + ind;
    if (ind < 52)
        return 'A' + (ind - 26);
    else if (ind < 62)
        return '0' + (ind - 52);
    return -1;
}

string get_chars_by_node(int node) {
    int a = node / 62;
    int b = node % 62;

    string str = "";
    str += get_char(a);
    str += get_char(b);
    return str;
}

int get_node_by_chars(char a, char b) {
    return get_index(a) * 62 + get_index(b);
}

vector<int> find_euler_path(vector<vector<int>>& graph, int n, vector<int>& deg_input, vector<int>& deg_output) {
    int v1 = -1, v2 = -1;
    bool bad = false;
    for (int i = 0; i < n; i++) {
        if (deg_output[i] == deg_input[i] + 1)
            if (v1 == -1)
                v1 = i;
            else
                bad = true;
        else if (deg_output[i] + 1 == deg_input[i])
            if (v2 == -1)
                v2 = i;
            else
                bad = true;
        else if (deg_output[i] != deg_input[i])
            bad = true;
    }

    if (v1 != -1)
        ++graph[v2][v1];

    int first = 0;
    while (!deg_output[first]) {
        first++;
    }

    int index_of_v1 = -1;
    vector<int> st;
    st.push_back (first);
    vector<bool> is_added;
    is_added.push_back (first == v2);
    vector<int> res;
    while (!st.empty()) {
        int v = st.back();
        bool added = is_added.back();
        int i;
        for (i = 0; i < n; i++)
            if (graph[v][i])
                break;

        if (i == n) {
            res.push_back(v);
            if (added) {
                index_of_v1 = res.size() - 1;
                //index_of_v2 = res.size() - 1;
            }
            st.pop_back();
            is_added.pop_back();
        }
        else {
            --graph[v][i];
            //--graph[i][v];
            st.push_back(i);
            is_added.push_back(v == v2 && i == v1);
        }
    }

    if (v1 != -1) {
        vector<int> res2;
        for (size_t j=index_of_v1; j > 0; --j)
            res2.push_back (res[j]);
        for (size_t j=res.size() - 1; j > index_of_v1; --j)
            res2.push_back (res[j]);
        /*for (size_t j=index_of_v2+1; j<res.size(); ++j)*/
            //res2.push_back (res[j]);
        //for (size_t j=1; j<=index_of_v2; ++j)
            /*res2.push_back (res[j]);*/

        res = res2;
    }
    else {
        reverse(res.begin(), res.end());
    }

    for (int i=0; i<n; ++i)
        for (int j=0; j<n; ++j)
            if (graph[i][j])
                bad = true;

    if (bad)
        res.clear();

    return res;
}

void dfs1 (int v, vector<char>& used, vector<vector<int>>& g, vector<int>& order, int n) {
	used[v] = true;
	for (size_t i=0; i<n; ++i)
		if (g[v][i] && !used[i])
			dfs1 (i, used, g, order, n);
	order.push_back (v);
}

void dfs2 (int v, vector<char>& used, vector<vector<int>>& gr, vector<int>& component, int n) {
	used[v] = true;
	component.push_back (v);
	for (size_t i=0; i<gr[v].size(); ++i)
		if (!used[gr[v][i]])
			dfs2 (gr[v][i], used, gr, component, n);
}

int count_strong_connected_components(vector<vector<int>>& graph, vector<vector<int>>& graph_bidir, int n, vector<int>& deg_input, vector<int>& deg_output) {
    vector<char> used;
    vector<int> order, component;
    used.assign (n, false);
    for (int i=0; i<n; ++i) {
        if (!used[i])
			dfs1 (i, used, graph, order, n);
    }
    used.assign (n, false);
    int counter = 0;
    for (int i=0; i<n; ++i) {
		int v = order[n-1-i];
        if (!used[v]) {
			dfs2 (v, used, graph_bidir, component, n);
            if (component.size() > 1 || component.size() == 1 && graph[v][v]) {
                counter++;
            }
			component.clear();
		}
    }

    return counter;
}

int main() {
    ios_base::sync_with_stdio(0);
    clock_t tStart = clock();
    //freopen(PROBLEM_ID".in", "r", stdin);
    //freopen(PROBLEM_ID".out", "w", stdout);
    int tests = 1;
    for (int test = 1; test <= tests; test++) {
        int n;
        cin >> n;
        string str;

        int graph_size = 62*62;
        vector<vector<int>> graph(graph_size, vector<int>(graph_size));
        vector<vector<int>> graph_bidir(graph_size);
        for (int i = 0; i < n; i++) {
            cin >> str;
            int from = get_node_by_chars(str[0], str[1]);
            int to = get_node_by_chars(str[1], str[2]);
            //cout << from << " " << to << endl;
            graph[from][to]++;
            graph_bidir[to].push_back(from);
            graph_bidir[from].push_back(to);
        }

        vector<int> deg_input(graph_size, 0), deg_output(graph_size, 0);
        for (int i = 0; i < graph_size; i++) {
            for (int j = 0; j < graph_size; j++) {
                deg_output[i] += graph[i][j];
                deg_input[j] += graph[i][j];
            }
        }

        bool bad = false;
        int number_of_components = count_strong_connected_components(graph, graph_bidir, graph_size, deg_input, deg_output);
        if (number_of_components != 1) {
            bad = true;
        }

        vector<int> euler_path;
        if (!bad) {
            euler_path = find_euler_path(graph, graph_size, deg_input, deg_output);
        }

        if (bad || euler_path.size() == 0) {
            cout << "NO" << endl;
        }
        else {
            cout << "YES" << endl;
            string res = "";
            for (int i = 0; i < euler_path.size(); i++) {
                string chars = get_chars_by_node(euler_path[i]);

                if (i == 0) {
                    res += chars;
                }
                else {
                    res += chars[1];
                }
            }

            cout << res << endl;
        }
    }
    //printf("Time taken: %.2fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
}


#pragma comment(linker, "/STACK:16777216")
#include <iostream>
#include <climits>
#include <fstream>
#include <cstring>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <iomanip>
#include <cstdio>
#include <ctime>
#include <functional>
#include <iterator>
#include <complex>
#include <queue>
#include <cassert>
#include <sstream>
#include <cstdlib>

#define PROBLEM_ID ""

using namespace std;

double pi = acos((double) -1);
const int MOD = 1000000007;
const int INF = 2147483647;
const long long LLONG_INF = 9223372036854775807LL;

int get_index(char a) {
    if ('a' <= a && a <= 'z') {
        return a - 'a';
    }
    else if ('A' <= a && a <= 'Z') {
        return 26 + (a - 'A');
    }
    else if ('0' <= a && a <= '9') {
        return 52 + (a - '0');
    }
    else {
        return -1;
    }
}

int get_char(int ind) {
    if (ind < 26)
        return 'a' + ind;
    if (ind < 52)
        return 'A' + (ind - 26);
    else if (ind < 62)
        return '0' + (ind - 52);
    return -1;
}

string get_chars_by_node(int node) {
    int a = node / 62;
    int b = node % 62;

    string str = "";
    str += get_char(a);
    str += get_char(b);
    return str;
}

int get_node_by_chars(char a, char b) {
    return get_index(a) * 62 + get_index(b);
}

vector<int> find_euler_path(vector<vector<int>>& graph, int n, vector<int>& deg_input, vector<int>& deg_output) {
    int v1 = -1, v2 = -1;
    bool bad = false;
    for (int i = 0; i < n; i++) {
        if (deg_output[i] == deg_input[i] + 1)
            if (v1 == -1)
                v1 = i;
            else
                bad = true;
        else if (deg_output[i] + 1 == deg_input[i])
            if (v2 == -1)
                v2 = i;
            else
                bad = true;
        else if (deg_output[i] != deg_input[i])
            bad = true;
    }

    if (v1 != -1)
        ++graph[v2][v1];

    int first = 0;
    while (!deg_output[first]) {
        first++;
    }

    int index_of_v1 = -1;
    vector<int> st;
    st.push_back (first);
    vector<bool> is_added;
    is_added.push_back (first == v1);
    vector<int> res;
    while (!st.empty()) {
        int v = st.back();
        bool added = is_added.back();
        int i;
        for (i = 0; i < n; i++)
            if (graph[v][i])
                break;

        if (i == n) {
            res.push_back(v);
            if (added) {
                index_of_v1 = res.size() - 1;
                //index_of_v2 = res.size() - 1;
            }
            st.pop_back();
            is_added.pop_back();
        }
        else {
            --graph[v][i];
            //--graph[i][v];
            st.push_back(i);
            is_added.push_back(v == v2 && i == v1);
        }
    }

    if (v1 != -1) {
        vector<int> res2;
        for (size_t j=index_of_v1; j > 0; --j)
            res2.push_back (res[j]);
        for (size_t j=res.size() - 1; j > index_of_v1; --j)
            res2.push_back (res[j]);
        /*for (size_t j=index_of_v2+1; j<res.size(); ++j)*/
            //res2.push_back (res[j]);
        //for (size_t j=1; j<=index_of_v2; ++j)
            /*res2.push_back (res[j]);*/

        res = res2;
    }
    else {
        reverse(res.begin(), res.end());
    }

    for (int i=0; i<n; ++i)
        for (int j=0; j<n; ++j)
            if (graph[i][j])
                bad = true;

    if (bad)
        res.clear();

    return res;
}

void dfs1 (int v, vector<char>& used, vector<vector<int>>& g, vector<int>& order, int n) {
	used[v] = true;
	for (size_t i=0; i<n; ++i)
		if (g[v][i] && !used[i])
			dfs1 (i, used, g, order, n);
	order.push_back (v);
}

void dfs2 (int v, vector<char>& used, vector<vector<int>>& gr, vector<int>& component, int n) {
	used[v] = true;
	component.push_back (v);
	for (size_t i=0; i<gr[v].size(); ++i)
		if (!used[gr[v][i]])
			dfs2 (gr[v][i], used, gr, component, n);
}

int count_strong_connected_components(vector<vector<int>>& graph, vector<vector<int>>& graph_bidir, int n, vector<int>& deg_input, vector<int>& deg_output) {
    vector<char> used;
    vector<int> order, component;
    used.assign (n, false);
    for (int i=0; i<n; ++i) {
        if (!used[i])
			dfs1 (i, used, graph, order, n);
    }
    used.assign (n, false);
    int counter = 0;
    for (int i=0; i<n; ++i) {
		int v = order[n-1-i];
        if (!used[v]) {
			dfs2 (v, used, graph_bidir, component, n);
            if (component.size() > 1 || component.size() == 1 && graph[v][v]) {
                counter++;
            }
			component.clear();
		}
    }

    return counter;
}

int main() {
    ios_base::sync_with_stdio(0);
    clock_t tStart = clock();
    //freopen(PROBLEM_ID".in", "r", stdin);
    //freopen(PROBLEM_ID".out", "w", stdout);
    int tests = 1;
    for (int test = 1; test <= tests; test++) {
        int n;
        cin >> n;
        string str;

        int graph_size = 62*62;
        vector<vector<int>> graph(graph_size, vector<int>(graph_size));
        vector<vector<int>> graph_bidir(graph_size);
        for (int i = 0; i < n; i++) {
            cin >> str;
            int from = get_node_by_chars(str[0], str[1]);
            int to = get_node_by_chars(str[1], str[2]);
            //cout << from << " " << to << endl;
            graph[from][to]++;
            graph_bidir[to].push_back(from);
            graph_bidir[from].push_back(to);
        }

        vector<int> deg_input(graph_size, 0), deg_output(graph_size, 0);
        for (int i = 0; i < graph_size; i++) {
            for (int j = 0; j < graph_size; j++) {
                deg_output[i] += graph[i][j];
                deg_input[j] += graph[i][j];
            }
        }

        bool bad = false;
        int number_of_components = count_strong_connected_components(graph, graph_bidir, graph_size, deg_input, deg_output);
        if (number_of_components != 1) {
            bad = true;
        }

        vector<int> euler_path;
        if (!bad) {
            euler_path = find_euler_path(graph, graph_size, deg_input, deg_output);
        }

        if (bad || euler_path.size() == 0) {
            cout << "NO" << endl;
        }
        else {
            cout << "YES" << endl;
            string res = "";
            for (int i = 0; i < euler_path.size(); i++) {
                string chars = get_chars_by_node(euler_path[i]);

                if (i == 0) {
                    res += chars;
                }
                else {
                    res += chars[1];
                }
            }

            cout << res << endl;
        }
    }
    //printf("Time taken: %.2fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
}


#pragma comment(linker, "/STACK:16777216")
#include <iostream>
#include <climits>
#include <fstream>
#include <cstring>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <iomanip>
#include <cstdio>
#include <ctime>
#include <functional>
#include <iterator>
#include <complex>
#include <queue>
#include <cassert>
#include <sstream>
#include <cstdlib>

#define PROBLEM_ID ""

using namespace std;

double pi = acos((double) -1);
const int MOD = 1000000007;
const int INF = 2147483647;
const long long LLONG_INF = 9223372036854775807LL;

int get_index(char a) {
    if ('a' <= a && a <= 'z') {
        return a - 'a';
    }
    else if ('A' <= a && a <= 'Z') {
        return 26 + (a - 'A');
    }
    else if ('0' <= a && a <= '9') {
        return 52 + (a - '0');
    }
    else {
        return -1;
    }
}

int get_char(int ind) {
    if (ind < 26)
        return 'a' + ind;
    if (ind < 52)
        return 'A' + (ind - 26);
    else if (ind < 62)
        return '0' + (ind - 52);
    return -1;
}

string get_chars_by_node(int node) {
    int a = node / 62;
    int b = node % 62;

    string str = "";
    str += get_char(a);
    str += get_char(b);
    return str;
}

int get_node_by_chars(char a, char b) {
    return get_index(a) * 62 + get_index(b);
}

vector<int> find_euler_path(vector<vector<int>>& graph, int n, vector<int>& deg) {
    int first = 0;
    while (!deg[first]) {
        first++;
    }

    int v1 = -1, v2 = -1;
    bool bad = false;
    for (int i = 0; i < n; i++) {
        if (deg[i] & 1)
            if (v1 == -1)
                v1 = i;
            else if (v2 == -1)
                v2 = i;
            else
                bad = true;
    }

    if (v1 != -1)
        ++graph[v1][v2],  ++graph[v2][v1];

    vector<int> st;
    st.push_back (first);
    vector<int> res;
    while (!st.empty()) {
        int v = st.back();
        int i;
        for (i = 0; i < n; i++) {
            if (graph[v][i])
                break;
        }

        if (i == n) {
            res.push_back(v);
            st.pop_back();
        }
        else {
            --graph[v][i];
            //--graph[i][v];
            st.push_back(i);
        }
    }

    if (v1 != -1)
        for (size_t i=0; i+1<res.size(); ++i)
            if (res[i] == v1 && res[i+1] == v2 || res[i] == v2 && res[i+1] == v1)
            {
                vector<int> res2;
                for (size_t j=i+1; j<res.size(); ++j)
                    res2.push_back (res[j]);
                for (size_t j=1; j<=i; ++j)
                    res2.push_back (res[j]);
                res = res2;
                break;
            }

    for (int i=0; i<n; ++i)
        for (int j=0; j<n; ++j)
            if (graph[i][j])
                bad = true;

    if (bad)
        res.clear();

    return res;
}

void dfs1 (int v, vector<char>& used, vector<vector<int>>& g, vector<int>& order, int n) {
	used[v] = true;
	for (size_t i=0; i<n; ++i)
		if (g[v][i] && !used[i])
			dfs1 (i, used, g, order, n);
	order.push_back (v);
}

void dfs2 (int v, vector<char>& used, vector<vector<int>>& gr, vector<int>& component, int n) {
	used[v] = true;
	component.push_back (v);
	for (size_t i=0; i<n; ++i)
		if (gr[i][v] && !used[i])
			dfs2 (i, used, gr, component, n);
}

int count_strong_connected_components(vector<vector<int>>& graph, int n, vector<int>& deg) {
    vector<char> used;
    vector<int> order, component;
    used.assign (n, false);
    for (int i=0; i<n; ++i)
		if (!used[i])
			dfs1 (i, used, graph, order, n);
    used.assign (n, false);
    int counter = 0;
    for (int i=0; i<n; ++i) {
		int v = order[n-1-i];
        if (!used[v]) {
			dfs2 (v, used, graph, component, n);
            if (component.size() > 1)
                counter++;
            if (component.size() == 1) {
                if (deg[v] > 0)
                    counter++;
            }
			component.clear();
		}
    }

    return counter;
}

int main() {
    ios_base::sync_with_stdio(0);
    clock_t tStart = clock();
    //freopen(PROBLEM_ID".in", "r", stdin);
    //freopen(PROBLEM_ID".out", "w", stdout);
    int tests = 1;
    for (int test = 1; test <= tests; test++) {
        int n;
        cin >> n;
        string str;

        int graph_size = 62*62;
        vector<vector<int>> graph(graph_size, vector<int>(graph_size));
        //vector<vector<int>> graph_reversed(graph_size, vector<int>(graph_size));
        for (int i = 0; i < n; i++) {
            cin >> str;
            int from = get_node_by_chars(str[0], str[1]);
            int to = get_node_by_chars(str[1], str[2]);
            graph[from][to]++;
            //graph_reversed[to][from]++;
        }

        vector<int> deg(graph_size);
        for (int i = 0; i < graph_size; i++) {
            for (int j = 0; j < graph_size; j++) {
                deg[i] += graph[i][j];
                deg[j] += graph[i][j];
            }
        }

        bool bad = false;
        int number_of_components = count_strong_connected_components(graph, graph_size, deg);
        if (number_of_components != 1) {
            bad = true;
        }

        vector<int> euler_path;
        if (!bad) {
            euler_path = find_euler_path(graph, graph_size, deg);
        }

        if (bad || euler_path.size() == 0) {
            cout << "NO" << endl;
        }
        else {
            cout << "YES" << endl;
            string res = "";
            for (int i = 0; i < euler_path.size(); i++) {
                string chars = get_chars_by_node(euler_path[i]);

                if (i == 0) {
                    res += chars;
                }
                else {
                    res += chars[1];
                }
            }

            cout << res << endl;
        }
    }
    //printf("Time taken: %.2fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
}


#pragma comment(linker, "/STACK:16777216")
#include <iostream>
#include <climits>
#include <fstream>
#include <cstring>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <iomanip>
#include <cstdio>
#include <ctime>
#include <functional>
#include <iterator>
#include <complex>
#include <queue>
#include <cassert>
#include <sstream>
#include <cstdlib>

#define PROBLEM_ID ""

using namespace std;

double pi = acos((double) -1);
const int MOD = 1000000007;
const int INF = 2147483647;
const long long LLONG_INF = 9223372036854775807LL;

int get_index(char a) {
    if ('a' <= a && a <= 'z') {
        return a - 'a';
    }
    else if ('A' <= a && a <= 'Z') {
        return 26 + (a - 'A');
    }
    else if ('0' <= a && a <= '9') {
        return 52 + (a - '0');
    }
    else {
        return -1;
    }
}

int get_char(int ind) {
    if (ind < 26)
        return 'a' + ind;
    if (ind < 52)
        return 'A' + (ind - 26);
    else if (ind < 62)
        return '0' + (ind - 52);
    return -1;
}

string get_chars_by_node(int node) {
    int a = node / 62;
    int b = node % 62;

    string str = "";
    str += get_char(a);
    str += get_char(b);
    return str;
}

int get_node_by_chars(char a, char b) {
    return get_index(a) * 62 + get_index(b);
}

vector<int> find_euler_path(vector<vector<int>>& graph, int n, vector<int>& deg_input, vector<int>& deg_output) {
    int v1 = -1, v2 = -1;
    bool bad = false;
    for (int i = 0; i < n; i++) {
        if (deg_output[i] == deg_input[i] + 1)
            if (v1 == -1)
                v1 = i;
            else
                bad = true;
        else if (deg_output[i] + 1 == deg_input[i])
            if (v2 == -1)
                v2 = i;
            else
                bad = true;
        else if (deg_output[i] != deg_input[i])
            bad = true;
    }

    if (v1 != -1)
        ++graph[v2][v1];

    int first = 0;
    while (!deg_output[first]) {
        first++;
    }

    int index_of_v1 = -1;
    vector<int> st;
    st.push_back (first);
    vector<bool> is_added;
    is_added.push_back (false);
    vector<int> res;
    while (!st.empty()) {
        int v = st.back();
        bool added = is_added.back();
        int i;
        for (i = 0; i < n; i++)
            if (graph[v][i])
                break;

        if (i == n) {
            res.push_back(v);
            if (added) {
                index_of_v1 = res.size() - 1;
                //index_of_v2 = res.size() - 1;
            }
            st.pop_back();
            is_added.pop_back();
        }
        else {
            --graph[v][i];
            //--graph[i][v];
            st.push_back(i);
            is_added.push_back(v == v2 && i == v1);
        }
    }

    if (v1 != -1) {
        vector<int> res2;
        for (size_t j=index_of_v1; j > 0; --j)
            res2.push_back (res[j]);
        for (size_t j=res.size() - 1; j > index_of_v1; --j)
            res2.push_back (res[j]);
        /*for (size_t j=index_of_v2+1; j<res.size(); ++j)*/
            //res2.push_back (res[j]);
        //for (size_t j=1; j<=index_of_v2; ++j)
            /*res2.push_back (res[j]);*/

        res = res2;
    }
    else {
        reverse(res.begin(), res.end());
    }

    for (int i=0; i<n; ++i)
        for (int j=0; j<n; ++j)
            if (graph[i][j])
                bad = true;

    if (bad)
        res.clear();

    return res;
}

void dfs1 (int v, vector<char>& used, vector<vector<int>>& g, vector<int>& order, int n) {
	used[v] = true;
	for (size_t i=0; i<n; ++i)
		if (g[v][i] && !used[i])
			dfs1 (i, used, g, order, n);
	order.push_back (v);
}

void dfs2 (int v, vector<char>& used, vector<vector<int>>& gr, vector<int>& component, int n) {
	used[v] = true;
	component.push_back (v);
	for (size_t i=0; i<gr[v].size(); ++i)
		if (!used[gr[v][i]])
			dfs2 (gr[v][i], used, gr, component, n);
}

int count_strong_connected_components(vector<vector<int>>& graph, vector<vector<int>>& graph_bidir, int n, vector<int>& deg_input, vector<int>& deg_output) {
    vector<char> used;
    vector<int> order, component;
    used.assign (n, false);
    for (int i=0; i<n; ++i) {
        if (!used[i])
			dfs1 (i, used, graph, order, n);
    }
    used.assign (n, false);
    int counter = 0;
    for (int i=0; i<n; ++i) {
		int v = order[n-1-i];
        if (!used[v]) {
			dfs2 (v, used, graph_bidir, component, n);
            if (component.size() > 1 || component.size() == 1 && graph[v][v]) {
                counter++;
            }
			component.clear();
		}
    }

    return counter;
}

int main() {
    ios_base::sync_with_stdio(0);
    clock_t tStart = clock();
    //freopen(PROBLEM_ID".in", "r", stdin);
    //freopen(PROBLEM_ID".out", "w", stdout);
    int tests = 1;
    for (int test = 1; test <= tests; test++) {
        int n;
        cin >> n;
        string str;

        int graph_size = 62*62;
        vector<vector<int>> graph(graph_size, vector<int>(graph_size));
        vector<vector<int>> graph_bidir(graph_size);
        for (int i = 0; i < n; i++) {
            cin >> str;
            int from = get_node_by_chars(str[0], str[1]);
            int to = get_node_by_chars(str[1], str[2]);
            //cout << from << " " << to << endl;
            graph[from][to]++;
            graph_bidir[to].push_back(from);
            graph_bidir[from].push_back(to);
        }

        vector<int> deg_input(graph_size, 0), deg_output(graph_size, 0);
        for (int i = 0; i < graph_size; i++) {
            for (int j = 0; j < graph_size; j++) {
                deg_output[i] += graph[i][j];
                deg_input[j] += graph[i][j];
            }
        }

        bool bad = false;
        int number_of_components = count_strong_connected_components(graph, graph_bidir, graph_size, deg_input, deg_output);
        if (number_of_components != 1) {
            bad = true;
        }

        vector<int> euler_path;
        if (!bad) {
            euler_path = find_euler_path(graph, graph_size, deg_input, deg_output);
        }

        if (bad || euler_path.size() == 0) {
            cout << "NO" << endl;
        }
        else {
            cout << "YES" << endl;
            string res = "";
            for (int i = 0; i < euler_path.size(); i++) {
                string chars = get_chars_by_node(euler_path[i]);

                if (i == 0) {
                    res += chars;
                }
                else {
                    res += chars[1];
                }
            }

            cout << res << endl;
        }
    }
    //printf("Time taken: %.2fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
}


#pragma comment(linker, "/STACK:16777216")
#include <iostream>
#include <climits>
#include <fstream>
#include <cstring>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <iomanip>
#include <cstdio>
#include <ctime>
#include <functional>
#include <iterator>
#include <complex>
#include <queue>
#include <cassert>
#include <sstream>
#include <cstdlib>

#define PROBLEM_ID ""

using namespace std;

double pi = acos((double) -1);
const int MOD = 1000000007;
const int INF = 2147483647;
const long long LLONG_INF = 9223372036854775807LL;

int get_index(char a) {
    if ('a' <= a && a <= 'z') {
        return a - 'a';
    }
    else if ('A' <= a && a <= 'Z') {
        return 26 + (a - 'A');
    }
    else if ('0' <= a && a <= '9') {
        return 52 + (a - '0');
    }
    else {
        return -1;
    }
}

int get_char(int ind) {
    if (ind < 26)
        return 'a' + ind;
    if (ind < 52)
        return 'A' + (ind - 26);
    else if (ind < 62)
        return '0' + (ind - 52);
    return -1;
}

string get_chars_by_node(int node) {
    int a = node / 62;
    int b = node % 62;

    string str = "";
    str += get_char(a);
    str += get_char(b);
    return str;
}

int get_node_by_chars(char a, char b) {
    return get_index(a) * 62 + get_index(b);
}

vector<int> find_euler_path(vector<vector<int>>& graph, int n, vector<int>& deg_input, vector<int>& deg_output) {
    int v1 = -1, v2 = -1;
    bool bad = false;
    for (int i = 0; i < n; i++) {
        if (deg_output[i] == deg_input[i] + 1)
            if (v1 == -1)
                v1 = i;
            else
                bad = true;
        else if (deg_output[i] + 1 == deg_input[i])
            if (v2 == -1)
                v2 = i;
            else
                bad = true;
        else if (deg_output[i] != deg_input[i])
            bad = true;
    }

    if (v1 != -1)
        ++graph[v2][v1];

    int first = 0;
    while (!deg_output[first]) {
        first++;
    }

    int index_of_v1 = -1;
    vector<int> st;
    st.push_back (first);
    vector<bool> is_added;
    is_added.push_back (first == v2);
    vector<int> res;
    while (!st.empty()) {
        int v = st.back();
        bool added = is_added.back();
        int i;
        for (i = 0; i < n; i++)
            if (graph[v][i])
                break;

        if (i == n) {
            res.push_back(v);
            if (added) {
                index_of_v1 = res.size() - 1;
                //index_of_v2 = res.size() - 1;
            }
            st.pop_back();
            is_added.pop_back();
        }
        else {
            --graph[v][i];
            //--graph[i][v];
            st.push_back(i);
            is_added.push_back(v == v2 && i == v1);
        }
    }

    if (v1 != -1) {
        vector<int> res2;
        for (size_t j=index_of_v1; j > 0; --j)
            res2.push_back (res[j]);
        for (size_t j=res.size() - 1; j > index_of_v1; --j)
            res2.push_back (res[j]);
        /*for (size_t j=index_of_v2+1; j<res.size(); ++j)*/
            //res2.push_back (res[j]);
        //for (size_t j=1; j<=index_of_v2; ++j)
            /*res2.push_back (res[j]);*/

        res = res2;
    }
    else {
        reverse(res.begin(), res.end());
    }

    for (int i=0; i<n; ++i)
        for (int j=0; j<n; ++j)
            if (graph[i][j])
                bad = true;

    if (bad)
        res.clear();

    return res;
}

void dfs1 (int v, vector<char>& used, vector<vector<int>>& g, vector<int>& order, int n) {
	used[v] = true;
	for (size_t i=0; i<n; ++i)
		if (g[v][i] && !used[i])
			dfs1 (i, used, g, order, n);
	order.push_back (v);
}

void dfs2 (int v, vector<char>& used, vector<vector<int>>& gr, vector<int>& component, int n) {
	used[v] = true;
	component.push_back (v);
	for (size_t i=0; i<gr[v].size(); ++i)
		if (!used[i])
			dfs2 (i, used, gr, component, n);
}

int count_strong_connected_components(vector<vector<int>>& graph, vector<vector<int>>& graph_bidir,int n, vector<int>& deg_input, vector<int>& deg_output) {
    vector<char> used;
    vector<int> order, component;
    used.assign (n, false);
    for (int i=0; i<n; ++i)
		if (!used[i])
			dfs1 (i, used, graph, order, n);
    used.assign (n, false);
    int counter = 0;
    for (int i=0; i<n; ++i) {
		int v = order[n-1-i];
        if (v == 1) {
            int gg = 1;
        }
        if (!used[v]) {
			dfs2 (v, used, graph_bidir, component, n);
            if (component.size() > 1)
                counter++;
            if (component.size() == 1) {
                bool add = graph[i][i];
                for (int j = 0; j < n; j++) {
                    if (i != j && graph[i][j]) {
                        add = false;
                        break;
                    }
                }

                if (add)
                    counter++;
            }
			component.clear();
		}
    }

    return counter;
}

int main() {
    ios_base::sync_with_stdio(0);
    clock_t tStart = clock();
    //freopen(PROBLEM_ID".in", "r", stdin);
    //freopen(PROBLEM_ID".out", "w", stdout);
    int tests = 1;
    for (int test = 1; test <= tests; test++) {
        int n;
        cin >> n;
        string str;

        int graph_size = 62*62;
        vector<vector<int>> graph(graph_size, vector<int>(graph_size));
        vector<vector<int>> graph_bidir(graph_size);
        for (int i = 0; i < n; i++) {
            cin >> str;
            int from = get_node_by_chars(str[0], str[1]);
            int to = get_node_by_chars(str[1], str[2]);
            graph[from][to]++;
            graph_bidir[to].push_back(from);
            graph_bidir[from].push_back(to);
        }

        vector<int> deg_input(graph_size, 0), deg_output(graph_size, 0);
        for (int i = 0; i < graph_size; i++) {
            for (int j = 0; j < graph_size; j++) {
                deg_output[i] += graph[i][j];
                deg_input[j] += graph[i][j];
            }
        }

        bool bad = false;
        int number_of_components = count_strong_connected_components(graph, graph_bidir, graph_size, deg_input, deg_output);
        if (number_of_components != 1) {
            bad = true;
        }

        vector<int> euler_path;
        if (!bad) {
            euler_path = find_euler_path(graph, graph_size, deg_input, deg_output);
        }

        if (bad || euler_path.size() == 0) {
            cout << "NO" << endl;
        }
        else {
            cout << "YES" << endl;
            string res = "";
            for (int i = 0; i < euler_path.size(); i++) {
                string chars = get_chars_by_node(euler_path[i]);

                if (i == 0) {
                    res += chars;
                }
                else {
                    res += chars[1];
                }
            }

            cout << res << endl;
        }
    }
    //printf("Time taken: %.2fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
}


#pragma comment(linker, "/STACK:16777216")
#include <iostream>
#include <climits>
#include <fstream>
#include <cstring>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <iomanip>
#include <cstdio>
#include <ctime>
#include <functional>
#include <iterator>
#include <complex>
#include <queue>
#include <cassert>
#include <sstream>
#include <cstdlib>

#define PROBLEM_ID ""

using namespace std;

double pi = acos((double) -1);
const int MOD = 1000000007;
const int INF = 2147483647;
const long long LLONG_INF = 9223372036854775807LL;

int get_index(char a) {
    if ('a' <= a && a <= 'z') {
        return a - 'a';
    }
    else if ('A' <= a && a <= 'Z') {
        return 26 + (a - 'A');
    }
    else if ('0' <= a && a <= '9') {
        return 52 + (a - '0');
    }
    else {
        return -1;
    }
}

int get_char(int ind) {
    if (ind < 26)
        return 'a' + ind;
    if (ind < 52)
        return 'A' + (ind - 26);
    else if (ind < 62)
        return '0' + (ind - 52);
    return -1;
}

string get_chars_by_node(int node) {
    int a = node / 62;
    int b = node % 62;

    string str = "";
    str += get_char(a);
    str += get_char(b);
    return str;
}

int get_node_by_chars(char a, char b) {
    return get_index(a) * 62 + get_index(b);
}

vector<int> find_euler_path(vector<vector<int>>& graph, int n, vector<int>& deg_input, vector<int>& deg_output) {
    int v1 = -1, v2 = -1;
    bool bad = false;
    for (int i = 0; i < n; i++) {
        if (deg_output[i] == deg_input[i] + 1)
            if (v1 == -1)
                v1 = i;
            else
                bad = true;
        else if (deg_output[i] + 1 == deg_input[i])
            if (v2 == -1)
                v2 = i;
            else
                bad = true;
        else if (deg_output[i] != deg_input[i])
            bad = true;
    }

    if (v1 != -1)
        ++graph[v2][v1];

    int first = 0;
    while (!deg_output[first]) {
        first++;
    }

    int index_of_v2 = -1;
    vector<int> st;
    st.push_back (first);
    vector<bool> is_added;
    is_added.push_back (first == v2);
    vector<int> res;
    while (!st.empty()) {
        int v = st.back();
        bool added = is_added.back();
        int i;
        for (i = 0; i < n; i++)
            if (graph[v][i])
                break;

        if (i == n) {
            res.push_back(v);
            if (added) {
                index_of_v2 = res.size() - 1;
            }
            st.pop_back();
            is_added.pop_back();
        }
        else {
            --graph[v][i];
            //--graph[i][v];
            st.push_back(i);
            is_added.push_back(i == v2 && v == v1);
        }
    }

    if (v1 != -1) {
        vector<int> res2;
        for (size_t j=index_of_v2; j<res.size(); ++j)
            res2.push_back (res[j]);
        for (size_t j=1; j<index_of_v2; ++j)
            res2.push_back (res[j]);
        /*for (size_t j=index_of_v2+1; j<res.size(); ++j)*/
            //res2.push_back (res[j]);
        //for (size_t j=1; j<=index_of_v2; ++j)
            /*res2.push_back (res[j]);*/

        res = res2;
    }
    reverse(res.begin(), res.end());

    for (int i=0; i<n; ++i)
        for (int j=0; j<n; ++j)
            if (graph[i][j])
                bad = true;

    if (bad)
        res.clear();

    return res;
}

void dfs1 (int v, vector<char>& used, vector<vector<int>>& g, vector<int>& order, int n) {
	used[v] = true;
	for (size_t i=0; i<n; ++i)
		if (g[v][i] && !used[i])
			dfs1 (i, used, g, order, n);
	order.push_back (v);
}

void dfs2 (int v, vector<char>& used, vector<vector<int>>& gr, vector<int>& component, int n) {
	used[v] = true;
	component.push_back (v);
	for (size_t i=0; i<n; ++i)
		if (gr[i][v] && !used[i])
			dfs2 (i, used, gr, component, n);
}

int count_strong_connected_components(vector<vector<int>>& graph, int n, vector<int>& deg_input, vector<int>& deg_output) {
    vector<char> used;
    vector<int> order, component;
    used.assign (n, false);
    for (int i=0; i<n; ++i)
		if (!used[i])
			dfs1 (i, used, graph, order, n);
    used.assign (n, false);
    int counter = 0;
    for (int i=0; i<n; ++i) {
		int v = order[n-1-i];
        if (!used[v]) {
			dfs2 (v, used, graph, component, n);
            if (component.size() > 1)
                counter++;
            if (component.size() == 1) {
                if (deg_output[v] > 0)
                    counter++;
            }
			component.clear();
		}
    }

    return counter;
}

int main() {
    ios_base::sync_with_stdio(0);
    clock_t tStart = clock();
    //freopen(PROBLEM_ID".in", "r", stdin);
    //freopen(PROBLEM_ID".out", "w", stdout);
    int tests = 1;
    for (int test = 1; test <= tests; test++) {
        int n;
        cin >> n;
        string str;

        int graph_size = 62*62;
        vector<vector<int>> graph(graph_size, vector<int>(graph_size));
        //vector<vector<int>> graph_reversed(graph_size, vector<int>(graph_size));
        for (int i = 0; i < n; i++) {
            cin >> str;
            int from = get_node_by_chars(str[0], str[1]);
            int to = get_node_by_chars(str[1], str[2]);
            graph[from][to]++;
            //graph_reversed[to][from]++;
        }

        vector<int> deg_input(graph_size, 0), deg_output(graph_size, 0);
        for (int i = 0; i < graph_size; i++) {
            for (int j = 0; j < graph_size; j++) {
                deg_output[i] += graph[i][j];
                deg_input[j] += graph[i][j];
            }
        }

        bool bad = false;
        int number_of_components = count_strong_connected_components(graph, graph_size, deg_input, deg_output);
        if (number_of_components != 1) {
            bad = true;
        }

        vector<int> euler_path;
        if (!bad) {
            euler_path = find_euler_path(graph, graph_size, deg_input, deg_output);
        }

        if (bad || euler_path.size() == 0) {
            cout << "NO" << endl;
        }
        else {
            cout << "YES" << endl;
            string res = "";
            for (int i = 0; i < euler_path.size(); i++) {
                string chars = get_chars_by_node(euler_path[i]);

                if (i == 0) {
                    res += chars;
                }
                else {
                    res += chars[1];
                }
            }

            cout << res << endl;
        }
    }
    //printf("Time taken: %.2fs\n", (double)(clock() - tStart)/CLOCKS_PER_SEC);
}


#include <bits/stdc++.h>
#define endl "\n"
#define FOR(x, y, z) for (int x = (y); x < (z); ++x)
#define FORR(x, y, z) for (int x = (y); x > (z); --x)
#define SORT(a) sort(a.begin(), a.end())
#define SORTR(a) sort(a.rbegin(), a.rend())
#define GET(a, n) for (int i = 0; i < n; ++i) cin >> a[i];
#define GETM(a, n, m) for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) cin >> a[i][j];
#define PRINTM(a, n, m) for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) cout << a[i][j] << " ";  cout << endl; };
#define PRINT(a, n) for (int i = 0; i < n; ++i) cout << a[i] << " ";
#define GETSUM(sum, n) sum = 0; for (int i = 0; i < n; ++i) { int tmp; cin >> tmp; sum += tmp; }
#define SUM(a, n, sum) sum = 0; for (int i = 0; i < n; ++i) { sum += a[i]; }
#define IT(a) a.begin(), a.end()
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef vector <int> VI;
typedef vector <vector <int>> VVI;
typedef pair <int, int> PII;
template <class T> typename T::value_type arr_sum(const T& v, int n) { typename T::value_type sum = 0; FOR(i, 0, n) sum += v[i]; return sum; }
struct Sync_stdio { Sync_stdio() { cin.tie(NULL); ios_base::sync_with_stdio(false); } } _sync_stdio;

vector <vector <PII>> in;
vector <vector <PII>> out;
vector <int> used;

void dfs(int t)
{
    //cout << t << endl;
    for (auto &i: out[t]) {
        if (i.second == 1) {
            continue;
        }
        i.second = 1;
        dfs(i.first);
    }
    used.push_back(t);
}

int main()
{
    int n;
    cin >> n;
    vector <string> v(n);
    GET(v, n);
    map <string, int> m;
    vector <string> p;
    FOR (i, 0, v.size()) {
        string s = v[i].substr(0, 2);
        if (m.find(s) == m.end()) {
            m[s] = p.size();
            p.push_back(s);
        }
        s = v[i].substr(1, 2);
        if (m.find(s) == m.end()) {
            m[s] = p.size();
            p.push_back(s);
        }
    }
    out.resize(p.size());
    in.resize(p.size());
    FOR (i, 0, v.size()) {
        int a = m[v[i].substr(0, 2)];
        int b = m[v[i].substr(1, 2)];
        out[a].push_back({b, 0});
        in[b].push_back({a, 0});
    }
    vector <int> odd(p.size());
    FOR (i, 0, p.size()) {
        odd[i] = out[i].size() - in[i].size();
    }
    int c0 = count(IT(odd), 0);
    int c1 = count(IT(odd), 1);
    if (c0 != odd.size() &&
(c0 != odd.size() - 2 || c1 != 1)) {
        cout << "NO" << endl;
        return 0;
    }
    int flag = 0;
    if (c0 == odd.size()) {
        dfs(0);
    } else {
        flag = 1;
        int first = find(IT(odd), 1) - odd.begin();
        int second = find(IT(odd), -1) - odd.begin();
        //in[first].push_back({second, 0});
        //out[second].push_back({first, 0});
        dfs(first);
    }
    reverse(IT(used));
    string ans = p[used[0]];
    FOR (i, 1, used.size()) {
        ans += p[used[i]][1];
    }
    //if (flag) {
       // ans.pop_back();
    //}
    if (ans.size() != n + 2) {
        cout << "NO";
        return 0;
    }
    cout << "YES" << endl;
    cout << ans;
}


#include <bits/stdc++.h>
#define endl "\n"
#define FOR(x, y, z) for (int x = (y); x < (z); ++x)
#define FORR(x, y, z) for (int x = (y); x > (z); --x)
#define SORT(a) sort(a.begin(), a.end())
#define SORTR(a) sort(a.rbegin(), a.rend())
#define GET(a, n) for (int i = 0; i < n; ++i) cin >> a[i];
#define GETM(a, n, m) for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) cin >> a[i][j];
#define PRINTM(a, n, m) for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) cout << a[i][j] << " ";  cout << endl; };
#define PRINT(a, n) for (int i = 0; i < n; ++i) cout << a[i] << " ";
#define GETSUM(sum, n) sum = 0; for (int i = 0; i < n; ++i) { int tmp; cin >> tmp; sum += tmp; }
#define SUM(a, n, sum) sum = 0; for (int i = 0; i < n; ++i) { sum += a[i]; }
#define IT(a) a.begin(), a.end()
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef vector <int> VI;
typedef vector <vector <int>> VVI;
typedef pair <int, int> PII;
template <class T> typename T::value_type arr_sum(const T& v, int n) { typename T::value_type sum = 0; FOR(i, 0, n) sum += v[i]; return sum; }
struct Sync_stdio { Sync_stdio() { cin.tie(NULL); ios_base::sync_with_stdio(false); } } _sync_stdio;

vector <vector <int>> in;
vector <vector <int>> out;
vector <int> used;
vector <int> start;

void dfs(int t)
{
    FOR(i, start[t], out[t].size()) {
        ++start[t];
        dfs(out[t][i]);
        i = max(i, start[t]);
    }
    used.push_back(t);
}

int main()
{
    int n;
    cin >> n;
    vector <string> v(n);
    GET(v, n);
    map <string, int> m;
    vector <string> p;
    FOR (i, 0, v.size()) {
        string s = v[i].substr(0, 2);
        if (m.find(s) == m.end()) {
            m[s] = p.size();
            p.push_back(s);
        }
        s = v[i].substr(1, 2);
        if (m.find(s) == m.end()) {
            m[s] = p.size();
            p.push_back(s);
        }
    }
    out.resize(p.size());
    in.resize(p.size());
    start.resize(p.size());
    FOR (i, 0, v.size()) {
        int a = m[v[i].substr(0, 2)];
        int b = m[v[i].substr(1, 2)];
        out[a].push_back(b);
        in[b].push_back(a);
    }
    vector <int> odd(p.size());
    FOR (i, 0, p.size()) {
        odd[i] = out[i].size() - in[i].size();
    }
    int c0 = count(IT(odd), 0);
    int c1 = count(IT(odd), 1);
    if (c0 != odd.size() &&
(c0 != odd.size() - 2 || c1 != 1)) {
        cout << "NO" << endl;
        return 0;
    }
    int flag = 0;
    if (c0 == odd.size()) {
        dfs(0);
    } else {
        int first = find(IT(odd), 1) - odd.begin();
        int second = find(IT(odd), -1) - odd.begin();
        dfs(first);
    }
    reverse(IT(used));
    string ans = p[used[0]];
    FOR (i, 1, used.size()) {
        ans += p[used[i]][1];
    }
    if (ans.size() != n + 2) {
        cout << "NO";
        return 0;
    }
    cout << "YES" << endl;
    cout << ans;
}


#include <bits/stdc++.h>
#define endl "\n"
#define FOR(x, y, z) for (int x = (y); x < (z); ++x)
#define FORR(x, y, z) for (int x = (y); x > (z); --x)
#define SORT(a) sort(a.begin(), a.end())
#define SORTR(a) sort(a.rbegin(), a.rend())
#define GET(a, n) for (int i = 0; i < n; ++i) cin >> a[i];
#define GETM(a, n, m) for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) cin >> a[i][j];
#define PRINTM(a, n, m) for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) cout << a[i][j] << " ";  cout << endl; };
#define PRINT(a, n) for (int i = 0; i < n; ++i) cout << a[i] << " ";
#define GETSUM(sum, n) sum = 0; for (int i = 0; i < n; ++i) { int tmp; cin >> tmp; sum += tmp; }
#define SUM(a, n, sum) sum = 0; for (int i = 0; i < n; ++i) { sum += a[i]; }
#define IT(a) a.begin(), a.end()
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef vector <int> VI;
typedef vector <vector <int>> VVI;
typedef pair <int, int> PII;
template <class T> typename T::value_type arr_sum(const T& v, int n) { typename T::value_type sum = 0; FOR(i, 0, n) sum += v[i]; return sum; }
struct Sync_stdio { Sync_stdio() { cin.tie(NULL); ios_base::sync_with_stdio(false); } } _sync_stdio;

vector <vector <int>> in;
vector <vector <int>> out;
vector <int> used;
vector <int> start;

void dfs(int t)
{
    FOR(i, start[t], out[t].size()) {
        ++start[t];
        dfs(out[t][i]);
        i = max(i, start[t] - 1);
    }
    used.push_back(t);
}

int main()
{
    int n;
    cin >> n;
    vector <string> v(n);
    GET(v, n);
    map <string, int> m;
    vector <string> p;
    FOR (i, 0, v.size()) {
        string s = v[i].substr(0, 2);
        if (m.find(s) == m.end()) {
            m[s] = p.size();
            p.push_back(s);
        }
        s = v[i].substr(1, 2);
        if (m.find(s) == m.end()) {
            m[s] = p.size();
            p.push_back(s);
        }
    }
    out.resize(p.size());
    in.resize(p.size());
    start.resize(p.size());
    FOR (i, 0, v.size()) {
        int a = m[v[i].substr(0, 2)];
        int b = m[v[i].substr(1, 2)];
        out[a].push_back(b);
        in[b].push_back(a);
    }
    vector <int> odd(p.size());
    FOR (i, 0, p.size()) {
        odd[i] = out[i].size() - in[i].size();
    }
    int c0 = count(IT(odd), 0);
    int c1 = count(IT(odd), 1);
    if (c0 != odd.size() &&
(c0 != odd.size() - 2 || c1 != 1)) {
        cout << "NO" << endl;
        return 0;
    }
    int flag = 0;
    if (c0 == odd.size()) {
        dfs(0);
    } else {
        int first = find(IT(odd), 1) - odd.begin();
        int second = find(IT(odd), -1) - odd.begin();
        //in[first].push_back({second, 0});
        //out[second].push_back({first, 0});
        dfs(first);
    }
    reverse(IT(used));
    string ans = p[used[0]];
    FOR (i, 1, used.size()) {
        ans += p[used[i]][1];
    }
    if (ans.size() != n + 2) {
        cout << "NO";
        return 0;
    }
    cout << "YES" << endl;
    cout << ans;
}


#include <bits/stdc++.h>
#define endl "\n"
#define FOR(x, y, z) for (int x = (y); x < (z); ++x)
#define FORR(x, y, z) for (int x = (y); x > (z); --x)
#define SORT(a) sort(a.begin(), a.end())
#define SORTR(a) sort(a.rbegin(), a.rend())
#define GET(a, n) for (int i = 0; i < n; ++i) cin >> a[i];
#define GETM(a, n, m) for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) cin >> a[i][j];
#define PRINTM(a, n, m) for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) cout << a[i][j] << " ";  cout << endl; };
#define PRINT(a, n) for (int i = 0; i < n; ++i) cout << a[i] << " ";
#define GETSUM(sum, n) sum = 0; for (int i = 0; i < n; ++i) { int tmp; cin >> tmp; sum += tmp; }
#define SUM(a, n, sum) sum = 0; for (int i = 0; i < n; ++i) { sum += a[i]; }
#define IT(a) a.begin(), a.end()
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef vector <int> VI;
typedef vector <vector <int>> VVI;
typedef pair <int, int> PII;
template <class T> typename T::value_type arr_sum(const T& v, int n) { typename T::value_type sum = 0; FOR(i, 0, n) sum += v[i]; return sum; }
struct Sync_stdio { Sync_stdio() { cin.tie(NULL); ios_base::sync_with_stdio(false); } } _sync_stdio;

vector <vector <PII>> in;
vector <vector <PII>> out;
vector <int> used;

void dfs(int t)
{
    //cout << t << endl;
    for (auto &i: out[t]) {
        if (i.second == 1) {
            continue;
        }
        i.second = 1;
        dfs(i.first);
    }
    used.push_back(t);
}

int main()
{
    int n;
    cin >> n;
    vector <string> v(n);
    GET(v, n);
    map <string, int> m;
    vector <string> p;
    FOR (i, 0, v.size()) {
        string s = v[i].substr(0, 2);
        if (m.find(s) == m.end()) {
            m[s] = p.size();
            p.push_back(s);
        }
        s = v[i].substr(1, 2);
        if (m.find(s) == m.end()) {
            m[s] = p.size();
            p.push_back(s);
        }
    }
    out.resize(p.size());
    in.resize(p.size());
    FOR (i, 0, v.size()) {
        int a = m[v[i].substr(0, 2)];
        int b = m[v[i].substr(1, 2)];
        out[a].push_back({b, 0});
        in[b].push_back({a, 0});
    }
    vector <int> odd(p.size());
    FOR (i, 0, p.size()) {
        odd[i] = out[i].size() - in[i].size();
    }
    int c0 = count(IT(odd), 0);
    int c1 = count(IT(odd), 1);
    if (c0 != odd.size() &&
(c0 != odd.size() - 2 || c1 != 1)) {
        cout << "NO" << endl;
        return 0;
    }
    int flag = 0;
    if (c0 == odd.size()) {
        dfs(0);
    } else {
        flag = 1;
        int first = find(IT(odd), 1) - odd.begin();
        int second = find(IT(odd), -1) - odd.begin();
        in[first].push_back({second, 0});
        out[second].push_back({first, 0});
        dfs(first);
    }
    cout << "YES" << endl;
    reverse(IT(used));
    string ans = p[used[0]];
    FOR (i, 1, used.size()) {
        ans += p[used[i]][1];
    }
    if (flag) {
        ans.pop_back();
    }
    cout << ans;
}


#include <iostream>
#include <utility>
#include <algorithm>
#include <memory.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <numeric>
#include <list>
#include <stack>
#include <cmath>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
using namespace std;

typedef  long long LL;
const int Mod = 1e9 + 9;
inline int FIX(LL a) {return (a % Mod + Mod) % Mod;}
#define MP(x,y) make_pair(x,y)
#define LEN(x) ((int)x.length())
#define SZ(x) ((int)x.size())
#define take(x,y) (((x)>>(y)) & 1ll)
//#define move(n) (1<<(n))
#define what_is(x) cerr << #x << " is " << x << endl;
#define eb emplace_back
#define pb push_back
#define UNQ(x) (sort(begin(x),end(x)),x.erase(unique(begin(x),end(x)),end(x)))
const int N = 1e6 + 5;
int n,idx = 0;
map<string,int>M;
string ink[N];
int getIdx(string &x){
    if(M.find(x) == M.end()) {
        M[x] = idx++;
        ink[idx - 1] = x;
    }
    return M[x];
}
vector<tuple<char,int,int>>E[N];
int in[N],out[N],used[N];
void gao(int rt,int pre) {
    used[rt] = 1;
    char a;
    int b,c;
    for(auto x : E[rt]) {
        std::tie(a,b,c) = x;
        if(b != pre && used[b] == 0) gao(b,rt);
    }
    return;
}
int f[N];
void getans(int rt,string &S) {
    char a;
    int b,c;
    for(auto &x : E[rt]) {
        std::tie(a,b,c) = x;
        if(f[c] == 0) {
            f[c] = 1;
            S += a;
            getans(b,S);
        }
    }
    return;
}
int main(){
    cin>>n;
    for(int i = 0;i < n;i++) {
        string tmp;
        cin>>tmp;
        string L = "";L += tmp[0];L += tmp[1];
        string R = "";R += tmp[1];R += tmp[2];
        int Lidx = getIdx(L),Ridx = getIdx(R);
        E[Lidx].eb(tmp[2],Ridx,i);
        in[Ridx]++;
        out[Lidx]++;
    }
    int s = -1;
    int t = 0;
    for(int i = 0;i < idx;i++) {
        //printf("%s : %d %d\n",ink[i].c_str(),in[i],out[i]);
        int d = abs(in[i] - out[i]);
        if(d > 1) {
            printf("NO\n");
            return 0;
        }
        if(out[i] == in[i] + 1) {
            if(s != -1) {
                printf("NO\n");
                return 0;
            }else s = i;
        }
        if(in[i] == out[i] + 1) {
            t++;
        }
    }
    if(s == -1) {
        s = 0;
    }
    gao(s,-1);
    for(int i = 0;i < idx;i++) {
        if(used[i] == 0) {
            printf("NO\n");
            return 0;
        }
    }
    string Ret = "";
    Ret += ink[s][0];Ret += ink[s][1];
    getans(s,Ret);
    if(Ret.length() != n + 2) {
        printf("NO\n");
        return 0;
    }
    cout<<"YES"<<endl;
    cout<<Ret<<endl;
    return 0;
}


#include <iostream>
#include <utility>
#include <algorithm>
#include <memory.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <numeric>
#include <list>
#include <stack>
#include <cmath>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
using namespace std;

typedef  long long LL;
const int Mod = 1e9 + 9;
inline int FIX(LL a) {return (a % Mod + Mod) % Mod;}
#define MP(x,y) make_pair(x,y)
#define LEN(x) ((int)x.length())
#define SZ(x) ((int)x.size())
#define take(x,y) (((x)>>(y)) & 1ll)
//#define move(n) (1<<(n))
#define what_is(x) cerr << #x << " is " << x << endl;
#define eb emplace_back
#define pb push_back
#define UNQ(x) (sort(begin(x),end(x)),x.erase(unique(begin(x),end(x)),end(x)))
const int N = 1e6 + 5;
int n,idx = 0;
map<string,int>M;
string ink[N];
int getIdx(string &x){
    if(M.find(x) == M.end()) {
        M[x] = idx++;
        ink[idx - 1] = x;
    }
    return M[x];
}
vector<tuple<char,int,int>>E[N];
int in[N],out[N],used[N];
void gao(int rt,int pre) {
    used[rt] = 1;
    char a;
    int b,c;
    for(auto x : E[rt]) {
        std::tie(a,b,c) = x;
        if(b != pre && used[b] == 0) gao(b,rt);
    }
    return;
}
int f[N];
void getans(int rt,string &S) {
    char a;
    int b,c;
    for(auto &x : E[rt]) {
        std::tie(a,b,c) = x;
        if(f[c] == 0) {
            f[c] = 1;
            S += a;
            getans(b,S);
        }
    }
    return;
}
map<string,int>chk;
int main(){
    cin>>n;
    for(int i = 0;i < n;i++) {
        string tmp;
        cin>>tmp;
        string L = "";L += tmp[0];L += tmp[1];
        string R = "";R += tmp[1];R += tmp[2];
        int Lidx = getIdx(L),Ridx = getIdx(R);
        E[Lidx].eb(tmp[2],Ridx,i);
        in[Ridx]++;
        out[Lidx]++;
        chk[tmp]++;
    }
    int s = -1;
    int t = 0;
    for(int i = 0;i < idx;i++) {
        //printf("%s : %d %d\n",ink[i].c_str(),in[i],out[i]);
        int d = abs(in[i] - out[i]);
        if(d > 1) {
            printf("NO\n");
            return 0;
        }
        if(out[i] == in[i] + 1) {
            if(s != -1) {
                printf("NO\n");
                return 0;
            }else s = i;
        }
        if(in[i] == out[i] + 1) {
            t++;
        }
    }
    if(s == -1) {
        s = 0;
    }
    gao(s,-1);
    for(int i = 0;i < idx;i++) {
        if(used[i] == 0) {
            printf("NO\n");
            return 0;
        }
    }
    string Ret = "";
    Ret += ink[s][0];Ret += ink[s][1];
    getans(s,Ret);
    if(Ret.length() != n + 2) {
        printf("NO\n");
        return 0;
    }
    cout<<"YES"<<endl;
    cout<<Ret<<endl;
    for(int i = 2;i < Ret.length();i++) {
        string tmp = "";
        tmp += Ret[i];tmp += Ret[i-1];tmp += Ret[i-2];
        if(M.find(tmp) != M.end()) {
            cout<<"cannot find "<<tmp<<endl;
        }else {
            if(M[tmp] == 0) {
                cout<<"not enough " << tmp << endl;
            }else {
                M[tmp]--;
            }
        }
    }
    return 0;
}


#include <iostream>
#include <utility>
#include <algorithm>
#include <memory.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <numeric>
#include <list>
#include <stack>
#include <cmath>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
using namespace std;

typedef  long long LL;
const int Mod = 1e9 + 9;
inline int FIX(LL a) {return (a % Mod + Mod) % Mod;}
#define MP(x,y) make_pair(x,y)
#define LEN(x) ((int)x.length())
#define SZ(x) ((int)x.size())
#define take(x,y) (((x)>>(y)) & 1ll)
//#define move(n) (1<<(n))
#define what_is(x) cerr << #x << " is " << x << endl;
#define eb emplace_back
#define pb push_back
#define UNQ(x) (sort(begin(x),end(x)),x.erase(unique(begin(x),end(x)),end(x)))
const int N = 1e6 + 5;
int n,idx = 0;
map<string,int>M;
string ink[N];
int getIdx(string x){
    if(M.find(x) == M.end()) {
        M[x] = idx++;
        ink[idx - 1] = x;
    }
    return M[x];
}
vector<tuple<char,int,int>>E[N];
int in[N],out[N],used[N];
void gao(int rt,int pre) {
    used[rt] = 1;
    char a;
    int b,c;
    for(auto x : E[rt]) {
        std::tie(a,b,c) = x;
        if(b != pre && used[b] == 0) gao(b,rt);
    }
    return;
}
int f[N];
string input[N];
void getans(int rt,string &S) {
    char a;
    int b,c;
    for(auto &x : E[rt]) {
        std::tie(a,b,c) = x;
        if(f[c] == 0) {
            f[c] = 1;
            S += a;
            //tmp += S[S.length() - 3];tmp += S[S.length() - 2];tmp += S[S.length() - 1];
            if(S.length() >= 3 && S[S.length() - 3] == 's' && S[S.length() - 2] == 'P' && S[S.length() - 1] == 'D') {
                for(int j = (int)S.length();j >= 0 && j >= S.length() - 10;j++) {
                    cout<<S[j];
                }
                cout<<endl;
                cout << "rt" << rt << " " << ink[rt] << endl;
                cout << "b"  << b  << " " << ink[b]  << endl;
                cout << "Edge" << input[c] << endl;
            }
            getans(b,S);
        }
    }
    return;
}
map<string,int>chk;
int main(){
    cin>>n;
    for(int i = 0;i < n;i++) {
        string tmp;
        cin>>tmp;
        string L = "";L += tmp[0];L += tmp[1];
        string R = "";R += tmp[1];R += tmp[2];
        int Lidx = getIdx(L),Ridx = getIdx(R);
        E[Lidx].eb(tmp[2],Ridx,i);
        in[Ridx]++;
        out[Lidx]++;
        chk[tmp]++;
        input[i] = tmp;
        if(n == 200000) {
            if(tmp == "sPD") {
                cout<<" found sPD" << endl;
            }
        }
    }
    if(n == 200000) {
        int Lidx = getIdx("sP");
        for(auto x : E[Lidx]) {
            char a;int b,c;
            tie(a,b,c) = x;
            if(a == 'D') {
                cout << "found sPD" << endl;
            }
        }
    }
    int s = -1;
    int t = 0;
    for(int i = 0;i < idx;i++) {
        //printf("%s : %d %d\n",ink[i].c_str(),in[i],out[i]);
        int d = abs(in[i] - out[i]);
        if(d > 1) {
            printf("NO\n");
            return 0;
        }
        if(out[i] == in[i] + 1) {
            if(s != -1) {
                printf("NO\n");
                return 0;
            }else s = i;
        }
        if(in[i] == out[i] + 1) {
            t++;
        }
    }
    if(s == -1) {
        s = 0;
    }
    gao(s,-1);
    for(int i = 0;i < idx;i++) {
        if(used[i] == 0) {
            printf("NO\n");
            return 0;
        }
    }
    string Ret = "";
    Ret += ink[s][0];Ret += ink[s][1];
    getans(s,Ret);
    if(Ret.length() != n + 2) {
        printf("NO\n");
        return 0;
    }
    cout<<"YES"<<endl;
    for(int i = 2;i < Ret.length();i++) {
        string tmp = "";
        tmp += Ret[i-2];tmp += Ret[i-1];tmp += Ret[i];
        if(chk.find(tmp) == chk.end()) {
            cout<<"cannot find "<<tmp<<endl;
        }else {
            if(chk[tmp] == 0) {
                cout<<"not enough " << tmp << endl;
            }else {
                chk[tmp]--;
            }
        }
    }
    cout<<Ret<<endl;
    return 0;
}


#include <iostream>
#include <utility>
#include <algorithm>
#include <memory.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <numeric>
#include <list>
#include <stack>
#include <cmath>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
using namespace std;

typedef  long long LL;
const int Mod = 1e9 + 9;
inline int FIX(LL a) {return (a % Mod + Mod) % Mod;}
#define MP(x,y) make_pair(x,y)
#define LEN(x) ((int)x.length())
#define SZ(x) ((int)x.size())
#define take(x,y) (((x)>>(y)) & 1ll)
//#define move(n) (1<<(n))
#define what_is(x) cerr << #x << " is " << x << endl;
#define eb emplace_back
#define pb push_back
#define UNQ(x) (sort(begin(x),end(x)),x.erase(unique(begin(x),end(x)),end(x)))
const int N = 2 * 1e5 + 5;
int n,idx = 0;
map<string,int>M;
string ink[N];
int getIdx(string &x){
    if(M.find(x) == M.end()) {
        M[x] = idx++;
        ink[idx - 1] = x;
    }
    return M[x];
}
vector<tuple<char,int,int>>E[N];
int in[N],out[N],used[N];
void gao(int rt,int pre) {
    used[rt] = 1;
    char a;
    int b,c;
    for(auto x : E[rt]) {
        std::tie(a,b,c) = x;
        if(b != pre && used[b] == 0) gao(b,rt);
    }
    return;
}
int f[N];
void getans(int rt,string &S) {
    char a;
    int b,c;
    for(auto &x : E[rt]) {
        std::tie(a,b,c) = x;
        if(f[c] == 0) {
            f[c] = 1;
            S += a;
            getans(b,S);
        }
    }
    return;
}
int main(){
    cin>>n;
    for(int i = 0;i < n;i++) {
        string tmp;
        cin>>tmp;
        string L = "";L += tmp[0];L += tmp[1];
        string R = "";R += tmp[1];R += tmp[2];
        int Lidx = getIdx(L),Ridx = getIdx(R);
        E[Lidx].eb(tmp[2],Ridx,i);
        in[Ridx]++;
        out[Lidx]++;
    }
    int s = -1;
    int t = 0;
    for(int i = 0;i < idx;i++) {
        //printf("%s : %d %d\n",ink[i].c_str(),in[i],out[i]);
        int d = abs(in[i] - out[i]);
        if(d > 1) {
            printf("NO\n");
            return 0;
        }
        if(out[i] == in[i] + 1) {
            if(s != -1) {
                printf("NO\n");
                return 0;
            }else s = i;
        }
        if(in[i] == out[i] + 1) {
            t++;
        }
    }
    if(s == -1) {
        s = 0;
    }
    gao(s,-1);
    for(int i = 0;i < idx;i++) {
        if(used[i] == 0) {
            printf("NO\n");
            return 0;
        }
    }
    string Ret = "";
    Ret += ink[s][0];Ret += ink[s][1];
    getans(s,Ret);
    if(Ret.length() != n + 2) {
        printf("NO\n");
        return 0;
    }
    cout<<"YES"<<endl;
    cout<<Ret<<endl;
    return 0;
}


#include <iostream>
#include <utility>
#include <algorithm>
#include <memory.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <numeric>
#include <list>
#include <stack>
#include <cmath>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
using namespace std;

typedef  long long LL;
const int Mod = 1e9 + 7;
inline int FIX(LL a) {return (a % Mod + Mod) % Mod;}
#define MP(x,y) make_pair(x,y)
#define LEN(x) ((int)x.length())
#define SZ(x) ((int)x.size())
#define take(x,y) (((x)>>(y)) & 1ll)
//#define move(n) (1<<(n))
#define what_is(x) cerr << #x << " is " << x << endl;
#define eb emplace_back
#define pb push_back
#define UNQ(x) (sort(begin(x),end(x)),x.erase(unique(begin(x),end(x)),end(x)))
const int N = 1e6 + 5;
int n,idx = 0;
map<string,int>M;
string ink[N];
int getIdx(string x){
    if(M.find(x) == M.end()) {
        M[x] = idx++;
        ink[idx - 1] = x;
    }
    return M[x];
}
vector<pair<char,int>>E[N];
int in[N],out[N],used[N];
int start[N];
string input[N];
string S;

void getans(int rt) {
    if(S[S.length() - 2] != ink[rt][0] || S[S.length() - 1] != ink[rt][1]) {
        cout<<"fuck"<<endl;
        cout<<ink[rt]<<endl;
    }
    for(;start[rt] < E[rt].size();) {
        auto x = E[rt][start[rt]++];
        S += x.first;
        string chk;chk += S[S.length() - 2];chk += S[S.length() - 1];
        if(chk != ink[x.second]) {
            cout << chk << endl;
            cout << ink[x.second] << endl;
            cout << ink[rt] << endl;
        }
        getans(x.second);
    }
    return;
}
map<string,int>chk;
int main(){
    cin>>n;
    for(int i = 0;i < n;i++) {
        string tmp;
        cin>>tmp;
        string L = "";L += tmp[0];L += tmp[1];
        string R = "";R += tmp[1];R += tmp[2];
        int Lidx = getIdx(L),Ridx = getIdx(R);
        E[Lidx].push_back(MP(tmp[2],Ridx));
        in[Ridx]++;
        out[Lidx]++;
        chk[tmp]++;
        input[i] = tmp;
    }

    int s = -1;
    int t = 0;
    for(int i = 0;i < idx;i++) {
        int d = abs(in[i] - out[i]);
        if(d > 1) {
            printf("NO\n");
            return 0;
        }
        if(out[i] == in[i] + 1) {
            if(s != -1) {
                printf("NO\n");
                return 0;
            }else s = i;
        }
        if(in[i] == out[i] + 1) {
            t++;
        }
    }
    if(s == -1) {
        s = 0;
    }
    string &Ret = S;
    Ret += ink[s][0];Ret += ink[s][1];
    getans(s);
    if(Ret.length() != n + 2) {
        printf("NO\n");
        return 0;
    }
    cout<<"YES"<<endl;
    for(int i = 2;i < Ret.length();i++) {
        string tmp = "";
        tmp += Ret[i-2];tmp += Ret[i-1];tmp += Ret[i];
        if(chk.find(tmp) == chk.end()) {
            cout<<"cannot find "<<tmp<<endl;
        }else {
            if(chk[tmp] == 0) {
                cout<<"not enough " << tmp << endl;
            }else {
                chk[tmp]--;
            }
        }
    }
    cout<<Ret<<endl;
    return 0;
}


#include <iostream>
#include <utility>
#include <algorithm>
#include <memory.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <numeric>
#include <list>
#include <stack>
#include <cmath>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
using namespace std;

typedef  long long LL;
const int Mod = 1e9 + 7;
inline int FIX(LL a) {return (a % Mod + Mod) % Mod;}
#define MP(x,y) make_pair(x,y)
#define LEN(x) ((int)x.length())
#define SZ(x) ((int)x.size())
#define take(x,y) (((x)>>(y)) & 1ll)
//#define move(n) (1<<(n))
#define what_is(x) cerr << #x << " is " << x << endl;
#define eb emplace_back
#define pb push_back
#define UNQ(x) (sort(begin(x),end(x)),x.erase(unique(begin(x),end(x)),end(x)))
const int N = 1e6 + 5;
int n,idx = 0;
map<string,int>M;
string ink[N];
int getIdx(string x){
    if(M.find(x) == M.end()) {
        M[x] = idx++;
        ink[idx - 1] = x;
    }
    return M[x];
}
vector<pair<char,int>>E[N];
int in[N],out[N],used[N];
int start[N];
string input[N];
string S;

void getans(int rt) {
    if(S[S.length() - 2] != ink[rt][0] || S[S.length() - 1] != ink[rt][1]) {
        cout<<"fuck"<<endl;
        cout<<ink[rt]<<endl;
    }
    for(;start[rt] < E[rt].size();) {
        auto x = E[rt][start[rt]++];
        S += x.first;
        string chk;chk += S[S.length() - 2];chk += S[S.length() - 1];
        if(chk != ink[x.second]) {
            cout << chk << endl;
            cout << ink[x.second] << endl;
        }
        getans(x.second);
    }
    return;
}
map<string,int>chk;
int main(){
    cin>>n;
    for(int i = 0;i < n;i++) {
        string tmp;
        cin>>tmp;
        string L = "";L += tmp[0];L += tmp[1];
        string R = "";R += tmp[1];R += tmp[2];
        int Lidx = getIdx(L),Ridx = getIdx(R);
        E[Lidx].push_back(MP(tmp[2],Ridx));
        in[Ridx]++;
        out[Lidx]++;
        chk[tmp]++;
        input[i] = tmp;
    }

    int s = -1;
    int t = 0;
    for(int i = 0;i < idx;i++) {
        int d = abs(in[i] - out[i]);
        if(d > 1) {
            printf("NO\n");
            return 0;
        }
        if(out[i] == in[i] + 1) {
            if(s != -1) {
                printf("NO\n");
                return 0;
            }else s = i;
        }
        if(in[i] == out[i] + 1) {
            t++;
        }
    }
    if(s == -1) {
        s = 0;
    }
    string &Ret = S;
    Ret += ink[s][0];Ret += ink[s][1];
    getans(s);
    if(Ret.length() != n + 2) {
        printf("NO\n");
        return 0;
    }
    cout<<"YES"<<endl;
    for(int i = 2;i < Ret.length();i++) {
        string tmp = "";
        tmp += Ret[i-2];tmp += Ret[i-1];tmp += Ret[i];
        if(chk.find(tmp) == chk.end()) {
            cout<<"cannot find "<<tmp<<endl;
        }else {
            if(chk[tmp] == 0) {
                cout<<"not enough " << tmp << endl;
            }else {
                chk[tmp]--;
            }
        }
    }
    cout<<Ret<<endl;
    return 0;
}


#include <iostream>
#include <utility>
#include <algorithm>
#include <memory.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <numeric>
#include <list>
#include <stack>
#include <cmath>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
using namespace std;

typedef  long long LL;
const int Mod = 1e9 + 7;
inline int FIX(LL a) {return (a % Mod + Mod) % Mod;}
#define MP(x,y) make_pair(x,y)
#define LEN(x) ((int)x.length())
#define SZ(x) ((int)x.size())
#define take(x,y) (((x)>>(y)) & 1ll)
//#define move(n) (1<<(n))
#define what_is(x) cerr << #x << " is " << x << endl;
#define eb emplace_back
#define pb push_back
#define UNQ(x) (sort(begin(x),end(x)),x.erase(unique(begin(x),end(x)),end(x)))
const int N = 1e6 + 5;
int n,idx = 0;
map<string,int>M;
string ink[N];
int getIdx(string x){
    if(M.find(x) == M.end()) {
        M[x] = idx++;
        ink[idx - 1] = x;
    }
    return M[x];
}
vector<pair<char,int>>E[N];
int in[N],out[N],used[N];
void gao(int rt,int pre) {
    used[rt] = 1;
    for(auto x : E[rt]) {
        if(x.second != pre && used[x.second] == 0) gao(x.second,rt);
    }
    return;
}
int start[N];
string input[N];
string S;
void getans(int rt) {
    if(S[S.length() - 2] != ink[rt][0] || S[S.length() - 1] != ink[rt][1]) {
        cout<<"fuck"<<endl;
        cout<<ink[rt]<<endl;
    }
    for(;start[rt] < E[rt].size();) {
        auto x = E[rt][start[rt]++];
        S += x.first;
        getans(x.second);
    }
    return;
}
map<string,int>chk;
int main(){
    cin>>n;
    for(int i = 0;i < n;i++) {
        string tmp;
        cin>>tmp;
        string L = "";L += tmp[0];L += tmp[1];
        string R = "";R += tmp[1];R += tmp[2];
        int Lidx = getIdx(L),Ridx = getIdx(R);
        E[Lidx].push_back(MP(tmp[2],Ridx));
        in[Ridx]++;
        out[Lidx]++;
        chk[tmp]++;
        input[i] = tmp;
    }

    int s = -1;
    int t = 0;
    for(int i = 0;i < idx;i++) {
        int d = abs(in[i] - out[i]);
        if(d > 1) {
            printf("NO\n");
            return 0;
        }
        if(out[i] == in[i] + 1) {
            if(s != -1) {
                printf("NO\n");
                return 0;
            }else s = i;
        }
        if(in[i] == out[i] + 1) {
            t++;
        }
    }
    if(s == -1) {
        s = 0;
    }
    gao(s,-1);
    for(int i = 0;i < idx;i++) {
        if(used[i] == 0) {
            printf("NO\n");
            return 0;
        }
    }
    string &Ret = S;
    Ret += ink[s][0];Ret += ink[s][1];
    getans(s);
    if(Ret.length() != n + 2) {
        printf("NO\n");
        return 0;
    }
    cout<<"YES"<<endl;
    for(int i = 2;i < Ret.length();i++) {
        string tmp = "";
        tmp += Ret[i-2];tmp += Ret[i-1];tmp += Ret[i];
        if(chk.find(tmp) == chk.end()) {
            cout<<"cannot find "<<tmp<<endl;
        }else {
            if(chk[tmp] == 0) {
                cout<<"not enough " << tmp << endl;
            }else {
                chk[tmp]--;
            }
        }
    }
    cout<<Ret<<endl;
    return 0;
}


#include <iostream>
#include <utility>
#include <algorithm>
#include <memory.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <numeric>
#include <list>
#include <stack>
#include <cmath>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
using namespace std;

typedef  long long LL;
const int Mod = 1e9 + 9;
inline int FIX(LL a) {return (a % Mod + Mod) % Mod;}
#define MP(x,y) make_pair(x,y)
#define LEN(x) ((int)x.length())
#define SZ(x) ((int)x.size())
#define take(x,y) (((x)>>(y)) & 1ll)
//#define move(n) (1<<(n))
#define what_is(x) cerr << #x << " is " << x << endl;
#define eb emplace_back
#define pb push_back
#define UNQ(x) (sort(begin(x),end(x)),x.erase(unique(begin(x),end(x)),end(x)))
const int N = 1e6 + 5;
int n,idx = 0;
map<string,int>M;
string ink[N];
int getIdx(string &x){
    if(M.find(x) == M.end()) {
        M[x] = idx++;
        ink[idx - 1] = x;
    }
    return M[x];
}
vector<tuple<char,int,int>>E[N];
int in[N],out[N],used[N];
void gao(int rt,int pre) {
    used[rt] = 1;
    char a;
    int b,c;
    for(auto x : E[rt]) {
        std::tie(a,b,c) = x;
        if(b != pre && used[b] == 0) gao(b,rt);
    }
    return;
}
int f[N];
void getans(int rt,string &S) {
    char a;
    int b,c;
    for(auto &x : E[rt]) {
        std::tie(a,b,c) = x;
        if(f[c] == 0) {
            f[c] = 1;
            S += a;
            getans(b,S);
        }
    }
    return;
}
int main(){
    cin>>n;
    for(int i = 0;i < n;i++) {
        string tmp;
        cin>>tmp;
        string L = "";L += tmp[0];L += tmp[1];
        string R = "";R += tmp[1];R += tmp[2];
        int Lidx = getIdx(L),Ridx = getIdx(R);
        E[Lidx].eb(tmp[2],Ridx,i);
        in[Ridx]++;
        out[Lidx]++;
    }
    int s = -1;
    int t = 0;
    for(int i = 0;i < idx;i++) {
        //printf("%s : %d %d\n",ink[i].c_str(),in[i],out[i]);
        int d = abs(in[i] - out[i]);
        if(d > 1) {
            printf("NO\n");
            return 0;
        }
        if(out[i] == in[i] + 1) {
            if(s != -1) {
                printf("NO\n");
                return 0;
            }else s = i;
        }
        if(in[i] == out[i] + 1) {
            t++;
        }
    }
    if(s == -1) {
        if(n == 200000) {
            cout<<ink[s]<<endl;
        }
        s = 0;
    }
    gao(s,-1);
    for(int i = 0;i < idx;i++) {
        if(used[i] == 0) {
            printf("NO\n");
            return 0;
        }
    }
    string Ret = "";
    Ret += ink[s][0];Ret += ink[s][1];
    getans(s,Ret);
    if(Ret.length() != n + 2) {
        printf("NO\n");
        return 0;
    }
    cout<<"YES"<<endl;
    cout<<Ret<<endl;
    return 0;
}


#include <iostream>
#include <utility>
#include <algorithm>
#include <memory.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <numeric>
#include <list>
#include <stack>
#include <cmath>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
using namespace std;

typedef  long long LL;
const int Mod = 1e9 + 9;
inline int FIX(LL a) {return (a % Mod + Mod) % Mod;}
#define MP(x,y) make_pair(x,y)
#define LEN(x) ((int)x.length())
#define SZ(x) ((int)x.size())
#define take(x,y) (((x)>>(y)) & 1ll)
//#define move(n) (1<<(n))
#define what_is(x) cerr << #x << " is " << x << endl;
#define eb emplace_back
#define pb push_back
#define UNQ(x) (sort(begin(x),end(x)),x.erase(unique(begin(x),end(x)),end(x)))
const int N = 1e6 + 5;
int n,idx = 0;
map<string,int>M;
string ink[N];
int getIdx(string &x){
    if(M.find(x) == M.end()) {
        M[x] = idx++;
        ink[idx - 1] = x;
    }
    return M[x];
}
vector<tuple<char,int,int>>E[N];
int in[N],out[N],used[N];
void gao(int rt,int pre) {
    used[rt] = 1;
    char a;
    int b,c;
    for(auto x : E[rt]) {
        std::tie(a,b,c) = x;
        if(b != pre && used[b] == 0) gao(b,rt);
    }
    return;
}
int f[N];
void getans(int rt,string &S) {
    char a;
    int b,c;
    for(auto &x : E[rt]) {
        std::tie(a,b,c) = x;
        if(f[c] == 0) {
            f[c] = 1;
            S += a;
            getans(b,S);
        }
    }
    return;
}
int main(){
    cin>>n;
    for(int i = 0;i < n;i++) {
        string tmp;
        cin>>tmp;
        string L = "";L += tmp[0];L += tmp[1];
        string R = "";R += tmp[1];R += tmp[2];
        int Lidx = getIdx(L),Ridx = getIdx(R);
        E[Lidx].eb(tmp[2],Ridx,i);
        in[Ridx]++;
        out[Lidx]++;
    }
    int s = -1;
    int t = 0;
    for(int i = 0;i < idx;i++) {
        //printf("%s : %d %d\n",ink[i].c_str(),in[i],out[i]);
        int d = abs(in[i] - out[i]);
        if(d > 1) {
            printf("NO\n");
            return 0;
        }
        if(out[i] == in[i] + 1) {
            if(s != -1) {
                printf("NO\n");
                return 0;
            }else s = i;
        }
        if(in[i] == out[i] + 1) {
            t++;
        }
    }
    if(s == -1) {
        s = 0;
    }
    if(n == 200000) {
        cout<<ink[s]<<endl;
    }

    gao(s,-1);
    for(int i = 0;i < idx;i++) {
        if(used[i] == 0) {
            printf("NO\n");
            return 0;
        }
    }
    string Ret = "";
    Ret += ink[s][0];Ret += ink[s][1];
    getans(s,Ret);
    if(Ret.length() != n + 2) {
        printf("NO\n");
        return 0;
    }
    cout<<"YES"<<endl;
    cout<<Ret<<endl;
    return 0;
}


#include <iostream>
#include <utility>
#include <algorithm>
#include <memory.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <numeric>
#include <list>
#include <stack>
#include <cmath>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
using namespace std;

typedef  long long LL;
const int Mod = 1e9 + 7;
inline int FIX(LL a) {return (a % Mod + Mod) % Mod;}
#define MP(x,y) make_pair(x,y)
#define LEN(x) ((int)x.length())
#define SZ(x) ((int)x.size())
#define take(x,y) (((x)>>(y)) & 1ll)
//#define move(n) (1<<(n))
#define what_is(x) cerr << #x << " is " << x << endl;
#define eb emplace_back
#define pb push_back
#define UNQ(x) (sort(begin(x),end(x)),x.erase(unique(begin(x),end(x)),end(x)))
const int N = 1e6 + 5;
int n,idx = 0;
map<string,int>M;
string ink[N];
int getIdx(string x){
    if(M.find(x) == M.end()) {
        M[x] = idx++;
        ink[idx - 1] = x;
    }
    return M[x];
}
vector<pair<char,int>>E[N];
int in[N],out[N],used[N];
void gao(int rt,int pre) {
    used[rt] = 1;
    for(auto x : E[rt]) {
        if(x.second != pre && used[x.second] == 0) gao(x.second,rt);
    }
    return;
}
int start[N];
string input[N];
void getans(int rt,string &S) {
    for(;start[rt] < E[rt].size();) {
        auto x = E[rt][start[rt]++];
        S += x.first;
        string chk;chk += ink[rt][1];
        chk += x.first;
        if(chk != ink[x.second]) {
            cout<<chk<<" " <<ink[x.second]<<endl;
        }
        getans(x.second,S);
    }
    return;
}
map<string,int>chk;
int main(){
    cin>>n;
    for(int i = 0;i < n;i++) {
        string tmp;
        cin>>tmp;
        string L = "";L += tmp[0];L += tmp[1];
        string R = "";R += tmp[1];R += tmp[2];
        int Lidx = getIdx(L),Ridx = getIdx(R);
        E[Lidx].eb(tmp[2],Ridx);
        in[Ridx]++;
        out[Lidx]++;
        chk[tmp]++;
        input[i] = tmp;
    }

    int s = -1;
    int t = 0;
    for(int i = 0;i < idx;i++) {
        int d = abs(in[i] - out[i]);
        if(d > 1) {
            printf("NO\n");
            return 0;
        }
        if(out[i] == in[i] + 1) {
            if(s != -1) {
                printf("NO\n");
                return 0;
            }else s = i;
        }
        if(in[i] == out[i] + 1) {
            t++;
        }
    }
    if(s == -1) {
        s = 0;
    }
    gao(s,-1);
    for(int i = 0;i < idx;i++) {
        if(used[i] == 0) {
            printf("NO\n");
            return 0;
        }
    }
    string Ret = "";
    Ret += ink[s][0];Ret += ink[s][1];
    getans(s,Ret);
    if(Ret.length() != n + 2) {
        printf("NO\n");
        return 0;
    }
    cout<<"YES"<<endl;
    for(int i = 2;i < Ret.length();i++) {
        string tmp = "";
        tmp += Ret[i-2];tmp += Ret[i-1];tmp += Ret[i];
        if(chk.find(tmp) == chk.end()) {
            cout<<"cannot find "<<tmp<<endl;
        }else {
            if(chk[tmp] == 0) {
                cout<<"not enough " << tmp << endl;
            }else {
                chk[tmp]--;
            }
        }
    }
    cout<<Ret<<endl;
    return 0;
}


#include <iostream>
#include <utility>
#include <algorithm>
#include <memory.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <numeric>
#include <list>
#include <stack>
#include <cmath>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
using namespace std;

typedef  long long LL;
const int Mod = 1e9 + 9;
inline int FIX(LL a) {return (a % Mod + Mod) % Mod;}
#define MP(x,y) make_pair(x,y)
#define LEN(x) ((int)x.length())
#define SZ(x) ((int)x.size())
#define take(x,y) (((x)>>(y)) & 1ll)
//#define move(n) (1<<(n))
#define what_is(x) cerr << #x << " is " << x << endl;
#define eb emplace_back
#define pb push_back
#define UNQ(x) (sort(begin(x),end(x)),x.erase(unique(begin(x),end(x)),end(x)))
const int N = 1e6 + 5;
int n,idx = 0;
map<string,int>M;
string ink[N];
int getIdx(string &x){
    if(M.find(x) == M.end()) {
        M[x] = idx++;
        ink[idx - 1] = x;
    }
    return M[x];
}
vector<tuple<char,int,int>>E[N];
int in[N],out[N],used[N];
void gao(int rt,int pre) {
    used[rt] = 1;
    char a;
    int b,c;
    for(auto x : E[rt]) {
        std::tie(a,b,c) = x;
        if(b != pre && used[b] == 0) gao(b,rt);
    }
    return;
}
int f[N];
void getans(int rt,string &S) {
    char a;
    int b,c;
    for(auto &x : E[rt]) {
        std::tie(a,b,c) = x;
        if(f[c] == 0) {
            f[c] = 1;
            S += a;
            getans(b,S);
        }
    }
    return;
}
map<string,int>chk;
int main(){
    cin>>n;
    for(int i = 0;i < n;i++) {
        string tmp;
        cin>>tmp;
        string L = "";L += tmp[0];L += tmp[1];
        string R = "";R += tmp[1];R += tmp[2];
        int Lidx = getIdx(L),Ridx = getIdx(R);
        E[Lidx].eb(tmp[2],Ridx,i);
        in[Ridx]++;
        out[Lidx]++;
        chk[tmp]++;
    }
    int s = -1;
    int t = 0;
    for(int i = 0;i < idx;i++) {
        //printf("%s : %d %d\n",ink[i].c_str(),in[i],out[i]);
        int d = abs(in[i] - out[i]);
        if(d > 1) {
            printf("NO\n");
            return 0;
        }
        if(out[i] == in[i] + 1) {
            if(s != -1) {
                printf("NO\n");
                return 0;
            }else s = i;
        }
        if(in[i] == out[i] + 1) {
            t++;
        }
    }
    if(s == -1) {
        s = 0;
    }
    gao(s,-1);
    for(int i = 0;i < idx;i++) {
        if(used[i] == 0) {
            printf("NO\n");
            return 0;
        }
    }
    string Ret = "";
    Ret += ink[s][0];Ret += ink[s][1];
    getans(s,Ret);
    if(Ret.length() != n + 2) {
        printf("NO\n");
        return 0;
    }
    cout<<"YES"<<endl;
    cout<<Ret<<endl;
    for(int i = 2;i < Ret.length();i++) {
        string tmp = "";
        tmp += Ret[i-2];tmp += Ret[i-1];tmp += Ret[i];
        if(chk.find(tmp) == chk.end()) {
            cout<<"cannot find "<<tmp<<endl;
        }else {
            if(chk[tmp] == 0) {
                cout<<"not enough " << tmp << endl;
            }else {
                chk[tmp]--;
            }
        }
    }
    return 0;
}


#include <iostream>
#include <utility>
#include <algorithm>
#include <memory.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <numeric>
#include <list>
#include <stack>
#include <cmath>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
using namespace std;

typedef  long long LL;
const int Mod = 1e9 + 7;
inline int FIX(LL a) {return (a % Mod + Mod) % Mod;}
#define MP(x,y) make_pair(x,y)
#define LEN(x) ((int)x.length())
#define SZ(x) ((int)x.size())
#define take(x,y) (((x)>>(y)) & 1ll)
//#define move(n) (1<<(n))
#define what_is(x) cerr << #x << " is " << x << endl;
#define eb emplace_back
#define pb push_back
#define UNQ(x) (sort(begin(x),end(x)),x.erase(unique(begin(x),end(x)),end(x)))
const int N = 1e6 + 5;
int n,idx = 0;
map<string,int>M;
string ink[N];
int getIdx(string x){
    if(M.find(x) == M.end()) {
        M[x] = idx++;
        ink[idx - 1] = x;
    }
    return M[x];
}
vector<pair<char,int>>E[N];
int in[N],out[N],used[N];
void gao(int rt,int pre) {
    used[rt] = 1;
    for(auto x : E[rt]) {
        if(x.second != pre && used[x.second] == 0) gao(x.second,rt);
    }
    return;
}
int start[N];
string input[N];
void getans(int rt,string &S) {
    for(;start[rt] < E[rt].size();) {
        auto x = E[rt][start[rt]++];
        S += x.first;
        /*string chk;chk += ink[rt][1];
        chk += x.first;

        if(chk != ink[x.second]) {
            cout<<chk<<" " <<ink[x.second]<<endl;
        }*/
        string chk;chk += S[S.length() - 2];
        chk += S[S.length() - 1];
        if(chk == "sP") {
            cout<<ink[rt]<<endl;
            cout<<ink[x.second]<<endl;
        }
        if(M.find(chk) == M.end()) {
            cout<<"cannot find " << chk<<endl;
        }
        getans(x.second,S);
    }
    return;
}
map<string,int>chk;
int main(){
    cin>>n;
    for(int i = 0;i < n;i++) {
        string tmp;
        cin>>tmp;
        string L = "";L += tmp[0];L += tmp[1];
        string R = "";R += tmp[1];R += tmp[2];
        int Lidx = getIdx(L),Ridx = getIdx(R);
        E[Lidx].eb(tmp[2],Ridx);
        in[Ridx]++;
        out[Lidx]++;
        chk[tmp]++;
        input[i] = tmp;
    }

    int s = -1;
    int t = 0;
    for(int i = 0;i < idx;i++) {
        int d = abs(in[i] - out[i]);
        if(d > 1) {
            printf("NO\n");
            return 0;
        }
        if(out[i] == in[i] + 1) {
            if(s != -1) {
                printf("NO\n");
                return 0;
            }else s = i;
        }
        if(in[i] == out[i] + 1) {
            t++;
        }
    }
    if(s == -1) {
        s = 0;
    }
    gao(s,-1);
    for(int i = 0;i < idx;i++) {
        if(used[i] == 0) {
            printf("NO\n");
            return 0;
        }
    }
    string Ret = "";
    Ret += ink[s][0];Ret += ink[s][1];
    getans(s,Ret);
    if(Ret.length() != n + 2) {
        printf("NO\n");
        return 0;
    }
    cout<<"YES"<<endl;
    for(int i = 2;i < Ret.length();i++) {
        string tmp = "";
        tmp += Ret[i-2];tmp += Ret[i-1];tmp += Ret[i];
        if(chk.find(tmp) == chk.end()) {
            cout<<"cannot find "<<tmp<<endl;
        }else {
            if(chk[tmp] == 0) {
                cout<<"not enough " << tmp << endl;
            }else {
                chk[tmp]--;
            }
        }
    }
    cout<<Ret<<endl;
    return 0;
}


#include <iostream>
#include <utility>
#include <algorithm>
#include <memory.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <numeric>
#include <list>
#include <stack>
#include <cmath>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
using namespace std;

typedef  long long LL;
const int Mod = 1e9 + 9;
inline int FIX(LL a) {return (a % Mod + Mod) % Mod;}
#define MP(x,y) make_pair(x,y)
#define LEN(x) ((int)x.length())
#define SZ(x) ((int)x.size())
#define take(x,y) (((x)>>(y)) & 1ll)
//#define move(n) (1<<(n))
#define what_is(x) cerr << #x << " is " << x << endl;
#define eb emplace_back
#define pb push_back
#define UNQ(x) (sort(begin(x),end(x)),x.erase(unique(begin(x),end(x)),end(x)))
const int N = 1e6 + 5;
int n,idx = 0;
map<string,int>M;
string ink[N];
int getIdx(string &x){
    if(M.find(x) == M.end()) {
        M[x] = idx++;
        ink[idx - 1] = x;
    }
    return M[x];
}
vector<tuple<char,int,int>>E[N];
int in[N],out[N],used[N];
void gao(int rt,int pre) {
    used[rt] = 1;
    char a;
    int b,c;
    for(auto x : E[rt]) {
        std::tie(a,b,c) = x;
        if(b != pre && used[b] == 0) gao(b,rt);
    }
    return;
}
int f[N];
void getans(int rt,string &S) {
    char a;
    int b,c;
    for(auto &x : E[rt]) {
        std::tie(a,b,c) = x;
        if(f[c] == 0) {
            f[c] = 1;
            S += a;
            getans(b,S);
        }
    }
    return;
}
map<string,int>chk;
int main(){
    cin>>n;
    for(int i = 0;i < n;i++) {
        string tmp;
        cin>>tmp;
        string L = "";L += tmp[0];L += tmp[1];
        string R = "";R += tmp[1];R += tmp[2];
        int Lidx = getIdx(L),Ridx = getIdx(R);
        E[Lidx].eb(tmp[2],Ridx,i);
        in[Ridx]++;
        out[Lidx]++;
        chk[tmp]++;
    }
    int s = -1;
    int t = 0;
    for(int i = 0;i < idx;i++) {
        //printf("%s : %d %d\n",ink[i].c_str(),in[i],out[i]);
        int d = abs(in[i] - out[i]);
        if(d > 1) {
            printf("NO\n");
            return 0;
        }
        if(out[i] == in[i] + 1) {
            if(s != -1) {
                printf("NO\n");
                return 0;
            }else s = i;
        }
        if(in[i] == out[i] + 1) {
            t++;
        }
    }
    if(s == -1) {
        s = 0;
    }
    gao(s,-1);
    for(int i = 0;i < idx;i++) {
        if(used[i] == 0) {
            printf("NO\n");
            return 0;
        }
    }
    string Ret = "";
    Ret += ink[s][0];Ret += ink[s][1];
    getans(s,Ret);
    if(Ret.length() != n + 2) {
        printf("NO\n");
        return 0;
    }
    cout<<"YES"<<endl;
    for(int i = 2;i < Ret.length();i++) {
        string tmp = "";
        tmp += Ret[i-2];tmp += Ret[i-1];tmp += Ret[i];
        if(chk.find(tmp) == chk.end()) {
            cout<<"cannot find "<<tmp<<endl;
        }else {
            if(chk[tmp] == 0) {
                cout<<"not enough " << tmp << endl;
            }else {
                chk[tmp]--;
            }
        }
    }
    cout<<Ret<<endl;
    return 0;
}


#include <iostream>
#include <utility>
#include <algorithm>
#include <memory.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <numeric>
#include <list>
#include <stack>
#include <cmath>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
using namespace std;

typedef  long long LL;
const int Mod = 1e9 + 9;
inline int FIX(LL a) {return (a % Mod + Mod) % Mod;}
#define MP(x,y) make_pair(x,y)
#define LEN(x) ((int)x.length())
#define SZ(x) ((int)x.size())
#define take(x,y) (((x)>>(y)) & 1ll)
//#define move(n) (1<<(n))
#define what_is(x) cerr << #x << " is " << x << endl;
#define eb emplace_back
#define pb push_back
#define UNQ(x) (sort(begin(x),end(x)),x.erase(unique(begin(x),end(x)),end(x)))
const int N = 1e6 + 5;
int n,idx = 0;
map<string,int>M;
string ink[N];
int getIdx(string &x){
    if(M.find(x) == M.end()) {
        M[x] = idx++;
        ink[idx - 1] = x;
    }
    return M[x];
}
vector<tuple<char,int,int>>E[N];
int in[N],out[N],used[N];
void gao(int rt,int pre) {
    used[rt] = 1;
    char a;
    int b,c;
    for(auto x : E[rt]) {
        std::tie(a,b,c) = x;
        if(b != pre && used[b] == 0) gao(b,rt);
    }
    return;
}
int f[N];
void getans(int rt,string &S) {
    char a;
    int b,c;
    for(auto &x : E[rt]) {
        std::tie(a,b,c) = x;
        if(f[c] == 0) {
            f[c] = 1;
            S += a;
            getans(b,S);
        }
    }
    return;
}
map<string,int>chk;
int main(){
    cin>>n;
    for(int i = 0;i < n;i++) {
        string tmp;
        cin>>tmp;
        string L = "";L += tmp[0];L += tmp[1];
        string R = "";R += tmp[1];R += tmp[2];
        int Lidx = getIdx(L),Ridx = getIdx(R);
        E[Lidx].eb(tmp[2],Ridx,i);
        in[Ridx]++;
        out[Lidx]++;
        chk[tmp]++;
    }
    int s = -1;
    int t = 0;
    for(int i = 0;i < idx;i++) {
        //printf("%s : %d %d\n",ink[i].c_str(),in[i],out[i]);
        int d = abs(in[i] - out[i]);
        if(d > 1) {
            printf("NO\n");
            return 0;
        }
        if(out[i] == in[i] + 1) {
            if(s != -1) {
                printf("NO\n");
                return 0;
            }else s = i;
        }
        if(in[i] == out[i] + 1) {
            t++;
        }
    }
    if(s == -1) {
        s = 0;
    }
    gao(s,-1);
    for(int i = 0;i < idx;i++) {
        if(used[i] == 0) {
            printf("NO\n");
            return 0;
        }
    }
    string Ret = "";
    Ret += ink[s][0];Ret += ink[s][1];
    getans(s,Ret);
    if(Ret.length() != n + 2) {
        printf("NO\n");
        return 0;
    }
    cout<<"YES"<<endl;
    cout<<Ret<<endl;
    for(int i = 2;i < Ret.length();i++) {
        string tmp = "";
        tmp += Ret[i];tmp += Ret[i-1];tmp += Ret[i-2];
        if(chk.find(tmp) != chk.end()) {
            cout<<"cannot find "<<tmp<<endl;
        }else {
            if(chk[tmp] == 0) {
                cout<<"not enough " << tmp << endl;
            }else {
                chk[tmp]--;
            }
        }
    }
    return 0;
}


#include <iostream>
#include <utility>
#include <algorithm>
#include <memory.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <numeric>
#include <list>
#include <stack>
#include <cmath>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
using namespace std;

typedef  long long LL;
const int Mod = 1e9 + 7;
inline int FIX(LL a) {return (a % Mod + Mod) % Mod;}
#define MP(x,y) make_pair(x,y)
#define LEN(x) ((int)x.length())
#define SZ(x) ((int)x.size())
#define take(x,y) (((x)>>(y)) & 1ll)
//#define move(n) (1<<(n))
#define what_is(x) cerr << #x << " is " << x << endl;
#define eb emplace_back
#define pb push_back
#define UNQ(x) (sort(begin(x),end(x)),x.erase(unique(begin(x),end(x)),end(x)))
const int N = 1e6 + 5;
int n,idx = 0;
map<string,int>M;
string ink[N];
int getIdx(string x){
    if(M.find(x) == M.end()) {
        M[x] = idx++;
        ink[idx - 1] = x;
    }
    return M[x];
}
vector<pair<char,int>>E[N];
int in[N],out[N],used[N];
void gao(int rt,int pre) {
    used[rt] = 1;
    for(auto x : E[rt]) {
        if(x.second != pre && used[x.second] == 0) gao(x.second,rt);
    }
    return;
}
int start[N];
string input[N];
string S;
void getans(int rt) {
    for(;start[rt] < E[rt].size();) {
        auto x = E[rt][start[rt]++];
        S += x.first;
        /*string chk;chk += ink[rt][1];
        chk += x.first;

        if(chk != ink[x.second]) {
            cout<<chk<<" " <<ink[x.second]<<endl;
        }*/
        /*string chk;chk += S[S.length() - 2];
        chk += S[S.length() - 1];
        if(chk == "sP") {
            cout<<ink[rt]<<endl;
            cout<<ink[x.second]<<endl;
        }*/
        getans(x.second);
    }
    return;
}
map<string,int>chk;
int main(){
    cin>>n;
    for(int i = 0;i < n;i++) {
        string tmp;
        cin>>tmp;
        string L = "";L += tmp[0];L += tmp[1];
        string R = "";R += tmp[1];R += tmp[2];
        int Lidx = getIdx(L),Ridx = getIdx(R);
        E[Lidx].eb(tmp[2],Ridx);
        in[Ridx]++;
        out[Lidx]++;
        chk[tmp]++;
        input[i] = tmp;
    }

    int s = -1;
    int t = 0;
    for(int i = 0;i < idx;i++) {
        int d = abs(in[i] - out[i]);
        if(d > 1) {
            printf("NO\n");
            return 0;
        }
        if(out[i] == in[i] + 1) {
            if(s != -1) {
                printf("NO\n");
                return 0;
            }else s = i;
        }
        if(in[i] == out[i] + 1) {
            t++;
        }
    }
    if(s == -1) {
        s = 0;
    }
    gao(s,-1);
    for(int i = 0;i < idx;i++) {
        if(used[i] == 0) {
            printf("NO\n");
            return 0;
        }
    }
    string &Ret = S;
    Ret += ink[s][0];Ret += ink[s][1];
    getans(s);
    if(Ret.length() != n + 2) {
        printf("NO\n");
        return 0;
    }
    cout<<"YES"<<endl;
    for(int i = 2;i < Ret.length();i++) {
        string tmp = "";
        tmp += Ret[i-2];tmp += Ret[i-1];tmp += Ret[i];
        if(chk.find(tmp) == chk.end()) {
            cout<<"cannot find "<<tmp<<endl;
        }else {
            if(chk[tmp] == 0) {
                cout<<"not enough " << tmp << endl;
            }else {
                chk[tmp]--;
            }
        }
    }
    cout<<Ret<<endl;
    return 0;
}