#include <bits/stdc++.h> // Thư viện tổng hợp, chứa vector, iostream, etc.
using namespace std;
 
// Hằng số modulo. Kết quả cuối cùng phải chia lấy dư cho số này.
const int MOD = 1e9 + 7;
 
// ======================================================================
// "CỖ MÁY" FWHT - Trái tim của thuật toán
// Hàm này thực hiện cả biến đổi xuôi và ngược.
// a: Mảng cần biến đổi (sẽ bị thay đổi trực tiếp).
// inverse: cờ điều khiển.
//   - false: Biến đổi xuôi (FWHT xuôi), dùng phép cộng.
//   - true: Biến đổi ngược (FWHT ngược), dùng phép trừ.
// ======================================================================
void fwht_or(vector<long long>& a, bool inverse) {
    int n = a.size(); // Kích thước mảng, luôn là lũy thừa của 2.
 
    // len: Kích thước của "một nửa nhóm" đang xét. Bắt đầu từ 1, 2, 4, ...
    for (int len = 1; len < n; len <<= 1) { // len <<= 1 tương đương len = len * 2
 
        // i: Điểm bắt đầu của các "nhóm lớn" (kích thước 2*len).
        // Nó nhảy qua từng nhóm lớn một.
        for (int i = 0; i < n; i += 2 * len) {
 
            // j: Vị trí tương ứng trong mỗi nửa nhóm.
            // Để ghép cặp phần tử thứ j của nửa đầu với phần tử thứ j của nửa sau.
            for (int j = 0; j < len; j++) {
 
                // u: Phần tử ở nửa đầu của nhóm.
                long long u = a[i + j];
 
                // v: Phần tử tương ứng ở nửa sau của nhóm.
                long long v = a[i + len + j];
 
                // Logic biến đổi cốt lõi
                if (!inverse) {
                    // Biến đổi xuôi: a' = a + b
                    // Nửa sau sẽ cộng dồn thông tin từ nửa đầu.
                    a[i + len + j] = (v + u) % MOD;
                } else {
                    // Biến đổi ngược: a = a' - b
                    // Nửa sau sẽ loại bỏ thông tin đã được cộng vào ở bước xuôi.
                    a[i + len + j] = (v - u + MOD) % MOD; // +MOD để đảm bảo kết quả không âm
                }
            }
        }
    }
}
 
 
int main() {
    // Tối ưu hóa tốc độ nhập xuất
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
 
    // ======================================================================
    // BƯỚC 0: ĐỌC DỮ LIỆU VÀ CHUẨN BỊ
    // ======================================================================
    int n;
    cin >> n; // Đọc kích thước mảng gốc
 
    // FWHT yêu cầu kích thước mảng phải là lũy thừa của 2.
    // Tìm N là lũy thừa của 2 nhỏ nhất >= n.
    int N = 1;
    while (N < n) {
        N *= 2;
    }
 
    // Tạo vector `a` với kích thước N. Các phần tử thừa (từ n đến N-1)
    // sẽ có giá trị 0, không ảnh hưởng đến tổng.
    vector<long long> a(N, 0);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
 
    // TRẠNG THÁI HIỆN TẠI: `a` chứa các giá trị gốc {a₀, a₁, ..., aₙ₋₁, 0, 0, ...}
 
 
    // ======================================================================
    // BƯỚC 1 & 2: KẾ HOẠCH & FWHT XUÔI
    // Kế hoạch: Tính mảng C. Để làm vậy, ta biến đổi `a` sang "thế giới song song".
    // ======================================================================
    fwht_or(a, false); // Gọi "cỗ máy" ở chế độ xuôi.
 
    // TRẠNG THÁI HIỆN TẠI: `a` đã bị biến đổi. Nó không còn chứa giá trị gốc.
    // Giờ đây nó chứa mảng `hat_a`, với a[k] = tổng các a_gốc[i] mà i là submask của k.
 
 
    // ======================================================================
    // BƯỚC 3: PHÉP NHÂN "THẦN KỲ"
    // Đây là "đường tắt" O(N) để thực hiện phép tích chập.
    // ======================================================================
    for (int i = 0; i < N; ++i) {
        a[i] = (a[i] * a[i]) % MOD;
    }
 
    // TRẠNG THÁI HIỆN TẠI: `a` bây giờ chứa mảng `hat_C`.
    // hat_C[k] = hat_a[k] * hat_a[k].
    // Đây là mảng C nhưng vẫn đang ở "thế giới song song".
 
 
    // ======================================================================
    // BƯỚC 4: FWHT NGƯỢC
    // Đưa kết quả từ "thế giới song song" trở về "thế giới thực".
    // ======================================================================
    fwht_or(a, true); // Gọi "cỗ máy" ở chế độ ngược.
 
    // TRẠNG THÁI HIỆN TẠI: `a` bây giờ chứa mảng `C`.
    // a[k] = C[k] = tổng của tất cả a_gốc[i] * a_gốc[j] mà i | j = k.
    // Chúng ta đã thành công tính được mảng trung gian quan trọng nhất.
 
 
    // ======================================================================
    // BƯỚC 5: TÍNH TỔNG TIỀN TỐ ĐỂ RA KẾT QUẢ CUỐI CÙNG
    // Từ mảng C, ta tính S(U) = C[0] + C[1] + ... + C[U].
    // ======================================================================
    vector<long long> result(n); // Vector để chứa n đáp án cuối cùng.
 
    // S(0) chính là C[0] (tức là a[0] hiện tại).
    if (n > 0) {
        result[0] = a[0];
    }
 
    // Vòng lặp tính các S(U) còn lại.
    // result[i] tương ứng với S(i).
    // S(i) = S(i-1) + C[i]
    for (int i = 1; i < n; ++i) {
        result[i] = (result[i - 1] + a[i]) % MOD;
    }
 
    // TRẠNG THÁI HIỆN TẠI: `result` chứa các đáp án S(0), S(1), ..., S(n-1).
 
 
    // ======================================================================
    // IN KẾT QUẢ
    // ======================================================================
    for (int i = 0; i < n; ++i) {
        cout << result[i] << (i == n - 1 ? "" : " ");
    }
    cout << endl;
 
    return 0;
}