#include <bits/stdc++.h>
#define err(args...) {}
#ifdef DEBUG
#include "_debug.cpp"
#endif
using namespace std;
using ll = long long;
using ld = long double;
template <typename T> using lim = numeric_limits<T>;
template <typename T> istream& operator>>(istream& is, vector<T>& a) { for(T& x : a) { is >> x; } return is; }
template <typename X, typename Y> istream& operator>>(istream& is, pair<X, Y>& p) { return is >> p.first >> p.second; }
int get_need(string& s) {
    int x = 0, ans = 0;
    for(char c : s) {
        if(c == '(') {
            x += 1;
        } else if(x == 0) {
            ans += 1;
        } else {
            x -= 1;
        }
    }
    return ans;
}
char rev(char c) {
    return c == ')' ? '(' : ')';
}
int get_give(string s) {
    reverse(s.begin(), s.end());
    for(char& c : s) {
        c = rev(c);
    }
    return get_need(s);
}
bool balanced(string& s) {
    return get_need(s) == 0 and get_give(s) == 0;
}
template <typename T> struct monoid {
    const T identity;
    const function<T(T, T)> combine;
};
template <typename T> struct segtree {
    using Type = T;
    using DeltaType = T;
    const int size;
    vector<T> tree;
    const monoid<T> m;
    segtree(int size, const monoid<T>& m) : size(size), tree(2 * (size + 1), m.identity), m(m) {}
    void update(int i, T x) {
        for(tree[i += size] = x; i >>= 1; )
            tree[i] = m.combine(tree[i << 1], tree[(i << 1) | 1]);
    }
    T query(int a, int b, bool inclusive) {
        assert(a <= b);
        T ans_l = m.identity, ans_r = m.identity;
        for(a += size, b += size + inclusive; a < b; a >>= 1, b >>= 1) {
            if(a & 1) ans_l = m.combine(ans_l, tree[a++]);
            if(b & 1) ans_r = m.combine(tree[--b], ans_r);
        }
        return m.combine(ans_l, ans_r);
    }
    T query(int i) { return query(i, i, true); }
    friend ostream& operator<<(ostream& os, segtree& t) {
        os << "[";
        for(int i = 0; i <= t.size; i++) {
            if(i != 0) os << ", ";
            os << t.query(i);
        }
        return os << "]";
    }
};
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    vector<string> s(n);
    cin >> s;
    vector<int> need(n), give(n);
    segtree<pair<int, int>> st(1'000'000, {{lim<int>::min(), -1}, [](const auto& p1, const auto& p2) {
        return max(p1, p2);
    }});
    map<int, vector<int>> waiting_need;
    for(int i = 0; i < n; i++) {
        need[i] = get_need(s[i]);
        give[i] = get_give(s[i]);
        waiting_need[need[i]].push_back(i);
    }
    for(auto& [_, v] : waiting_need) {
        sort(v.begin(), v.end(), [&](int i, int j) {
            return give[i] < give[j];
        });
        st.update(need[v.back()], {give[v.back()], v.back()});
        v.pop_back();
    }
    vector<int> ans;
    int opened = 0;
    for(int i = 0; i < n; i++) {
        int j = st.query(0, opened, true).second;
        if(j == -1) {
            cout << "No" << endl;
            exit(0);
        }
        ans.push_back(j);
        opened -= need[j];
        opened += give[j];
        if(not waiting_need[need[j]].empty()) {
            int k = waiting_need[need[j]].back();
            st.update(need[k], {give[k], k});
            waiting_need[need[k]].pop_back();
        } else {
            st.update(need[j], {lim<int>::min(), -1});
        }
    }
    string t;
    for(int j : ans) {
        t += s[j];
    }
    cout << (balanced(t) ? "Yes" : "No") << endl;
    return 0;
}


Measured memory_bytes: 68636