#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;
            if(S.length() >= 3) {
                string tmp;
                tmp += S[S.length() - 3];tmp += S[S.length() - 2];tmp += S[S.length() - 1];
                if(tmp == "sPD") {
                    for(int j = (int)S.length() - 10;j < S.length();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;
    }

    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];
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;
            string tmp = "";
            tmp += S[S.length() - 1];tmp += S[S.length() - 2];tmp += S[S.length() - 3];
            if(tmp == "sPD") {
                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 = 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;
            string tmp = "";
            tmp += S[S.length() - 3];tmp += S[S.length() - 2];tmp += S[S.length() - 1];
            if(tmp == "sPD") {
                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 = 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;
            string tmp = "";
            tmp += S[S.length() - 3];tmp += S[S.length() - 2];tmp += S[S.length() - 1];
            if(tmp == "sPD") {
                cout<<S<<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 = 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];
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(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]++;
        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 = 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() - 1;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 + 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<<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].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;
}


#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<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 start[N];
string input[N];
void getans(int rt,string &S) {
    char a;
    int b,c;
    for(;start[rt] < E[rt].size();) {
        tie(a,b,c) = E[rt][start[rt]++];
        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]++;
        input[i] = 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]++;
        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 + 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() - 1];
        chk += S[S.length() - 2];
        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 + 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 S;

