#include "bits/stdc++.h"
#include <boost/multi_array.hpp>
#include <boost/optional.hpp>
#include <boost/range/irange.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/dynamic_bitset.hpp>
namespace adaptor = boost::adaptors;
using index_t = std::size_t;

namespace lib
{
	using graph_t = std::vector<std::set<index_t>>;
	template<class T>using weighted_graph_t = std::vector<std::map<index_t, T>>;

	struct max_t
	{
		template<class T>constexpr T operator()(T const& lhs, T const& rhs)const
		{
			return std::max(lhs, rhs);
		}
	};
	struct min_t
	{
		template<class T>constexpr T operator()(T const& lhs, T const& rhs)const
		{
			return std::min(lhs, rhs);
		}
	};

	constexpr max_t max;
	constexpr min_t min;

	template<class T>auto order_by(T func)
	{
		return [=](auto&& lhs, auto&& rhs)
		{
			return func(lhs) < func(rhs);
		};
	}

	template<class T>constexpr auto max_v = std::numeric_limits<T>::max();
	template<class T>constexpr auto min_v = std::numeric_limits<T>::min();

	template<class T>using p_queue = std::priority_queue<T, std::vector<T>, std::greater<>>;
}


template<char First, char Last>class create_rolling_hash_t
{
	static_assert(First <= Last);
	static constexpr std::uint64_t min = Last - First + 2;
	static constexpr std::uint64_t max = Last - First + 11;
	std::uniform_int_distribution<std::uint64_t> dist;
	std::mt19937 random;
	std::uint64_t base0, base1;
public:
	class modnum61_1
	{
		static const std::uint64_t mask30 = (1ULL << 30) - 1;
		static const std::uint64_t mask31 = (1ULL << 31) - 1;
		static const std::uint64_t mod = (1ULL << 61) - 1;

		std::uint64_t val;
	public:
		modnum61_1() = default;
		modnum61_1(std::uint64_t v) :val(v% mod)
		{

		}
		modnum61_1(std::int64_t v) :val()
		{
			if (v < 0)
			{
				v += (std::abs(v) / mod + 1) * mod;
			}
			val = v % mod;
		}
		modnum61_1(std::uint32_t v) :val(static_cast<std::uint64_t>(v))
		{

		}
		modnum61_1(std::int32_t v) :val(static_cast<std::int32_t>(v))
		{

		}

		auto& operator+=(modnum61_1 const& rhs)
		{
			val += rhs.val;
			val %= mod;
			return *this;
		}
		auto& operator-=(modnum61_1 const& rhs)
		{
			val += mod - rhs.val;
			val %= mod;
			return *this;
		}
		auto& operator*=(modnum61_1 const& rhs)
		{
			auto au = val >> 31;
			auto ad = val & mask31;
			auto bu = rhs.val >> 31;
			auto bd = rhs.val & mask31;
			auto mid = ad * bu + au * bd;
			auto midu = mid >> 30;
			auto midd = mid & mask30;
			val = (au * bu * 2 + midu + (midd << 31) + ad * bd);
			return *this;
		}
		auto&& operator*()const
		{
			return val;
		}

		friend auto operator+(modnum61_1 lhs, modnum61_1 rhs)
		{
			return lhs += rhs;
		}
		friend auto operator-(modnum61_1 lhs, modnum61_1 rhs)
		{
			return lhs -= rhs;
		}
		friend auto operator*(modnum61_1 lhs, modnum61_1 rhs)
		{
			return lhs *= rhs;
		}
		friend auto operator==(modnum61_1 lhs, modnum61_1 rhs)
		{
			return lhs.val == rhs.val;
		}
		friend auto operator!=(modnum61_1 lhs, modnum61_1 rhs)
		{
			return lhs.val != rhs.val;
		}
	};

	class rolling_hash
	{
		std::uint64_t base0, base1;
		modnum61_1 pow0, pow1, val0, val1;
		friend class create_rolling_hash_t;
		rolling_hash(std::uint64_t b0, std::uint64_t b1)
			:base0(b0), base1(b1),
			pow0(1), pow1(1), val0(), val1()
		{

		}
		void next()
		{
			pow0 *= base0;
			pow1 *= base1;
		}
	public:
		void push_back(char c)
		{
			auto v = c - First + 1;
			val0 *= base0;
			val0 += v;
			val1 *= base1;
			val1 += v;
			next();
		}
		void push_front(char c)
		{
			auto v = c - First + 1;
			val0 += v * pow0;
			val1 += v * pow1;
			next();
		}
		friend bool operator==(rolling_hash const& lhs, rolling_hash const& rhs)
		{
			return
				lhs.base0 == rhs.base0 &&
				lhs.base1 == rhs.base1 &&
				lhs.val0 == rhs.val0 &&
				lhs.val1 == rhs.val1;
		}
		friend bool operator!=(rolling_hash const& lhs, rolling_hash const& rhs)
		{
			return !(lhs == rhs);
		}
		friend bool operator<(rolling_hash const& lhs, rolling_hash const& rhs)
		{
			return
				std::make_pair(*lhs.val0, *lhs.val1) <
				std::make_pair(*rhs.val0, *rhs.val1);
		}
		friend std::ostream& operator<<(std::ostream& os, rolling_hash const& hash)
		{
			os << "(" << *hash.val0 << ", " << *hash.val1 << ")";
			return os;
		}
	};

	create_rolling_hash_t() :dist(min, max), random(std::random_device()()), base0(), base1()
	{
		change_base();
	}

	void change_base()
	{
		base0 = dist(random);
		base1 = dist(random);
	}

	rolling_hash create_hash()
	{
		return rolling_hash(base0, base1);
	}
};
typedef create_rolling_hash_t<'a', 'z'>::rolling_hash rolling_hash;

void Main()
{
	constexpr std::size_t X = 26;
	int N;
	std::cin >> N;
	create_rolling_hash_t<'a', 'z'> create;
	std::vector<std::pair<std::string, rolling_hash>> vec;
	std::map<rolling_hash, std::array<std::int64_t, X>> map;
	for (auto i : boost::irange(N))
	{
		auto hash = create.create_hash();
		std::string str;
		std::cin >> str;
		std::vector<rolling_hash> hashes;
		for (auto j : boost::irange(str.size()) | adaptor::reversed)
		{
			hashes.emplace_back(hash);
			hash.push_back(str[j]);
		}
		auto rev = hashes.rbegin();
		std::array<bool, X> flag{};
		for (auto j : boost::irange(str.size()))
		{
			flag[str[j] - 'a'] = true;
			for (auto k : boost::irange(X))
			{
				map[rev[j]][k] += flag[k];
			}
		}
		vec.emplace_back(std::move(str), rev[0]);
	}
	std::int64_t count = 0;
	for (auto&& [str, hash] : vec)
	{
		count += map[hash][str[0] - 'a'] - 1;
	}
	std::cout << count << std::endl;
}

int main()
{
	std::cin.tie(nullptr);
	std::ios_base::sync_with_stdio(false);
	std::cout << std::fixed << std::setprecision(15);
	Main();
}

Measured memory_bytes: 339304