#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;

using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vb = vector<bool>;
using vd = vector<double>;
using vs = vector<string>;

typedef tree<
ll,
null_type,
less<ll>,
rb_tree_tag,
tree_order_statistics_node_update>
ordered_set;
// ordered_set X;
// *X.find_by_order(i) = ith largest element (counting from zero)
// X.order_of_key(k) = number of items in X < k (strict lt)

constexpr double PI = atan(1)*4;

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    cout << setprecision(18);

    int N;
    ll L;
    cin >> N >> L;

    vll T(N);
    for (int i=0;i<N;i++) cin >> T[i];

    vd angs(N);
    for (int i=0;i<N;i++) angs[i] = (2*PI*T[i])/L;

    double ansx = 0.;
    double ansy = 0.;
    for (int i=0;i<N;i++) {
        for (int j=i+1; j<N; j++) {
            double nang = (angs[i] + angs[j]) / 2;
            int between = (j - i - 1);

            ansx += (N-2 - between)*cos(nang);
            ansy += (N-2 - between)*sin(nang);

            ansx += between*cos(nang + PI);
            ansy += between*sin(nang + PI);


        }
    }

    ansx *= 6.0/(N*(N-1)*(N-2));
    ansy *= 6.0/(N*(N-1)*(N-2));
    

    cout << ansx << " " << ansy << endl;

    return 0;
}