#include <bits/stdc++.h>
#define ll long long
#define INF 1000000005
#define MOD 1000000007
#define EPS 1e-10
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define rrep(i,n) for(int i=(int)(n)-1;i>=0;--i)
#define srep(i,s,t) for(int i=(int)(s);i<(int)(t);++i)
#define each(a,b) for(auto& (a): (b))
#define all(v) (v).begin(),(v).end()
#define len(v) (int)(v).size()
#define zip(v) sort(all(v)),v.erase(unique(all(v)),v.end())
#define cmx(x,y) x=max(x,y)
#define cmn(x,y) x=min(x,y)
#define fi first
#define se second
#define pb push_back
#define show(x) cout<<#x<<" = "<<(x)<<endl
#define spair(p) cout<<#p<<": "<<p.fi<<" "<<p.se<<endl
#define sar(a,n) cout<<#a<<":";rep(pachico,n)cout<<" "<<a[pachico];cout<<endl
#define svec(v) cout<<#v<<":";rep(pachico,v.size())cout<<" "<<v[pachico];cout<<endl
#define svecp(v) cout<<#v<<":";each(pachico,v)cout<<" {"<<pachico.first<<":"<<pachico.second<<"}";cout<<endl
#define sset(s) cout<<#s<<":";each(pachico,s)cout<<" "<<pachico;cout<<endl
#define smap(m) cout<<#m<<":";each(pachico,m)cout<<" {"<<pachico.first<<":"<<pachico.second<<"}";cout<<endl

using namespace std;

typedef pair<int,int> P;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<P> vp;
typedef vector<string> vs;

const int MAX_N = 100005;

template<class _Key, class _Tp> class MapIterator;