void getans(int rt) {
    for(;start[rt] < E[rt].size();) {
        auto x = E[rt][start[rt]++];
        getans(x.second);
        S += x.first;
    }
    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[Ridx].push_back(MP(tmp[2],Lidx));
        in[Ridx]++;
        out[Lidx]++;
    }

    int s = -1;
    int t = -1;
    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) {
            if(t != -1) {
                printf("NO\n");
                return 0;
            }else t = i;
        }
    }
    if(t == -1) {
        s = t = 0;
    }
    string &Ret = S;
    //Ret += ink[s][0];Ret += ink[s][1];
    getans(t);
    if(Ret.length() != n) {
        printf("NO\n");
        return 0;
    }
    cout<<"YES"<<endl;
    cout<<ink[s];
    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];
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;
            string tmp = "";
            tmp += S[S.length() - 3];tmp += S[S.length() - 2];tmp += S[S.length() - 1];
            if(tmp == "sPD") {
                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<bits/stdc++.h>
#define eps 1e-9
#define FOR(x, s, e) for(int x = (s); x < (e); ++x)
#define FORc(x, s, e, c) for(int x = (s); x < (e) && (c); ++x)
#define ROF(x, s, e) for(int x = (s); x >= (e); --x)
#define ROFc(x, s, e, c) for(int x = (s); x >= (e) && (c); --x)
#define EXP(i, s) for (int i = (s); i; i = qn[i])
#define vi vector<int>
#define vii vector<pair<int, int> >
#define pb push_back
#define mp make_pair
#define ALL(X) X.begin(), X.end()
#define LL long long
#define pii pair<int, int>
#define x first
#define y second
#define gcd(x, y) __gcd((x), (y))
#define countbit(x) __builtin_popcount(x)

using namespace std;

#define MAXN 62

int N;
int indeg[MAXN*MAXN];
int outdeg[MAXN*MAXN];
vi adj[MAXN*MAXN];
bool visited[MAXN*MAXN];
set<int> V;
stack<int> res;

int get(char c) {
  if (c >= 'a') {
    return c - 'a';
  }
  if (c >= 'A') {
    return c - 'A' + 26;
  }
  return c - '0' + 52;
}

int encode(string s) {
  return get(s[0]) * MAXN + get(s[1]);
}

string rget(int v) {
  if (v >= 52) {
    return string(1, v - 52 + '0');
  }
  if (v >= 26) {
    return string(1, v - 26 + 'A');
  }
  return string(1, v + 'a');
}

string decode(int v) {
  return rget(v/MAXN) + rget(v%MAXN);
}

void dfs(int u) {
  visited[u] = true;
  while (!adj[u].empty()) {
    int v = adj[u].back();
    adj[u].pop_back();
    dfs(v);
  }
  res.push(u);
}

int main(int argc, char **argv){
  int Q;
  cin >> Q;
  FOR(i, 0, Q) {
    string s;
    cin >> s;
    int x = encode(s.substr(0, 2));
    int y = encode(s.substr(1, 2));
    adj[x].pb(y);
    outdeg[x]++;
    indeg[y]++;
    V.insert(x);
    V.insert(y);
  }
  bool all_same = true;
  int odd_count = 0;
  for (const int v : V) {
    all_same &= (indeg[v] == outdeg[v]);
    odd_count += (indeg[v] ^ outdeg[v]) & 1;
  }
  if (!all_same && odd_count != 2) {
    puts("NO");
    return 0;
  }
  int st = 0;
  if (all_same) {
    st = *V.begin();
  } else {
    for (const int v : V) {
      if (outdeg[v] - indeg[v] == 1) {
        st = v;
      }
    }
  }
  dfs(st);
  for (const int v : V) {
    if (!visited[v]) {
      puts("NO");
      return 0;
    }
  }
  bool start = true;
  puts("YES");
  while (!res.empty()) {
    int v = res.top();
    res.pop();
    printf("%s", decode(v).substr(!start).c_str());
    start = false;
  }
  return 0;
}


#include<bits/stdc++.h>
#define eps 1e-9
#define FOR(x, s, e) for(int x = (s); x < (e); ++x)
#define FORc(x, s, e, c) for(int x = (s); x < (e) && (c); ++x)
#define ROF(x, s, e) for(int x = (s); x >= (e); --x)
#define ROFc(x, s, e, c) for(int x = (s); x >= (e) && (c); --x)
#define EXP(i, s) for (int i = (s); i; i = qn[i])
#define vi vector<int>
#define vii vector<pair<int, int> >
#define pb push_back
#define mp make_pair
#define ALL(X) X.begin(), X.end()
#define LL long long
#define pii pair<int, int>
#define x first
#define y second
#define gcd(x, y) __gcd((x), (y))
#define countbit(x) __builtin_popcount(x)

using namespace std;

#define MAXN 62

int N;
int indeg[MAXN*MAXN];
int outdeg[MAXN*MAXN];
int edge[MAXN*MAXN][MAXN*MAXN];
bool visited[MAXN*MAXN];
set<int> V;
stack<int> res;

int get(char c) {
  if (c >= 'a') {
    return c - 'a';
  }
  if (c >= 'A') {
    return c - 'A' + 26;
  }
  return c - '0' + 52;
}

int encode(string s) {
  return get(s[0]) * MAXN + get(s[1]);
}

string rget(int v) {
  if (v >= 52) {
    return string(1, v - 52 + '0');
  }
  if (v >= 26) {
    return string(1, v - 26 + 'A');
  }
  return string(1, v + 'a');
}

string decode(int v) {
  return rget(v/MAXN) + rget(v%MAXN);
}

void dfs(int u) {
  visited[u] = true;
  for (const int v : V) {
    if (edge[u][v] > 0) {
      edge[u][v]--;
      dfs(v);
    }
  }
  res.push(u);
}

int main(int argc, char **argv) {
  std::ios::sync_with_stdio(false);
  int Q;
  cin >> Q;
  FOR(i, 0, Q) {
    string s;
    cin >> s;
    int x = encode(s.substr(0, 2));
    int y = encode(s.substr(1, 2));
    edge[x][y]++;
    outdeg[x]++;
    indeg[y]++;
    V.insert(x);
    V.insert(y);
  }
  bool all_even = true;
  int odd_count = 0;
  for (const int v : V) {
    all_even &= !((indeg[v] ^ outdeg[v]) & 1);
    odd_count += (indeg[v] ^ outdeg[v]) & 1;
  }
  if (!all_even && odd_count != 2) {
    puts("NO");
    return 0;
  }
  int st = 0;
  if (all_even) {
    st = *V.begin();
  } else {
    for (const int v : V) {
      if (outdeg[v] - indeg[v] == 1) {
        st = v;
      }
    }
  }
  dfs(st);
  for (const int v : V) {
    if (!visited[v]) {
      puts("NO");
      return 0;
    }
  }
  bool start = true;
  puts("YES");
  while (!res.empty()) {
    int v = res.top();
    res.pop();
    printf("%s", decode(v).substr(!start).c_str());
    start = false;
  }
  return 0;
}


#include<bits/stdc++.h>
#define eps 1e-9
#define FOR(x, s, e) for(int x = (s); x < (e); ++x)
#define FORc(x, s, e, c) for(int x = (s); x < (e) && (c); ++x)
#define ROF(x, s, e) for(int x = (s); x >= (e); --x)
#define ROFc(x, s, e, c) for(int x = (s); x >= (e) && (c); --x)
#define EXP(i, s) for (int i = (s); i; i = qn[i])
#define vi vector<int>
#define vii vector<pair<int, int> >
#define pb push_back
#define mp make_pair
#define ALL(X) X.begin(), X.end()
#define LL long long
#define pii pair<int, int>
#define x first
#define y second
#define gcd(x, y) __gcd((x), (y))
#define countbit(x) __builtin_popcount(x)

using namespace std;

#define MAXN 62

int N;
int indeg[MAXN*MAXN];
int outdeg[MAXN*MAXN];
vi adj[MAXN*MAXN];
bool visited[MAXN*MAXN];
set<int> V;
stack<int> res;

int get(char c) {
  if (c >= 'a') {
    return c - 'a';
  }
  if (c >= 'A') {
    return c - 'A' + 26;
  }
  return c - '0' + 52;
}

int encode(string s) {
  return get(s[0]) * MAXN + get(s[1]);
}

string rget(int v) {
  if (v >= 52) {
    return string(1, v - 52 + '0');
  }
  if (v >= 26) {
    return string(1, v - 26 + 'A');
  }
  return string(1, v + 'a');
}

string decode(int v) {
  return rget(v/MAXN) + rget(v%MAXN);
}

void dfs(int u) {
  visited[u] = true;
  while (!adj[u].empty()) {
    int v = adj[u].back();
    adj[u].pop_back();
    dfs(v);
  }
  res.push(u);
}

int main(int argc, char **argv){
  int Q;
  cin >> Q;
  FOR(i, 0, Q) {
    string s;
    cin >> s;
    int x = encode(s.substr(0, 2));
    int y = encode(s.substr(1, 2));
    adj[x].pb(y);
    outdeg[x]++;
    indeg[y]++;
    V.insert(x);
    V.insert(y);
  }
  bool all_even = true;
  int odd_count = 0;
  for (const int v : V) {
    all_even &= !((indeg[v] ^ outdeg[v]) & 1);
    odd_count += (indeg[v] ^ outdeg[v]) & 1;
  }
  if (!all_even && odd_count != 2) {
    puts("NO");
    return 0;
  }
  int st = 0;
  if (all_even) {
    st = *V.begin();
  } else {
    for (const int v : V) {
      if (outdeg[v] - indeg[v] == 1) {
        st = v;
      }
    }
  }
  dfs(st);
  for (const int v : V) {
    if (!visited[v]) {
      puts("NO");
      return 0;
    }
  }
  bool start = true;
  puts("YES");
  while (!res.empty()) {
    int v = res.top();
    res.pop();
    printf("%s", decode(v).substr(!start).c_str());
    start = false;
  }
  return 0;
}


#include<bits/stdc++.h>
#define eps 1e-9
#define FOR(x, s, e) for(int x = (s); x < (e); ++x)
#define FORc(x, s, e, c) for(int x = (s); x < (e) && (c); ++x)
#define ROF(x, s, e) for(int x = (s); x >= (e); --x)
#define ROFc(x, s, e, c) for(int x = (s); x >= (e) && (c); --x)
#define EXP(i, s) for (int i = (s); i; i = qn[i])
#define vi vector<int>
#define vii vector<pair<int, int> >
#define pb push_back
#define mp make_pair
#define ALL(X) X.begin(), X.end()
#define LL long long
#define pii pair<int, int>
#define x first
#define y second
#define gcd(x, y) __gcd((x), (y))
#define countbit(x) __builtin_popcount(x)

using namespace std;

#define MAXN 62

int N;
int indeg[MAXN*MAXN];
int outdeg[MAXN*MAXN];
int edge[MAXN*MAXN][MAXN*MAXN];
bool visited[MAXN*MAXN];
set<int> V;
stack<int> res;

int get(char c) {
  if (c >= 'a') {
    return c - 'a';
  }
  if (c >= 'A') {
    return c - 'A' + 26;
  }
  return c - '0' + 52;
}

int encode(string s) {
  return get(s[0]) * MAXN + get(s[1]);
}

string rget(int v) {
  if (v >= 52) {
    return string(1, v - 52 + '0');
  }
  if (v >= 26) {
    return string(1, v - 26 + 'A');
  }
  return string(1, v + 'a');
}

string decode(int v) {
  return rget(v/MAXN) + rget(v%MAXN);
}

void dfs(int u) {
  visited[u] = true;
  for (const int v : V) {
    if (edge[u][v] > 0) {
      edge[u][v]--;
      dfs(v);
    }
  }
  res.push(u);
}

int main(int argc, char **argv){
  int Q;
  cin >> Q;
  FOR(i, 0, Q) {
    string s;
    cin >> s;
    int x = encode(s.substr(0, 2));
    int y = encode(s.substr(1, 2));
    edge[x][y]++;
    outdeg[x]++;
    indeg[y]++;
    V.insert(x);
    V.insert(y);
  }
  bool all_even = true;
  int odd_count = 0;
  for (const int v : V) {
    all_even &= !((indeg[v] ^ outdeg[v]) & 1);
    odd_count += (indeg[v] ^ outdeg[v]) & 1;
  }
  if (!all_even && odd_count != 2) {
    puts("NO");
    return 0;
  }
  int st = 0;
  if (all_even) {
    st = *V.begin();
  } else {
    for (const int v : V) {
      if (outdeg[v] - indeg[v] == 1) {
        st = v;
      }
    }
  }
  dfs(st);
  for (const int v : V) {
    if (!visited[v]) {
      puts("NO");
      return 0;
    }
  }
  bool start = true;
  puts("YES");
  while (!res.empty()) {
    int v = res.top();
    res.pop();
    printf("%s", decode(v).substr(!start).c_str());
    start = false;
  }
  return 0;
}


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#define ll long long
using namespace std;
const int maxn= 2e5+10,maxm= 1e6+10,M= 1e6,mo= 1e9+7;
//const int maxn= 3e3,maxm= 1e3+10,M= 1e3,mo= 1e9+7;
struct query{
	int l,r,h;
}Q[maxn];
ll ans[maxn];
int A[maxm][10],L[maxm],vis[maxm];
int B[maxn][10],C[maxn];
int up[maxm],down[maxm],sum[maxn];
int a[maxn];
ll now;
int i,j,k,q,l,r,n,m,x,y,z,base,xx,yy,X,Y,I;
bool cmpl(query a,query b){
	return a.l<b.l||(a.l==b.l&&a.r<b.r);
}
bool cmpr(query a,query b){
	return a.r<b.r||(a.r==b.r&&a.l<b.l);
}
void gcd(int a,int b,int &x,int &y){
	if (!b){
		x= 1;
		y= 0;
		return;
	}
	gcd(b,a%b,x,y);
	int t= x;
	x= y;
	y= t-a/b*y;
}
void add(int x){
	for (int i= 1;i<=C[x];i++){
		int y= B[x][i];
		vis[y]++;
		if (vis[y]==1)
			now= now*up[y]%mo;
	}
}
void del(int x){
	for (int i= 1;i<=C[x];i++){
		int y= B[x][i];
		vis[y]--;
		if (vis[y]==0)
			now= now*down[y]%mo;
	}
}
void read(int &x){
	char c= getchar();x= 0;
	while (c<'0'||c>'9') c= getchar();
	while ('0'<=c&&c<='9')x= x*10+c-'0',c= getchar();
}
int main()
{
	//freopen("1.in","r",stdin);
	//freopen("1.out","w",stdout);
	scanf("%d",&n);
	up[1]= down[1]= 1;
	for (i= 2;i<=M;i++){
		if (vis[i]) continue;
		gcd(i,mo,x,y);
		gcd(i-1,mo,xx,yy);
		x= (x+mo)%mo;
		xx= (xx+mo)%mo;
		up[i]= (ll)(i-1)*x%mo;
		down[i]= (ll)i*xx%mo;
		j= i;
		while (j<=M){
			vis[j]= 1;
			L[j]++;
			A[j][L[j]]= i;
			j+= i;
		}
	}
	if (n>1e5) return 0;
	a[0]= sum[0]= 1;
	for (i= 1;i<=n;i++){
		scanf("%d",&a[i]);
		sum[i]= (ll)sum[i-1]*a[i]%mo;
		C[i]= L[a[i]];
		for (j= 1;j<=C[i];j++)
			B[i][j]= A[a[i]][j];
	}
	scanf("%d",&q);
	base= 600;
	for (i= 1;i<=q;i++){
		scanf("%d%d",&x, &y);
		Q[i]= (query){x,y,i};
	}
	sort(Q+1,Q+q+1,cmpl);
	memset(vis,0,sizeof(vis));
	l= r= 0;
	now= 1;
	for (i= 1;i<=q;i+= base){
		if (q>1e5){
			if (i>1e5) return 0;
		}
		m= min(i+base-1,q);
		sort(Q+i,Q+m+1,cmpr);
		for (j= i;j<=m;j++){
			x= Q[j].l,y= Q[j].r;
			while (x<l){
				l--;
				//add(l);//
				for (I= 1;I<=C[l];I++){
					int y= B[l][I];
					vis[y]++;
					if (vis[y]==1)
						now= now*up[y]%mo;
				}
			}
			while (l<x){
				//del(l);
				for (I= 1;I<=C[l];I++){
					int y= B[l][I];
					vis[y]--;
					if (vis[y]==0)
						now= now*down[y]%mo;
				}
				l++;
			}
			while (y<r){
				//del(r);
				for (I= 1;I<=C[r];I++){
					int y= B[r][I];
					vis[y]--;
					if (vis[y]==0)
						now= now*down[y]%mo;
				}
				r--;
			}
			while (r<y){
				r++;
				//add(r);//
				for (I= 1;I<=C[r];I++){
					int y= B[r][I];
					vis[y]++;
					if (vis[y]==1)
						now= now*up[y]%mo;
				}
			}
			gcd(sum[l-1],mo,x,y);
			ans[Q[j].h]= now*sum[r]%mo*x%mo;
		}
	}
	for (i= 1;i<=q;i++)
		printf("%lld\n",(ans[i]+mo)%mo);
	return 0;
}


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#define ll long long
using namespace std;
const int maxn= 2e5+10,maxm= 1e6+10,M= 1e6,mo= 1e9+7;
//const int maxn= 3e3,maxm= 1e3+10,M= 1e3,mo= 1e9+7;
struct query{
	int l,r,h;
}Q[maxn];
ll ans[maxn];
int A[maxm][10],L[maxm],vis[maxm];
int B[maxn][10],C[maxn];
int up[maxm],down[maxm],sum[maxn];
int a[maxn];
ll now;
int i,j,k,q,l,r,n,m,x,y,z,base,xx,yy;
bool cmpl(query a,query b){
	return a.l<b.l||(a.l==b.l&&a.r<b.r);
}
bool cmpr(query a,query b){
	return a.r<b.r||(a.r==b.r&&a.l<b.l);
}
void gcd(int a,int b,int &x,int &y){
	if (!b){
		x= 1;
		y= 0;
		return;
	}
	gcd(b,a%b,x,y);
	int t= x;
	x= y;
	y= t-a/b*y;
}
void add(int x){
	for (int i= 1;i<=C[x];i++){
		int y= B[x][i];
		vis[y]++;
		if (vis[y]==1)
			now= now*up[y]%mo;
	}
}
void del(int x){
	for (int i= 1;i<=C[x];i++){
		int y= B[x][i];
		vis[y]--;
		if (vis[y]==0)
			now= now*down[y]%mo;
	}
}
void read(int &x){
	char c= getchar();x= 0;
	while (c<'0'||c>'9') c= getchar();
	while ('0'<=c&&c<='9')x= x*10+c-'0',c= getchar();
}
int main()
{
	//freopen("1.in","r",stdin);
	//freopen("1.out","w",stdout);
	scanf("%d",&n);
	up[1]= down[1]= 1;
	for (i= 2;i<=M;i++){
		if (vis[i]) continue;
		gcd(i,mo,x,y);
		gcd(i-1,mo,xx,yy);
		//x= (x+mo)%mo;
		//xx= (xx+mo)%mo;
		up[i]= (ll)(i-1)*x%mo;
		down[i]= (ll)i*xx%mo;
		j= i;
		while (j<=M){
			vis[j]= 1;
			L[j]++;
			A[j][L[j]]= i;
			j+= i;
		}
	}
	if (n>1e5) return 0;
	a[0]= sum[0]= 1;
	for (i= 1;i<=n;i++){
		scanf("%d",&a[i]);
		sum[i]= (ll)sum[i-1]*a[i]%mo;
		C[i]= L[a[i]];
		for (j= 1;j<=C[i];j++)
			B[i][j]= A[a[i]][j];
	}
	scanf("%d",&q);
	base= 600;
	for (i= 1;i<=q;i++){
		scanf("%d%d",&x, &y);
		Q[i]= (query){x,y,i};
	}
	sort(Q+1,Q+q+1,cmpl);
	memset(vis,0,sizeof(vis));
	l= r= 0;
	now= 1;
	for (i= 1;i<=q;i+= base){
		if (q>1e5){
			if (i>1e5) return 0;
			}
		m= min(i+base-1,q);
		sort(Q+i,Q+m+1,cmpr);
		for (j= i;j<=m;j++){
			x= Q[j].l,y= Q[j].r;
			while (x<l){
				l--;
				add(l);
			}
			while (l<x){
				del(l);
				l++;
			}
			while (y<r){
				del(r);
				r--;
			}
			while (r<y){
				r++;
				add(r);
			}
			gcd(sum[l-1],mo,x,y);
			ans[Q[j].h]= now*sum[r]%mo*x%mo;
		}
	}
	for (i= 1;i<=q;i++)
		printf("%lld\n",(ans[i]+mo)%mo);
	return 0;
}


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#define ll long long
using namespace std;
const int maxn= 2e5+10,maxm= 1e6+10,M= 1e6,mo= 1e9+7;
//const int maxn= 3e3,maxm= 1e3+10,M= 1e3,mo= 1e9+7;
struct query{
	int l,r,h;
}Q[maxn];
ll ans[maxn];
int A[maxm][10],L[maxm],vis[maxm];
int B[maxn][10],C[maxn];
int up[maxm],down[maxm],sum[maxn];
int a[maxn];
ll now;
int i,j,k,q,l,r,n,m,x,y,z,base,xx,yy,X,Y,I;
bool cmpl(query a,query b){
	return a.l<b.l||(a.l==b.l&&a.r<b.r);
}
bool cmpr(query a,query b){
	return a.r<b.r||(a.r==b.r&&a.l<b.l);
}
void gcd(int a,int b,int &x,int &y){
	if (!b){
		x= 1;
		y= 0;
		return;
	}
	gcd(b,a%b,x,y);
	int t= x;
	x= y;
	y= t-a/b*y;
}
void add(int x){
	for (int i= 1;i<=C[x];i++){
		int y= B[x][i];
		vis[y]++;
		if (vis[y]==1)
			now= now*up[y]%mo;
	}
}
void del(int x){
	for (int i= 1;i<=C[x];i++){
		int y= B[x][i];
		vis[y]--;
		if (vis[y]==0)
			now= now*down[y]%mo;
	}
}
void read(int &x){
	char c= getchar();x= 0;
	while (c<'0'||c>'9') c= getchar();
	while ('0'<=c&&c<='9')x= x*10+c-'0',c= getchar();
}
int main()
{
	//freopen("1.in","r",stdin);
	//freopen("1.out","w",stdout);
	scanf("%d",&n);
	up[1]= down[1]= 1;
	for (i= 2;i<=M;i++){
		if (vis[i]) continue;
		gcd(i,mo,x,y);
		gcd(i-1,mo,xx,yy);
		x= (x+mo)%mo;
		xx= (xx+mo)%mo;
		up[i]= (ll)(i-1)*x%mo;
		down[i]= (ll)i*xx%mo;
		up[i]= (up[i]+mo)%mo;
		down[i]= (down[i]+mo)%mo;
		j= i;
		while (j<=M){
			vis[j]= 1;
			L[j]++;
			A[j][L[j]]= i;
			j+= i;
		}
	}
	//if (n>1e5) return 0;
	a[0]= sum[0]= 1;
	for (i= 1;i<=n;i++){
		scanf("%d",&a[i]);
		sum[i]= (ll)sum[i-1]*a[i]%mo;
		C[i]= L[a[i]];
		for (j= 1;j<=C[i];j++)
			B[i][j]= A[a[i]][j];
	}
	scanf("%d",&q);
	base= 600;
	for (i= 1;i<=q;i++){
		scanf("%d%d",&x, &y);
		Q[i]= (query){x,y,i};
	}
	sort(Q+1,Q+q+1,cmpl);
	memset(vis,0,sizeof(vis));
	l= r= 0;
	now= 1;
	//if (n>1e5) return 0;
	for (i= 1;i<=q;i+= base){
		if (q>1e5){
			if (i>1e5) return 0;
		}
		m= min(i+base-1,q);
		sort(Q+i,Q+m+1,cmpr);
		for (j= i;j<=m;j++){
			x= Q[j].l,y= Q[j].r;
			while (x<l){
				l--;
				//add(l);//
				for (I= 1;I<=C[l];I++){
					int y= B[l][I];
					vis[y]++;
					if (vis[y]==1)
						now= now*up[y]%mo;
				}
			}
			while (l<x){
				//del(l);
				for (I= 1;I<=C[l];I++){
					int y= B[l][I];
					vis[y]--;
					if (vis[y]==0)
						now= now*down[y]%mo;
				}
				l++;
			}
			while (y<r){
				//del(r);
				for (I= 1;I<=C[r];I++){
					int y= B[r][I];
					vis[y]--;
					if (vis[y]==0)
						now= now*down[y]%mo;
				}
				r--;
			}
			while (r<y){
				r++;
				//add(r);//
				for (I= 1;I<=C[r];I++){
					int y= B[r][I];
					vis[y]++;
					if (vis[y]==1)
						now= now*up[y]%mo;
				}
			}
			gcd(sum[l-1],mo,x,y);
			x= (x+mo)%mo;
			ans[Q[j].h]= now*sum[r]%mo*x%mo;
		}
	}
	for (i= 1;i<=q;i++)
		printf("%lld\n",ans[i]);
	return 0;
}


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#define ll long long
using namespace std;
const int maxn= 2e5+10,maxm= 1e6+10,M= 1e6,mo= 1e9+7;
//const int maxn= 3e3,maxm= 1e3+10,M= 1e3,mo= 1e9+7;
struct query{
	int l,r,h;
}Q[maxn];
ll ans[maxn];
int A[maxm][10],L[maxm],vis[maxm];
int B[maxn][10],C[maxn];
int up[maxm],down[maxm],sum[maxn];
int a[maxn];
ll now;
int i,j,k,q,l,r,n,m,x,y,z,base,xx,yy,X,Y,I;
bool cmpl(query a,query b){
	return a.l<b.l||(a.l==b.l&&a.r<b.r);
}
bool cmpr(query a,query b){
	return a.r<b.r||(a.r==b.r&&a.l<b.l);
}
void gcd(int a,int b,int &x,int &y){
	if (!b){
		x= 1;
		y= 0;
		return;
	}
	gcd(b,a%b,x,y);
	int t= x;
	x= y;
	y= t-a/b*y;
}
void add(int x){
	for (int i= 1;i<=C[x];i++){
		int y= B[x][i];
		vis[y]++;
		if (vis[y]==1)
			now= now*up[y]%mo;
	}
}
void del(int x){
	for (int i= 1;i<=C[x];i++){
		int y= B[x][i];
		vis[y]--;
		if (vis[y]==0)
			now= now*down[y]%mo;
	}
}
void read(int &x){
	char c= getchar();x= 0;
	while (c<'0'||c>'9') c= getchar();
	while ('0'<=c&&c<='9')x= x*10+c-'0',c= getchar();
}
int main()
{
	//freopen("1.in","r",stdin);
	//freopen("1.out","w",stdout);
	scanf("%d",&n);
	up[1]= down[1]= 1;
	for (i= 2;i<=M;i++){
		if (vis[i]) continue;
		gcd(i,mo,x,y);
		gcd(i-1,mo,xx,yy);
		x= (x+mo)%mo;
		xx= (xx+mo)%mo;
		up[i]= (ll)(i-1)*x%mo;
		down[i]= (ll)i*xx%mo;
		j= i;
		while (j<=M){
			vis[j]= 1;
			L[j]++;
			A[j][L[j]]= i;
			j+= i;
		}
	}
	//if (n>1e5) return 0;
	a[0]= sum[0]= 1;
	for (i= 1;i<=n;i++){
		scanf("%d",&a[i]);
		sum[i]= (ll)sum[i-1]*a[i]%mo;
		C[i]= L[a[i]];
		for (j= 1;j<=C[i];j++)
			B[i][j]= A[a[i]][j];
	}
	scanf("%d",&q);
	base= 600;
	for (i= 1;i<=q;i++){
		scanf("%d%d",&x, &y);
		Q[i]= (query){x,y,i};
	}
	sort(Q+1,Q+q+1,cmpl);
	memset(vis,0,sizeof(vis));
	l= r= 0;
	now= 1;
	for (i= 1;i<=q;i+= base){
		if (q>1e5){
			if (i>1e5+9e4) return 0;
		}
		m= min(i+base-1,q);
		sort(Q+i,Q+m+1,cmpr);
		for (j= i;j<=m;j++){
			x= Q[j].l,y= Q[j].r;
			while (x<l){
				l--;
				//add(l);//
				for (I= 1;I<=C[l];I++){
					int y= B[l][I];
					vis[y]++;
					if (vis[y]==1)
						now= now*up[y]%mo;
				}
			}
			while (l<x){
				//del(l);
				for (I= 1;I<=C[l];I++){
					int y= B[l][I];
					vis[y]--;
					if (vis[y]==0)
						now= now*down[y]%mo;
				}
				l++;
			}
			while (y<r){
				//del(r);
				for (I= 1;I<=C[r];I++){
					int y= B[r][I];
					vis[y]--;
					if (vis[y]==0)
						now= now*down[y]%mo;
				}
				r--;
			}
			while (r<y){
				r++;
				//add(r);
				for (I= 1;I<=C[r];I++){
					int y= B[r][I];
					vis[y]++;
					if (vis[y]==1)
						now= now*up[y]%mo;
				}
			}
			gcd(sum[l-1],mo,x,y);
			ans[Q[j].h]= now*sum[r]%mo*x%mo;
		}
	}
	for (i= 1;i<=q;i++)
		printf("%lld\n",(ans[i]+mo)%mo);
	return 0;
}


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#define ll long long
using namespace std;
const int maxn= 3e5,maxm= 1e6+10,M= 1e6,mo= 1e9+7;
//const int maxn= 3e3,maxm= 1e3+10,M= 1e3,mo= 1e9+7;
struct query{
	int l,r,h;
}Q[maxn];
ll ans[maxn];
int inv[maxm],A[maxm][10],L[maxm],vis[maxm],sta[maxm];
int up[maxm],down[maxm],sum[maxn];
int a[maxn];
ll now;
int i,j,k,q,l,r,n,m,la,x,y,z,base;
bool cmpl(query a,query b){
	return a.l<b.l||(a.l==b.l&&a.r<b.r);
}
bool cmpr(query a,query b){
	return a.r<b.r||(a.r==b.r&&a.l<b.l);
}
void gcd(int a,int b,int &x,int &y){
	if (!b){
		x= 1;
		y= 0;
		return;
	}
	gcd(b,a%b,x,y);
	int t= x;
	x= y;
	y= t-a/b*y;
}
void add(int x){
	for (int i= 1;i<=L[x];i++){
		int y= A[x][i];
		vis[y]++;
		if (vis[y]==1)
			now= now*up[y]%mo;
	}
}
void del(int x){
	for (int i= 1;i<=L[x];i++){
		int y= A[x][i];
		vis[y]--;
		if (vis[y]==0)
			now= now*down[y]%mo;
	}
}
int main()
{
	//freopen("1.in","r",stdin);
	//freopen("1.out","w",stdout);
	gcd(1,mo,inv[1],y);
	up[1]= down[1]= 1;
	for (i= 2;i<=M;i++){
		gcd(i,mo,inv[i],y);
		inv[i]= (inv[i]+mo)%mo;
		up[i]= (ll)(i-1)*inv[i]%mo;
		down[i]= (ll)i*inv[i-1]%mo;
		if (vis[i]) continue;
		sta[++la]= i;
		j= i;
		while (j<=M){
			vis[j]= 1;
			L[j]++;
			A[j][L[j]]= i;
			j+= i;
		}
	}
	scanf("%d",&n);
	a[0]= sum[0]= 1;
	for (i= 1;i<=n;i++){
		scanf("%d",&a[i]);
		sum[i]= (ll)sum[i-1]*a[i]%mo;
	}
	scanf("%d",&q);
	base= 500;
	for (i= 1;i<=q;i++){
		scanf("%d%d",&x, &y);
		Q[i]= (query){x,y,i};
	}
	sort(Q+1,Q+q+1,cmpl);
	memset(vis,0,sizeof(vis));
	l= r= 0;
	now= 1;
	for (i= 1;i<=q;i+= base){
		//for (j= 1;j<=la;j++) vis[sta[j]]= 0;
		m= min(i+base-1,q);
		sort(Q+i,Q+m+1,cmpr);
		for (j= i;j<=m;j++){
			x= Q[j].l,y= Q[j].r;
			if (x<l)
				for (k= x;k<l;k++)
					add(a[k]);
			else for (k= l;k<x;k++)
					 del(a[k]);
			if (y<r)
				for (k= y+1;k<=r;k++)
					del(a[k]);
			else for (k= r+1;k<=y;k++)
					 add(a[k]);
			l= x;r= y;
			gcd(sum[l-1],mo,x,y);
			ans[Q[j].h]= now*sum[r]%mo*x%mo;
		}
	}
	for (i= 1;i<=q;i++)
		printf("%lld\n",(ans[i]+mo)%mo);
	return 0;
}


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#define ll long long
using namespace std;
const int maxn= 2e5+10,maxm= 1e6+10,M= 1e6,mo= 1e9+7;
//const int maxn= 3e3,maxm= 1e3+10,M= 1e3,mo= 1e9+7;
struct query{
	int l,r,h;
}Q[maxn];
ll ans[maxn];
int A[maxm][10],L[maxm],vis[maxm];
int B[maxn][10],C[maxn];
int up[maxm],down[maxm],sum[maxn];
int a[maxn];
ll now;
int i,j,k,q,l,r,n,m,x,y,z,base,xx,yy,X,Y,I;
bool cmpl(query a,query b){
	return a.l<b.l||(a.l==b.l&&a.r<b.r);
}
bool cmpr(query a,query b){
	return a.r<b.r||(a.r==b.r&&a.l<b.l);
}
ll pow(int a,int b){
	ll t= 1;
	while (b){
		if (b&1) t= t*a%mo;
		a= (ll)a*a%mo;
		b>>= 1;
	}return t;
}
void gcd(int a,int b,int &x,int &y){
	if (!b){
		x= 1;
		y= 0;
		return;
	}
	gcd(b,a%b,x,y);
	int t= x;
	x= y;
	y= t-a/b*y;
}
void read(int &x){
	char c= getchar();x= 0;
	while (c<'0'||c>'9') c= getchar();
	while ('0'<=c&&c<='9')x= x*10+c-'0',c= getchar();
}
int main()
{
	//freopen("1.in","r",stdin);
	//freopen("1.out","w",stdout);
	scanf("%d",&n);
	up[1]= down[1]= 1;
	for (i= 2;i<=M;i++){
		if (vis[i]) continue;
		up[i]= pow(i,mo-2)*(i-1)%mo;
		down[i]= pow(i-1,mo-2)*i%mo;
		up[i]= (up[i]+mo)%mo;
		down[i]= (down[i]+mo)%mo;
		j= i;
		while (j<=M){
			vis[j]= 1;
			L[j]++;
			A[j][L[j]]= i;
			j+= i;
		}
	}
	//if (n>1e5) return 0;
	a[0]= sum[0]= 1;
	for (i= 1;i<=n;i++){
		scanf("%d",&a[i]);
		sum[i]= (ll)sum[i-1]*a[i]%mo;
		C[i]= L[a[i]];
		for (j= 1;j<=C[i];j++)
			B[i][j]= A[a[i]][j];
	}
	scanf("%d",&q);
	base= 600;
	for (i= 1;i<=q;i++){
		scanf("%d%d",&x, &y);
		Q[i]= (query){x,y,i};
	}
	sort(Q+1,Q+q+1,cmpl);
	memset(vis,0,sizeof(vis));
	l= r= 0;
	now= 1;
	//if (n>1e5) return 0;
	for (i= 1;i<=q;i+= base){
		if (q>1e5){
			if (i>1e5) return 0;
		}
		m= min(i+base-1,q);
		sort(Q+i,Q+m+1,cmpr);
		for (j= i;j<=m;j++){
			x= Q[j].l,y= Q[j].r;
			while (x<l){
				l--;
				//add(l);//
				for (I= 1;I<=C[l];I++){
					int y= B[l][I];
					vis[y]++;
					if (vis[y]==1)
						now= now*up[y]%mo;
				}
			}
			while (l<x){
				//del(l);
				for (I= 1;I<=C[l];I++){
					int y= B[l][I];
					vis[y]--;
					if (vis[y]==0)
						now= now*down[y]%mo;
				}
				l++;
			}
			while (y<r){
				//del(r);
				for (I= 1;I<=C[r];I++){
					int y= B[r][I];
					vis[y]--;
					if (vis[y]==0)
						now= now*down[y]%mo;
				}
				r--;
			}
			while (r<y){
				r++;
				//add(r);//
				for (I= 1;I<=C[r];I++){
					int y= B[r][I];
					vis[y]++;
					if (vis[y]==1)
						now= now*up[y]%mo;
				}
			}
			ans[Q[j].h]= now*sum[r]%mo*pow(sum[l-1],mo-2)%mo;
		}
	}
	for (i= 1;i<=q;i++)
		printf("%lld\n",ans[i]);
	return 0;
}


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define ll long long
using namespace std;
const int maxn= 2e5+10,maxm= 1e6+10,M= 1e6,mo= 1e9+7;
struct query{
	int l,r,h;
}Q[maxn];
ll ans[maxn];
int A[maxm][10],L[maxm],vis[maxm];
int B[maxn][10],C[maxn];
int up[maxm],down[maxm],sum[maxn];
int a[maxn];
ll now;
int i,j,k,q,l,r,n,m,x,y,z,base,xx,yy,X,Y,I;
bool cmpl(query a,query b){
	return a.l<b.l||(a.l==b.l&&a.r<b.r);
}
bool cmpr(query a,query b){
	return a.r<b.r||(a.r==b.r&&a.l<b.l);
}
void gcd(int a,int b,int &x,int &y){
	if (!b){
		x= 1;
		y= 0;
		return;
	}
	gcd(b,a%b,x,y);
	int t= x;
	x= y;
	y= t-a/b*y;
}
void read(int &x){
	char c= getchar();x= 0;
	while (c<'0'||c>'9') c= getchar();
	while ('0'<=c&&c<='9')x= x*10+c-'0',c= getchar();
}
int main()
{
	//freopen("1.in","r",stdin);
	//freopen("1.out","w",stdout);
	scanf("%d",&n);
	up[1]= down[1]= 1;
	for (i= 2;i<=M;i++){
		if (vis[i]) continue;
		gcd(i,mo,x,y);
		gcd(i-1,mo,xx,yy);
		x= (x+mo)%mo;
		xx= (xx+mo)%mo;
		up[i]= (ll)(i-1)*x%mo;
		down[i]= (ll)i*xx%mo;
		up[i]= (up[i]+mo)%mo;
		down[i]= (down[i]+mo)%mo;
		j= i;
		while (j<=M){
			vis[j]= 1;
			L[j]++;
			A[j][L[j]]= i;
			j+= i;
		}
	}
	//if (n>1e5) return 0;
	a[0]= sum[0]= 1;
	for (i= 1;i<=n;i++){
		scanf("%d",&a[i]);
		sum[i]= (ll)sum[i-1]*a[i]%mo;
		C[i]= L[a[i]];
		for (j= 1;j<=C[i];j++)
			B[i][j]= A[a[i]][j];
	}
	scanf("%d",&q);
	base= 600;
	for (i= 1;i<=q;i++){
		scanf("%d%d",&x, &y);
		Q[i]= (query){x,y,i};
	}
	sort(Q+1,Q+q+1,cmpl);
	memset(vis,0,sizeof(vis));
	l= r= 0;
	now= 1;
	//if (n>1e5) return 0;
	for (i= 1;i<=q;i+= base){
		if (q>1e5){
			if (i>1e5) return 0;
		}
		m= min(i+base-1,q);
		sort(Q+i,Q+m+1,cmpr);
		rep(j,i,m){
			x= Q[j].l,y= Q[j].r;
			while (x<l){
				l--;
				//add(l);//
				rep(I,1,C[l]){
					int y= B[l][I];
					vis[y]++;
					if (vis[y]==1)
						now= now*up[y]%mo;
				}
			}
			while (l<x){
				//del(l);
				rep(I,1,C[l]){
					int y= B[l][I];
					vis[y]--;
					if (vis[y]==0)
						now= now*down[y]%mo;
				}
				l++;
			}
			while (y<r){
				//del(r);
				rep(I,1,C[r]){
					int y= B[r][I];
					vis[y]--;
					if (vis[y]==0)
						now= now*down[y]%mo;
				}
				r--;
			}
			while (r<y){
				r++;
				//add(r);//
				rep(I,1,C[r]){
					int y= B[r][I];
					vis[y]++;
					if (vis[y]==1)
						now= now*up[y]%mo;
				}
			}
			gcd(sum[l-1],mo,x,y);
			x= (x+mo)%mo;
			ans[Q[j].h]= now*sum[r]%mo*x%mo;
		}
	}
	for (i= 1;i<=q;i++)
		printf("%lld\n",ans[i]);
	return 0;
}


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#define ll long long
using namespace std;
const int maxn= 2e5+10,maxm= 1e6+10,M= 1e6,mo= 1e9+7;
struct query{
	int l,r,h;
}Q[maxn];
ll ans[maxn];
int A[maxm][10],L[maxm],vis[maxm];
int B[maxn][10],C[maxn];
int up[maxm],down[maxm],sum[maxn];
int a[maxn];
ll now;
int i,j,k,q,l,r,n,m,x,y,z,base,xx,yy,X,Y,I;
bool cmpl(query a,query b){
	return a.l<b.l||(a.l==b.l&&a.r<b.r);
}
bool cmpr(query a,query b){
	return a.r<b.r||(a.r==b.r&&a.l<b.l);
}
void gcd(int a,int b,int &x,int &y){
	if (!b){
		x= 1;
		y= 0;
		return;
	}
	gcd(b,a%b,x,y);
	int t= x;
	x= y;
	y= t-a/b*y;
}
int main()
{
	//freopen("1.in","r",stdin);
	//freopen("1.out","w",stdout);
	scanf("%d",&n);
	up[1]= down[1]= 1;
	for (i= 2;i<=M;i++){
		if (vis[i]) continue;
		gcd(i,mo,x,y);
		gcd(i-1,mo,xx,yy);
		x= (x+mo)%mo;
		xx= (xx+mo)%mo;
		up[i]= (ll)(i-1)*x%mo;
		down[i]= (ll)i*xx%mo;
		up[i]= (up[i]+mo)%mo;
		down[i]= (down[i]+mo)%mo;
		j= i;
		while (j<=M){
			vis[j]= 1;
			L[j]++;
			A[j][L[j]]= i;
			j+= i;
		}
	}
	a[0]= sum[0]= 1;
	for (i= 1;i<=n;i++){
		scanf("%d",&a[i]);
		sum[i]= (ll)sum[i-1]*a[i]%mo;
		C[i]= L[a[i]];
		for (j= 1;j<=C[i];j++)
			B[i][j]= A[a[i]][j];
	}
	scanf("%d",&q);
	base= 600;
	for (i= 1;i<=q;i++){
		scanf("%d%d",&x, &y);
		Q[i]= (query){x,y,i};
	}
	sort(Q+1,Q+q+1,cmpl);
	memset(vis,0,sizeof(vis));
	l= r= 0;
	now= 1;
	for (i= 1;i<=q;i+= base){
		if (q>1e5){
			//if (i>1e5) return 0;
		}
		m= min(i+base-1,q);
		sort(Q+i,Q+m+1,cmpr);
		for (j= i;j<=m;j++){
			x= Q[j].l,y= Q[j].r;
			while (x<l){
				l--;
				for (I= 1;I<=C[l];I++){
					int y= B[l][I];
					vis[y]++;
					if (vis[y]==1)
						now= now*up[y]%mo;
				}
			}
			while (l<x){
				for (I= 1;I<=C[l];I++){
					int y= B[l][I];
					vis[y]--;
					if (vis[y]==0)
						now= now*down[y]%mo;
				}
				l++;
			}
			while (y<r){
				for (I= 1;I<=C[r];I++){
					int y= B[r][I];
					vis[y]--;
					if (vis[y]==0)
						now= now*down[y]%mo;
				}
				r--;
			}
			while (r<y){
				r++;
				for (I= 1;I<=C[r];I++){
					int y= B[r][I];
					vis[y]++;
					if (vis[y]==1)
						now= now*up[y]%mo;
				}
			}
			gcd(sum[l-1],mo,x,y);
			x= (x+mo)%mo;
			ans[Q[j].h]= now*sum[r]%mo*x%mo;
		}
	}
	for (i= 1;i<=q;i++)
		printf("%lld\n",ans[i]);
	return 0;
}


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#define ll long long
using namespace std;
const int maxn= 2e5+10,maxm= 1e6+10,M= 1e6,mo= 1e9+7;
//const int maxn= 3e3,maxm= 1e3+10,M= 1e3,mo= 1e9+7;
struct query{
	int l,r,h;
}Q[maxn];
vector<int> B[maxn];
ll ans[maxn];
int inv[maxm],A[maxm][10],L[maxm],vis[maxm],sta[maxm];
int C[maxn];
int up[maxm],down[maxm],sum[maxn];
int a[maxn];
ll now;
int i,j,k,q,l,r,n,m,la,x,y,z,base;
bool cmpl(query a,query b){
	return a.l<b.l||(a.l==b.l&&a.r<b.r);
}
bool cmpr(query a,query b){
	return a.r<b.r||(a.r==b.r&&a.l<b.l);
}
void gcd(int a,int b,int &x,int &y){
	if (!b){
		x= 1;
		y= 0;
		return;
	}
	gcd(b,a%b,x,y);
	int t= x;
	x= y;
	y= t-a/b*y;
}
void add(int x){
	for (int i= 0;i<C[x];i++){
		int y= B[x][i];
		vis[y]++;
		if (vis[y]==1)
			now= now*up[y]%mo;
	}
}
void del(int x){
	for (int i= 0;i<C[x];i++){
		int y= B[x][i];
		vis[y]--;
		if (vis[y]==0)
			now= now*down[y]%mo;
	}
}
int main()
{
	//freopen("1.in","r",stdin);
	//freopen("1.out","w",stdout);
	gcd(1,mo,inv[1],y);
	up[1]= down[1]= 1;
	for (i= 2;i<=M;i++){
		gcd(i,mo,inv[i],y);
		inv[i]= (inv[i]+mo)%mo;
		up[i]= (ll)(i-1)*inv[i]%mo;
		down[i]= (ll)i*inv[i-1]%mo;
		if (vis[i]) continue;
		sta[++la]= i;
		j= i;
		while (j<=M){
			vis[j]= 1;
			L[j]++;
			A[j][L[j]]= i;
			j+= i;
		}
	}
	scanf("%d",&n);
	a[0]= sum[0]= 1;
	for (i= 1;i<=n;i++){
		scanf("%d",&a[i]);
		sum[i]= (ll)sum[i-1]*a[i]%mo;
		C[i]= L[a[i]];
		for (j= 1;j<=C[i];j++)
			B[i].push_back(A[a[i]][j]);
	}
	scanf("%d",&q);
	base= 500;
	for (i= 1;i<=q;i++){
		scanf("%d%d",&x, &y);
		Q[i]= (query){x,y,i};
	}
	sort(Q+1,Q+q+1,cmpl);
	memset(vis,0,sizeof(vis));
	l= r= 0;
	now= 1;
	for (i= 1;i<=q;i+= base){
		//for (j= 1;j<=la;j++) vis[sta[j]]= 0;
		m= min(i+base-1,q);
		sort(Q+i,Q+m+1,cmpr);
		for (j= i;j<=m;j++){
			x= Q[j].l,y= Q[j].r;
			if (x<l)
				for (k= x;k<l;k++)
					add(k);
			else for (k= l;k<x;k++)
					 del(k);
			if (y<r)
				for (k= y+1;k<=r;k++)
					del(k);
			else for (k= r+1;k<=y;k++)
					 add(k);
			l= x;r= y;
			gcd(sum[l-1],mo,x,y);
			ans[Q[j].h]= now*sum[r]%mo*x%mo;
		}
	}
	for (i= 1;i<=q;i++)
		printf("%lld\n",(ans[i]+mo)%mo);
	return 0;
}


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define ll long long
using namespace std;
const int maxn= 2e5+10,maxm= 1e6+10,M= 1e6,mo= 1e9+7;
struct query{
	int l,r,h;
}Q[maxn];
ll ans[maxn];
int A[maxm][10],L[maxm],vis[maxm];
int B[maxn][10],C[maxn];
int up[maxm],down[maxm],sum[maxn];
int a[maxn];
ll now;
int i,j,k,q,l,r,n,m,x,y,z,base,xx,yy,X,Y,I;
bool cmpl(query a,query b){
	return a.l<b.l||(a.l==b.l&&a.r<b.r);
}
bool cmpr(query a,query b){
	return a.r<b.r||(a.r==b.r&&a.l<b.l);
}
void gcd(int a,int b,int &x,int &y){
	if (!b){
		x= 1;
		y= 0;
		return;
	}
	gcd(b,a%b,x,y);
	int t= x;
	x= y;
	y= t-a/b*y;
}
void read(int &x){
	char c= getchar();x= 0;
	while (c<'0'||c>'9') c= getchar();
	while ('0'<=c&&c<='9')x= x*10+c-'0',c= getchar();
}
int main()
{
	//freopen("1.in","r",stdin);
	//freopen("1.out","w",stdout);
	scanf("%d",&n);
	up[1]= down[1]= 1;
	for (i= 2;i<=M;i++){
		if (vis[i]) continue;
		gcd(i,mo,x,y);
		gcd(i-1,mo,xx,yy);
		x= (x+mo)%mo;
		xx= (xx+mo)%mo;
		up[i]= (ll)(i-1)*x%mo;
		down[i]= (ll)i*xx%mo;
		up[i]= (up[i]+mo)%mo;
		down[i]= (down[i]+mo)%mo;
		j= i;
		while (j<=M){
			vis[j]= 1;
			L[j]++;
			A[j][L[j]]= i;
			j+= i;
		}
	}
	//if (n>1e5) return 0;
	a[0]= sum[0]= 1;
	for (i= 1;i<=n;i++){
		scanf("%d",&a[i]);
		sum[i]= (ll)sum[i-1]*a[i]%mo;
		C[i]= L[a[i]];
		for (j= 1;j<=C[i];j++)
			B[i][j]= A[a[i]][j];
	}
	scanf("%d",&q);
	base= 600;
	for (i= 1;i<=q;i++){
		scanf("%d%d",&x, &y);
		Q[i]= (query){x,y,i};
	}
	sort(Q+1,Q+q+1,cmpl);
	memset(vis,0,sizeof(vis));
	l= r= 0;
	now= 1;
	//if (n>1e5) return 0;
	for (i= 1;i<=q;i+= base){
		if (q>1e5){
			//if (i>1e5) return 0;
		}
		m= min(i+base-1,q);
		sort(Q+i,Q+m+1,cmpr);
		rep(j,i,m){
			x= Q[j].l,y= Q[j].r;
			while (x<l){
				l--;
				//add(l);//
				rep(I,1,C[l]){
					int y= B[l][I];
					vis[y]++;
					if (vis[y]==1)
						now= now*up[y]%mo;
				}
			}
			while (l<x){
				//del(l);
				rep(I,1,C[l]){
					int y= B[l][I];
					vis[y]--;
					if (vis[y]==0)
						now= now*down[y]%mo;
				}
				l++;
			}
			while (y<r){
				//del(r);
				rep(I,1,C[r]){
					int y= B[r][I];
					vis[y]--;
					if (vis[y]==0)
						now= now*down[y]%mo;
				}
				r--;
			}
			while (r<y){
				r++;
				//add(r);//
				rep(I,1,C[r]){
					int y= B[r][I];
					vis[y]++;
					if (vis[y]==1)
						now= now*up[y]%mo;
				}
			}
			gcd(sum[l-1],mo,x,y);
			x= (x+mo)%mo;
			ans[Q[j].h]= now*sum[r]%mo*x%mo;
		}
	}
	for (i= 1;i<=q;i++)
		printf("%lld\n",ans[i]);
	return 0;
}


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#define rep(i,a,n) for (int i= a;i<=n;i++)
#define ll long long
using namespace std;
const int maxn= 2e5+10,maxm= 1e6+10,M= 1e6,mo= 1e9+7;
struct query{
	int l,r,h;
}Q[maxn];
ll ans[maxn];
int A[maxm][10],L[maxm],vis[maxm];
int B[maxn][10],C[maxn];
int up[maxm],down[maxm],sum[maxn];
int a[maxn];
ll now;
int i,j,k,q,l,r,n,m,x,y,z,base,xx,yy,X,Y,I;
bool cmpl(query a,query b){
	return a.l<b.l||(a.l==b.l&&a.r<b.r);
}
bool cmpr(query a,query b){
	return a.r<b.r||(a.r==b.r&&a.l<b.l);
}
void gcd(int a,int b,int &x,int &y){
	if (!b){
		x= 1;
		y= 0;
		return;
	}
	gcd(b,a%b,x,y);
	int t= x;
	x= y;
	y= t-a/b*y;
}
int main()
{
	//freopen("1.in","r",stdin);
	//freopen("1.out","w",stdout);
	scanf("%d",&n);
	up[1]= down[1]= 1;
	for (i= 2;i<=M;i++){
		if (vis[i]) continue;
		gcd(i,mo,x,y);
		gcd(i-1,mo,xx,yy);
		x= (x+mo)%mo;
		xx= (xx+mo)%mo;
		up[i]= (ll)(i-1)*x%mo;
		down[i]= (ll)i*xx%mo;
		j= i;
		while (j<=M){
			vis[j]= 1;
			L[j]++;
			A[j][L[j]]= i;
			j+= i;
		}
	}
	//if (n>1e5) return 0;
	a[0]= sum[0]= 1;
	for (i= 1;i<=n;i++){
		scanf("%d",&a[i]);
		sum[i]= (ll)sum[i-1]*a[i]%mo;
		C[i]= L[a[i]];
		for (j= 1;j<=C[i];j++)
			B[i][j]= A[a[i]][j];
	}
	scanf("%d",&q);
	base= 600;
	for (i= 1;i<=q;i++){
		scanf("%d%d",&x, &y);
		Q[i]= (query){x,y,i};
	}
	sort(Q+1,Q+q+1,cmpl);
	memset(vis,0,sizeof(vis));
	l= r= 0;
	now= 1;
	for (i= 1;i<=q;i+= base){
		if (q>1e5){
			if (i>1e5) return 0;
		}
		m= min(i+base-1,q);
		sort(Q+i,Q+m+1,cmpr);
		//rep(j,i,m)
		for (j= i;j<=m;j++){
			x= Q[j].l,y= Q[j].r;
			while (x<l){
				l--;
				for (I= 1;I<=C[l];I++){
					int y= B[l][I];
					vis[y]++;
					if (vis[y]==1)
						now= now*up[y]%mo;
				}
			}
			while (l<x){
				//del(l);
				for (I= 1;I<=C[l];I++){
					int y= B[l][I];
					vis[y]--;
					if (vis[y]==0)
						now= now*down[y]%mo;
				}
				l++;
			}
			while (y<r){
				//del(r);
				for (I= 1;I<=C[r];I++){
					int y= B[r][I];
					vis[y]--;
					if (vis[y]==0)
						now= now*down[y]%mo;
				}
				r--;
			}
			while (r<y){
				r++;
				//add(r);//
				for (I= 1;I<=C[r];I++){
					int y= B[r][I];
					vis[y]++;
					if (vis[y]==1)
						now= now*up[y]%mo;
				}
			}
			gcd(sum[l-1],mo,x,y);
			ans[Q[j].h]= now*sum[r]%mo*x%mo;
		}
	}
	for (i= 1;i<=q;i++)
		printf("%lld\n",(ans[i]+mo)%mo);
	return 0;
}


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#define ll long long
using namespace std;
const int maxn= 2e5+10,maxm= 1e6+10,M= 1e6,mo= 1e9+7;
//const int maxn= 3e3,maxm= 1e3+10,M= 1e3,mo= 1e9+7;
struct query{
	int l,r,h;
}Q[maxn];
ll ans[maxn];
int inv[maxm],A[maxm][10],L[maxm],vis[maxm];
int B[maxn][10],C[maxn];
int up[maxm],down[maxm],sum[maxn];
int a[maxn];
ll now;
int i,j,k,q,l,r,n,m,x,y,z,base;
bool cmpl(query a,query b){
	return a.l<b.l||(a.l==b.l&&a.r<b.r);
}
bool cmpr(query a,query b){
	return a.r<b.r||(a.r==b.r&&a.l<b.l);
}
void gcd(int a,int b,int &x,int &y){
	if (!b){
		x= 1;
		y= 0;
		return;
	}
	gcd(b,a%b,x,y);
	int t= x;
	x= y;
	y= t-a/b*y;
}
void add(int x){
	for (int i= 1;i<=C[x];i++){
		int y= B[x][i];
		vis[y]++;
		if (vis[y]==1)
			now= now*up[y]%mo;
	}
}
void del(int x){
	for (int i= 1;i<=C[x];i++){
		int y= B[x][i];
		vis[y]--;
		if (vis[y]==0)
			now= now*down[y]%mo;
	}
}
void read(int &x){
	char c= getchar();x= 0;
	while (c<'0'||c>'9') c= getchar();
	while ('0'<=c&&c<='9')x= x*10+c-'0',c= getchar();
}
int main()
{
	//freopen("1.in","r",stdin);
	//freopen("1.out","w",stdout);
	gcd(1,mo,inv[1],y);
	up[1]= down[1]= 1;
	for (i= 2;i<=M;i++){
		gcd(i,mo,inv[i],y);
		inv[i]= (inv[i]+mo)%mo;
		up[i]= (ll)(i-1)*inv[i]%mo;
		down[i]= (ll)i*inv[i-1]%mo;
		if (vis[i]) continue;
		j= i;
		while (j<=M){
			vis[j]= 1;
			L[j]++;
			A[j][L[j]]= i;
			j+= i;
		}
	}
	scanf("%d",&n);
	if (n>1e5)
		return 0;
	a[0]= sum[0]= 1;
	for (i= 1;i<=n;i++){
		scanf("%d",&a[i]);
		//read(a[i]);
		sum[i]= (ll)sum[i-1]*a[i]%mo;
		C[i]= L[a[i]];
		for (j= 1;j<=C[i];j++)
			B[i][j]= A[a[i]][j];
	}
	scanf("%d",&q);
	base= 600;
	for (i= 1;i<=q;i++){
		//read(x);
		//read(y);
		scanf("%d%d",&x, &y);
		Q[i]= (query){x,y,i};
	}
	sort(Q+1,Q+q+1,cmpl);
	memset(vis,0,sizeof(vis));
	l= r= 0;
	now= 1;
	for (i= 1;i<=q;i+= base){
		if (q>1e5){
			if (i>1e5) return 0;
			}
		m= min(i+base-1,q);
		sort(Q+i,Q+m+1,cmpr);
		for (j= i;j<=m;j++){
			x= Q[j].l,y= Q[j].r;
			while (x<l){
				l--;
				add(l);
			}
			while (l<x){
				del(l);
				l++;
			}
			while (y<r){
				del(r);
				r--;
			}
			while (r<y){
				r++;
				add(r);
			}
			gcd(sum[l-1],mo,x,y);
			ans[Q[j].h]= now*sum[r]%mo*x%mo;
		}
	}
	for (i= 1;i<=q;i++)
		printf("%lld\n",(ans[i]+mo)%mo);
	return 0;
}


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#define ll long long
using namespace std;
const int maxn= 2e5+10,maxm= 1e6+10,M= 1e6,mo= 1e9+7;
//const int maxn= 3e3,maxm= 1e3+10,M= 1e3,mo= 1e9+7;
struct query{
	int l,r,h;
}Q[maxn];
ll ans[maxn];
int A[maxm][10],L[maxm],vis[maxm];
int B[maxn][10],C[maxn];
int up[maxm],down[maxm],sum[maxn];
int a[maxn];
ll now;
int i,j,k,q,l,r,n,m,x,y,z,base,xx,yy,X,Y,I;
bool cmpl(query a,query b){
	return a.l<b.l||(a.l==b.l&&a.r<b.r);
}
bool cmpr(query a,query b){
	return a.r<b.r||(a.r==b.r&&a.l<b.l);
}
void gcd(int a,int b,int &x,int &y){
	if (!b){
		x= 1;
		y= 0;
		return;
	}
	gcd(b,a%b,x,y);
	int t= x;
	x= y;
	y= t-a/b*y;
}
void add(int x){
	for (int i= 1;i<=C[x];i++){
		int y= B[x][i];
		vis[y]++;
		if (vis[y]==1)
			now= now*up[y]%mo;
	}
}
void del(int x){
	for (int i= 1;i<=C[x];i++){
		int y= B[x][i];
		vis[y]--;
		if (vis[y]==0)
			now= now*down[y]%mo;
	}
}
void read(int &x){
	char c= getchar();x= 0;
	while (c<'0'||c>'9') c= getchar();
	while ('0'<=c&&c<='9')x= x*10+c-'0',c= getchar();
}
int main()
{
	//freopen("1.in","r",stdin);
	//freopen("1.out","w",stdout);
	scanf("%d",&n);
	up[1]= down[1]= 1;
	for (i= 2;i<=M;i++){
		if (vis[i]) continue;
		gcd(i,mo,x,y);
		gcd(i-1,mo,xx,yy);
		x= (x+mo)%mo;
		xx= (xx+mo)%mo;
		up[i]= (ll)(i-1)*x%mo;
		down[i]= (ll)i*xx%mo;
		j= i;
		while (j<=M){
			vis[j]= 1;
			L[j]++;
			A[j][L[j]]= i;
			j+= i;
		}
	}
	//if (n>1e5) return 0;
	a[0]= sum[0]= 1;
	for (i= 1;i<=n;i++){
		scanf("%d",&a[i]);
		sum[i]= (ll)sum[i-1]*a[i]%mo;
		C[i]= L[a[i]];
		for (j= 1;j<=C[i];j++)
			B[i][j]= A[a[i]][j];
	}
	scanf("%d",&q);
	base= 600;
	for (i= 1;i<=q;i++){
		scanf("%d%d",&x, &y);
		Q[i]= (query){x,y,i};
	}
	sort(Q+1,Q+q+1,cmpl);
	memset(vis,0,sizeof(vis));
	l= r= 0;
	now= 1;
	for (i= 1;i<=q;i+= base){
		if (q>1e5){
			if (i>1e5+5e4) return 0;
		}
		m= min(i+base-1,q);
		sort(Q+i,Q+m+1,cmpr);
		for (j= i;j<=m;j++){
			x= Q[j].l,y= Q[j].r;
			while (x<l){
				l--;
				//add(l);//
				for (int i= 1;i<=C[l];i++){
					int y= B[l][i];
					vis[y]++;
					if (vis[y]==1)
						now= now*up[y]%mo;
				}
			}
			while (l<x){
				//del(l);
				for (int i= 1;i<=C[l];i++){
					int y= B[l][i];
					vis[y]--;
					if (vis[y]==0)
						now= now*down[y]%mo;
				}
				l++;
			}
			while (y<r){
				//del(r);
				for (int i= 1;i<=C[r];i++){
					int y= B[r][i];
					vis[y]--;
					if (vis[y]==0)
						now= now*down[y]%mo;
				}
				r--;
			}
			while (r<y){
				r++;
				//add(r);
				for (int i= 1;i<=C[r];i++){
					int y= B[r][i];
					vis[y]++;
					if (vis[y]==1)
						now= now*up[y]%mo;
				}
			}
			gcd(sum[l-1],mo,x,y);
			ans[Q[j].h]= now*sum[r]%mo*x%mo;
		}
	}
	for (i= 1;i<=q;i++)
		printf("%lld\n",(ans[i]+mo)%mo);
	return 0;
}


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define ll long long
using namespace std;
const int maxn= 2e5+10,maxm= 1e6+10,M= 1e6,mo= 1e9+7;
struct query{
	int l,r,h;
}Q[maxn];
ll ans[maxn];
int A[maxm][10],L[maxm],vis[maxm];
int B[maxn][10],C[maxn];
int up[maxm],down[maxm],sum[maxn];
int a[maxn];
ll now;
int i,j,k,q,l,r,n,m,x,y,z,base,xx,yy,X,Y,I;
bool cmpl(query a,query b){
	return a.l<b.l||(a.l==b.l&&a.r<b.r);
}
bool cmpr(query a,query b){
	return a.r<b.r||(a.r==b.r&&a.l<b.l);
}
void gcd(int a,int b,int &x,int &y){
	if (!b){
		x= 1;
		y= 0;
		return;
	}
	gcd(b,a%b,x,y);
	int t= x;
	x= y;
	y= t-a/b*y;
}
void read(int &x){
	char c= getchar();x= 0;
	while (c<'0'||c>'9') c= getchar();
	while ('0'<=c&&c<='9')x= x*10+c-'0',c= getchar();
}
int main()
{
	//freopen("1.in","r",stdin);
	//freopen("1.out","w",stdout);
	scanf("%d",&n);
	up[1]= down[1]= 1;
	for (i= 2;i<=M;i++){
		if (vis[i]) continue;
		gcd(i,mo,x,y);
		gcd(i-1,mo,xx,yy);
		x= (x+mo)%mo;
		xx= (xx+mo)%mo;
		up[i]= (ll)(i-1)*x%mo;
		down[i]= (ll)i*xx%mo;
		up[i]= (up[i]+mo)%mo;
		down[i]= (down[i]+mo)%mo;
		j= i;
		while (j<=M){
			vis[j]= 1;
			L[j]++;
			A[j][L[j]]= i;
			j+= i;
		}
	}
	//if (n>1e5) return 0;
	a[0]= sum[0]= 1;
	for (i= 1;i<=n;i++){
		scanf("%d",&a[i]);
		sum[i]= (ll)sum[i-1]*a[i]%mo;
		C[i]= L[a[i]];
		for (j= 1;j<=C[i];j++)
			B[i][j]= A[a[i]][j];
	}
	scanf("%d",&q);
	base= 600;
	for (i= 1;i<=q;i++){
		scanf("%d%d",&x, &y);
		Q[i]= (query){x,y,i};
	}
	sort(Q+1,Q+q+1,cmpl);
	memset(vis,0,sizeof(vis));
	l= r= 0;
	now= 1;
	//if (n>1e5) return 0;
	for (i= 1;i<=q;i+= base){
		if (q>1e5){
			if (i>1e5) return 0;
		}
		m= min(i+base-1,q);
		sort(Q+i,Q+m+1,cmpr);
		rep(j,i,m){
			x= Q[j].l,y= Q[j].r;
			while (x<l){
				l--;
				//add(l);//
				rep(I,1,C[l]){
					int y= B[l][I];
					vis[y]++;
					if (vis[y]==1)
						now= now*up[y]%mo;
				}
			}
			while (l<x){
				//del(l);
				rep(I,1,C[l]){
					int y= B[l][I];
					vis[y]--;
					if (vis[y]==0)
						now= now*down[y]%mo;
				}
				l++;
			}
			while (y<r){
				//del(r);
				rep(I,1,C[l]){
					int y= B[r][I];
					vis[y]--;
					if (vis[y]==0)
						now= now*down[y]%mo;
				}
				r--;
			}
			while (r<y){
				r++;
				//add(r);//
				rep(I,1,C[l]){
					int y= B[r][I];
					vis[y]++;
					if (vis[y]==1)
						now= now*up[y]%mo;
				}
			}
			gcd(sum[l-1],mo,x,y);
			x= (x+mo)%mo;
			ans[Q[j].h]= now*sum[r]%mo*x%mo;
		}
	}
	for (i= 1;i<=q;i++)
		printf("%lld\n",ans[i]);
	return 0;
}


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#define ll long long
using namespace std;
const int maxn= 2e5+10,maxm= 1e6+10,M= 1e6,mo= 1e9+7;
//const int maxn= 3e3,maxm= 1e3+10,M= 1e3,mo= 1e9+7;
struct query{
	int l,r,h;
}Q[maxn];
ll ans[maxn];
int inv[maxm],A[maxm][10],L[maxm],vis[maxm],sta[maxm];
int B[maxn][10],C[maxn];
int up[maxm],down[maxm],sum[maxn];
int a[maxn];
ll now;
int i,j,k,q,l,r,n,m,la,x,y,z,base;
bool cmpl(query a,query b){
	return a.l<b.l||(a.l==b.l&&a.r<b.r);
}
bool cmpr(query a,query b){
	return a.r<b.r||(a.r==b.r&&a.l<b.l);
}
void gcd(int a,int b,int &x,int &y){
	if (!b){
		x= 1;
		y= 0;
		return;
	}
	gcd(b,a%b,x,y);
	int t= x;
	x= y;
	y= t-a/b*y;
}
void add(int x){
	for (int i= 1;i<=C[x];i++){
		int y= B[x][i];
		vis[y]++;
		if (vis[y]==1)
			now= now*up[y]%mo;
	}
}
void del(int x){
	for (int i= 1;i<=C[x];i++){
		int y= B[x][i];
		vis[y]--;
		if (vis[y]==0)
			now= now*down[y]%mo;
	}
}
int main()
{
	freopen("1.in","r",stdin);
	freopen("1.out","w",stdout);
	gcd(1,mo,inv[1],y);
	up[1]= down[1]= 1;
	for (i= 2;i<=M;i++){
		gcd(i,mo,inv[i],y);
		inv[i]= (inv[i]+mo)%mo;
		up[i]= (ll)(i-1)*inv[i]%mo;
		down[i]= (ll)i*inv[i-1]%mo;
		if (vis[i]) continue;
		sta[++la]= i;
		j= i;
		while (j<=M){
			vis[j]= 1;
			L[j]++;
			A[j][L[j]]= i;
			j+= i;
		}
	}
	scanf("%d",&n);
	a[0]= sum[0]= 1;
	for (i= 1;i<=n;i++){
		scanf("%d",&a[i]);
		sum[i]= (ll)sum[i-1]*a[i]%mo;
		C[i]= L[a[i]];
		for (j= 1;j<=C[i];j++)
			B[i][j]= A[a[i]][j];
	}
	scanf("%d",&q);
	base= 600;
	for (i= 1;i<=q;i++){
		scanf("%d%d",&x, &y);
		Q[i]= (query){x,y,i};
	}
	sort(Q+1,Q+q+1,cmpl);
	memset(vis,0,sizeof(vis));
	l= r= 0;
	now= 1;
	for (i= 1;i<=q;i+= base){
		m= min(i+base-1,q);
		sort(Q+i,Q+m+1,cmpr);
		for (j= i;j<=m;j++){
			x= Q[j].l,y= Q[j].r;
			if (x<l)
				for (k= x;k<l;k++)
					add(k);
			else for (k= l;k<x;k++)
					 del(k);
			if (y<r)
				for (k= y+1;k<=r;k++)
					del(k);
			else for (k= r+1;k<=y;k++)
					 add(k);
			l= x;r= y;
			gcd(sum[l-1],mo,x,y);
			ans[Q[j].h]= now*sum[r]%mo*x%mo;
		}
	}
	for (i= 1;i<=q;i++)
		printf("%lld\n",(ans[i]+mo)%mo);
	return 0;
}


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#define ll long long
using namespace std;
const int maxn= 2e5+10,maxm= 1e6+10,M= 1e6,mo= 1e9+7;
//const int maxn= 3e3,maxm= 1e3+10,M= 1e3,mo= 1e9+7;
struct query{
	int l,r,h;
}Q[maxn];
ll ans[maxn];
int A[maxm][10],L[maxm],vis[maxm];
int B[maxn][10],C[maxn];
int up[maxm],down[maxm],sum[maxn];
int a[maxn];
ll now;
int i,j,k,q,l,r,n,m,x,y,z,base,xx,yy,X,Y,I;
bool cmpl(query a,query b){
	return a.l<b.l||(a.l==b.l&&a.r<b.r);
}
bool cmpr(query a,query b){
	return a.r<b.r||(a.r==b.r&&a.l<b.l);
}
void gcd(int a,int b,int &x,int &y){
	if (!b){
		x= 1;
		y= 0;
		return;
	}
	gcd(b,a%b,x,y);
	int t= x;
	x= y;
	y= t-a/b*y;
}
void add(int x){
	for (int i= 1;i<=C[x];i++){
		int y= B[x][i];
		vis[y]++;
		if (vis[y]==1)
			now= now*up[y]%mo;
	}
}
void del(int x){
	for (int i= 1;i<=C[x];i++){
		int y= B[x][i];
		vis[y]--;
		if (vis[y]==0)
			now= now*down[y]%mo;
	}
}
void read(int &x){
	char c= getchar();x= 0;
	while (c<'0'||c>'9') c= getchar();
	while ('0'<=c&&c<='9')x= x*10+c-'0',c= getchar();
}
int main()
{
	//freopen("1.in","r",stdin);
	//freopen("1.out","w",stdout);
	scanf("%d",&n);
	up[1]= down[1]= 1;
	for (i= 2;i<=M;i++){
		if (vis[i]) continue;
		gcd(i,mo,x,y);
		gcd(i-1,mo,xx,yy);
		x= (x+mo)%mo;
		xx= (xx+mo)%mo;
		up[i]= (ll)(i-1)*x%mo;
		down[i]= (ll)i*xx%mo;
		j= i;
		while (j<=M){
			vis[j]= 1;
			L[j]++;
			A[j][L[j]]= i;
			j+= i;
		}
	}
	//if (n>1e5) return 0;
	a[0]= sum[0]= 1;
	for (i= 1;i<=n;i++){
		scanf("%d",&a[i]);
		sum[i]= (ll)sum[i-1]*a[i]%mo;
		C[i]= L[a[i]];
		for (j= 1;j<=C[i];j++)
			B[i][j]= A[a[i]][j];
	}
	scanf("%d",&q);
	base= 605;
	for (i= 1;i<=q;i++){
		scanf("%d%d",&x, &y);
		Q[i]= (query){x,y,i};
	}
	sort(Q+1,Q+q+1,cmpl);
	memset(vis,0,sizeof(vis));
	l= r= 0;
	now= 1;
	for (i= 1;i<=q;i+= base){
		if (q>1e5){
			if (i>1e5+9e4+1) return 0;
		}
		m= min(i+base-1,q);
		sort(Q+i,Q+m+1,cmpr);
		for (j= i;j<=m;j++){
			x= Q[j].l,y= Q[j].r;
			while (x<l){
				l--;
				//add(l);//
				for (I= 1;I<=C[l];I++){
					int y= B[l][I];
					vis[y]++;
					if (vis[y]==1)
						now= now*up[y]%mo;
				}
			}
			while (l<x){
				//del(l);
				for (I= 1;I<=C[l];I++){
					int y= B[l][I];
					vis[y]--;
					if (vis[y]==0)
						now= now*down[y]%mo;
				}
				l++;
			}
			while (y<r){
				//del(r);
				for (I= 1;I<=C[r];I++){
					int y= B[r][I];
					vis[y]--;
					if (vis[y]==0)
						now= now*down[y]%mo;
				}
				r--;
			}
			while (r<y){
				r++;
				//add(r);//
				for (I= 1;I<=C[r];I++){
					int y= B[r][I];
					vis[y]++;
					if (vis[y]==1)
						now= now*up[y]%mo;
				}
			}
			gcd(sum[l-1],mo,x,y);
			ans[Q[j].h]= now*sum[r]%mo*x%mo;
		}
	}
	for (i= 1;i<=q;i++)
		printf("%lld\n",(ans[i]+mo)%mo);
	return 0;
}