template<class _Key, class _Tp> class Map {
private:
    using iterator = MapIterator<_Key, _Tp>;
    using data_type = pair<_Key, _Tp>;
    using aligned_pointer = typename aligned_storage<sizeof(data_type), alignof(data_type)>::type;
    friend MapIterator<_Key, _Tp>;
    struct node {
        node *_M_left, *_M_right, *_M_parent;
        aligned_pointer _data_ptr;
        node() noexcept : _M_left(nullptr), _M_right(nullptr), _M_parent(nullptr){}
        ~node(){ if(data_ptr()) data_ptr()->~data_type(); }
        inline data_type& data() noexcept {
            return *reinterpret_cast<data_type*>(&_data_ptr);
        }
        inline data_type* data_ptr() noexcept {
            return reinterpret_cast<data_type*>(&_data_ptr);
        }
        inline const _Key& get_key() noexcept { return data_ptr()->first; }
        inline void new_data(const data_type& data){
            new(&_data_ptr) data_type(data);
        }
        inline bool isRoot() const noexcept { return !_M_parent; }
        void rotate(const bool right) noexcept {
            node *p = _M_parent, *g = p->_M_parent;
            if(right){
                if((p->_M_left = _M_right)) _M_right->_M_parent = p;
                _M_right = p, p->_M_parent = this;
            }else{
                if((p->_M_right = _M_left)) _M_left->_M_parent = p;
                _M_left = p, p->_M_parent = this;
            }
            if(!(_M_parent = g)) return;
            if(g->_M_left == p) g->_M_left = this;
            if(g->_M_right == p) g->_M_right = this;
        }
    };
    node *root, *_M_header, *start;
    size_t _M_node_count;
    node *splay(node *u) noexcept {
        while(!(u->isRoot())){
            node *p = u->_M_parent, *gp = p->_M_parent;
            if(p->isRoot()){
                u->rotate((u == p->_M_left));
            }else{
                bool flag = (u == p->_M_left);
                if((u == p->_M_left) == (p == gp->_M_left)){
                    p->rotate(flag), u->rotate(flag);
                }else{
                    u->rotate(flag), u->rotate(!flag);
                }
            }
        }
        return root = u;
    }
    static node *increment(node *ver) noexcept {
        if(ver->_M_right){
            ver = ver->_M_right;
            while(ver->_M_left) ver = ver->_M_left;
        }else{
            node *nx = ver->_M_parent;
            while(ver == nx->_M_right) ver = nx, nx = nx->_M_parent;
            ver = nx;
        }
        return ver;
    }
    node *join(node *ver1, node *ver2, const node *ver) noexcept {
        while(ver2->_M_left) ver2 = ver2->_M_left;
        splay(ver2)->_M_left = ver1;
        return ver1 ? (ver1->_M_parent = ver2) : (start = ver2);
    }
    node *_find(const _Key& _key, bool push=false) noexcept {
        node *cur = nullptr, *nx = root;
        do {
            cur = nx;
            if(cur == _M_header || cur->get_key() > _key) nx = cur->_M_left;
            else if(cur->get_key() < _key) nx = cur->_M_right;
            else return splay(cur);
        }while(nx);
        if(!push) return _M_header;
        if(cur == _M_header || cur->get_key() > _key){
            nx = new node();
            nx->new_data(data_type(_key, _Tp()));
            cur->_M_left = nx, nx->_M_parent = cur;
            if(cur == start) start = nx;
            return _M_node_count++, splay(nx);
        }else{
            nx = new node();
            nx->new_data(data_type(_key, _Tp()));
            cur->_M_right = nx, nx->_M_parent = cur;
            return _M_node_count++, splay(nx);
        }
    }
    node *_insert(const data_type& data) noexcept {
        node *ver = new node();
        ver->new_data(data);
        node *cur = nullptr, *nx = root;
        do {
            cur = nx;
            if(cur == _M_header || cur->get_key() > data.first) nx = cur->_M_left;
            else nx = cur->_M_right;
        }while(nx);
        if(cur == _M_header || cur->get_key() > data.first){
            cur->_M_left = ver, ver->_M_parent = cur;
            if(cur == start) start = ver;
            return _M_node_count++, splay(ver);
        }else{
            cur->_M_right = ver, ver->_M_parent = cur;
            return _M_node_count++, splay(ver);
        }
    }
    node *_erase(node *root_ver){
        assert(root_ver != _M_header);
        if(root_ver->_M_left) root_ver->_M_left->_M_parent = nullptr;
        if(root_ver->_M_right) root_ver->_M_right->_M_parent = nullptr;
        node *res = join(root_ver->_M_left, root_ver->_M_right, root_ver);
        delete root_ver;
        return _M_node_count--, res;
    }
    node *_erase(const _Key& _key){
        node *ver = _find(_key);
        return _erase(ver);
    }
    node *_lower_bound(const _Key& _key) noexcept {
        node *cur = nullptr, *nx = root, *res = nullptr;
        do {
            cur = nx;
            if(cur == _M_header){ nx = cur->_M_left; continue; }
            else if(cur->get_key() >= _key){
                nx = cur->_M_left;
                if(!res || cur->get_key() <= res->get_key()) res = cur;
            }else nx = cur->_M_right;
        }while(nx);
        splay(cur);
        return res ? res : _M_header;
    }
    node *_upper_bound(const _Key& _key) noexcept {
        node *cur = nullptr, *nx = root, *res = nullptr;
        do {
            cur = nx;
            if(cur == _M_header){ nx = cur->_M_left; continue; }
            else if(cur->get_key() > _key){
                nx = cur->_M_left;
                if(!res || cur->get_key() <= res->get_key()) res = cur;
            }else nx = cur->_M_right;
        }while(nx);
        splay(cur);
        return res ? res : _M_header;
    }
    void clear_dfs(node *cur) noexcept {
        if(cur->_M_left) clear_dfs(cur->_M_left);
        if(cur->_M_right) clear_dfs(cur->_M_right);
        delete cur;
    }

public:
    Map() noexcept : _M_node_count(0){ root = _M_header = start = new node(); }
    // ~Map() noexcept { if(root) clear_dfs(root); }
    friend ostream& operator<< (ostream& os, Map& mp) noexcept {
        for(auto& val : mp) os << '{' << val.first << ',' << val.second << "} ";
        return os;
    }
    _Tp& operator[](const _Key& _key) noexcept { return _find(_key, true)->data_ptr()->second; }
    const _Tp& at(const _Key& _key){
        node *res = _find(_key);
        if(res == _M_header) __throw_out_of_range(__N("Map::at"));
        return res->data_ptr()->second;
    }
    size_t size() const noexcept { return _M_node_count; }
    bool empty() const noexcept { return size() == 0; }
    iterator begin() const noexcept { return iterator(start); }
    iterator end() const noexcept { return iterator(_M_header); }
    void clear(){ clear_dfs(root), _M_node_count = 0, root = _M_header = start = new node(); }
    iterator find(const _Key& _key){ return iterator(_find(_key)); }
    iterator insert(const data_type& data){ return iterator(_insert(data)); }
    iterator erase(const _Key& _key){ return iterator(_erase(_key)); }
    iterator erase(const iterator& itr){ return iterator(_erase(splay(itr.node_ptr))); }
    iterator lower_bound(const _Key& _key){ return iterator(_lower_bound(_key)); }
    iterator upper_bound(const _Key& _key){ return iterator(_upper_bound(_key)); }
};

template<class _Key, class _Tp>
class MapIterator {
private:
    friend Map<_Key, _Tp>;
    typename Map<_Key, _Tp>::node *node_ptr;
    using iterator_category = forward_iterator_tag;
    using value_type = pair<_Key, _Tp>;
    using difference_type = pair<_Key, _Tp>;
    using pointer = pair<_Key, _Tp>*;
    using reference = pair<_Key, _Tp>&;

private:
    MapIterator(typename Map<_Key, _Tp>::node *mp) noexcept : node_ptr(mp){}

public:
    MapIterator() noexcept : node_ptr(){}
    MapIterator(const MapIterator& itr) noexcept : node_ptr(itr.node_ptr){}
    MapIterator& operator=(const MapIterator& itr) & noexcept { return node_ptr = itr.node_ptr, *this; }
    MapIterator& operator=(const MapIterator&& itr) & noexcept { return node_ptr = itr.node_ptr, *this; }
    reference operator*() const { return node_ptr->data(); }
    pointer operator->() const { return node_ptr->data_ptr(); }
    MapIterator& operator++() noexcept { return node_ptr = Map<_Key, _Tp>::increment(node_ptr), *this; }
    MapIterator operator++(int) const noexcept { return MapIterator(Map<_Key, _Tp>::increment(this->node_ptr)); }
    bool operator==(const MapIterator& itr) const noexcept { return !(*this != itr); };
    bool operator!=(const MapIterator& itr) const noexcept { return node_ptr != itr.node_ptr; }
};

//0:red,1:blue
Map<string, Map<string,int> > mp[2];

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n;
    cin >> n;
    n *= 2;
    string s;
    cin >> s;
    rep(i,(1 << (n-n/2))){
        string red,blue;
        rep(j,n-n/2){
            if((i >> j) & 1){
                red.pb(s[j+n/2]);
            }else{
                blue.pb(s[j+n/2]);
            }
        }
        reverse(all(blue));
        if(len(red) <= len(blue)){
            mp[0][blue][red]++;
        }else{
            mp[1][red][blue]++;
        }
    }
    ll ans = 0;
    rep(i,(1 << n/2)){
        string red, blue;
        rep(j,n/2){
            if((i >> j) & 1){
                red.pb(s[j]);
            }else{
                blue.pb(s[j]);
            }
        }
        reverse(all(blue));
        if(len(red) >= len(blue)){
            ans += mp[0][red][blue];
        }else{
            ans += mp[1][blue][red];
        }
    }
    cout << ans << "\n";
    return 0;
}


Measured memory_bytes: 131328