// #define ONLINE_JUDGE

// Interactive problem solution template

#if defined(ONLINE_JUDGE)
#define _SECURE_SCL 0
#endif

#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <deque>
#include <set>
#include <map>
#include <functional>
#include <memory>
#include <cmath>
#include <climits>
#include <numeric>
#include <tuple>
#include <random>
#include <memory.h>
#include <stdint.h>

#if !defined(__GNUC__)
#else // !defined(__GNUC__)
#define _CrtDbgBreak() __builtin_trap()
#endif // !defined(__GNUC__)

#if defined(ONLINE_JUDGE)
#define LOCAL_TEST 0
#else
#define LOCAL_TEST 1
#endif

template<typename T1, typename T2> auto Endl(std::basic_ostream<T1, T2>& ostr) -> decltype(std::endl<T1, T2>(ostr)) {
    return std::endl<T1, T2>(ostr);
}

#if LOCAL_TEST
struct AssertsCounter
{
	AssertsCounter(): counter(0) {}
	~AssertsCounter() { std::cerr << Endl << "DIAG: " << (counter == 0 ? "OK" : "FAIL!!!") << " Asserts count: " << counter << Endl; }
	void Increment() { counter++; }
	uint32_t counter;
};
AssertsCounter g_assertsCounter;
#define LOCAL_ASSERT(expr) { if (!(expr)) {std::cerr << "ASSERT FAILED (" << __LINE__ << "): '" << #expr << "'" << Endl; g_assertsCounter.Increment(); _CrtDbgBreak(); } }
#define LOCAL_ASSERT_EQ(expr1, expr2) { if ((expr1) != (expr2)) {std::cerr << "ASSERT FAILED (" << __LINE__ << "): '" << #expr1 << "' == '" << #expr2 << "' (" << (expr1) << " vs " << (expr2) << "')" << Endl; g_assertsCounter.Increment(); _CrtDbgBreak(); } }
#else
volatile bool isLocalTestEnabled = 0;
#define LOCAL_ASSERT(expr)
#define LOCAL_ASSERT_EQ(expr1, expr2)
#endif

bool g_isLocalPrintEnabled = (bool)(LOCAL_TEST);
#define LOCAL_PRINT() if (!g_isLocalPrintEnabled) { } else std::cerr // << .. << ..

typedef std::string string8_t;
typedef long double ld_t;

typedef std::vector<size_t> vector_size_t;
typedef std::vector<uint8_t> vector_uint8_t;
typedef std::vector<int32_t> vector_int32_t;
typedef std::vector<uint32_t> vector_uint32_t;
typedef std::vector<int64_t> vector_int64_t;
typedef std::vector<uint64_t> vector_uint64_t;
typedef std::vector<string8_t> vector_string8_t;

typedef std::vector<vector_size_t> vector_2d_size_t;
typedef std::vector<vector_int32_t> vector_2d_int32_t;
typedef std::vector<vector_uint32_t> vector_2d_uint32_t;
typedef std::vector<vector_int64_t> vector_2d_int64_t;
typedef std::vector<vector_uint64_t> vector_2d_uint64_t;

typedef std::set<size_t> set_size_t;
typedef std::set<int32_t> set_int32_t;
typedef std::set<uint32_t> set_uint32_t;
typedef std::set<int64_t> set_int64_t;
typedef std::set<uint64_t> set_uint64_t;
typedef std::set<string8_t> set_string8_t;

typedef std::multiset<size_t> multiset_size_t;
typedef std::multiset<string8_t> multiset_string8_t;

// Auxiliary functions definition
//
template<typename T> void UpdateMin(T& a, const T b) {a = std::min(a, b);}
template<typename T> void UpdateMax(T& a, const T b) {a = std::max(a, b);}

const ld_t Pi = std::atan(1.0L) * 4.0L;
static const ld_t Eps = 1.0e-09;
template<typename T> bool IsEqual(const T a, const T b) { return std::abs(a - b) < Eps; }
template<typename T> bool IsGreater(const T a, const T b) { return a > b + Eps; }
template<typename T> bool IsLess(const T a, const T b) { return a + Eps < b; }
template<typename T> bool IsGreaterEqual(const T a, const T b) { return !IsLess(a, b); }
template<typename T> bool IsLessEqual(const T a, const T b) { return !IsGreater(a, b); }

template<typename T> string8_t ToStr(const T& val) { std::ostringstream ostr; ostr << val; return ostr.str(); }
template<typename T> bool FromStr(const string8_t& str, T& val) {std::istringstream istr(str); istr >> val; return !!istr; }
template<typename T> T FromStr(const string8_t& str) {T val = {}; std::istringstream istr(str); istr >> val; return val; }

template<typename ContainerType, typename ValueType> bool Contains(const ContainerType& c, const ValueType& v) { return c.find(v) != c.end(); }

uint64_t SafeAdd(uint64_t a, uint64_t b) { uint64_t M = std::numeric_limits<uint64_t>::max(); return a <= M - b ? a + b : M; }
uint64_t SafeMul(uint64_t a, uint64_t b) { uint64_t M = std::numeric_limits<uint64_t>::max(); return a <= M / b ? a * b : M; }

template<typename T> std::istream& operator>>(std::istream& ist, std::vector<T>& data)
{
	LOCAL_ASSERT(!!ist);
	for (size_t i = 0; i < data.size(); i++) { ist >> data[i]; }
	return ist;
}

template<typename T> T Read(std::istream& ist)
{
	LOCAL_ASSERT(!!ist);
	T val; ist >> val; return val;
}

template<typename T> std::ostream& operator<<(std::ostream& ost, const std::vector<T>& data)
{
	for (size_t i = 0; i < data.size(); i++) { if (i != 0) { ost << ' '; } ost << data[i]; }
	return ost;
}

struct IInteractor {
    // TODO: Declare interaction operations here
	virtual uint32_t GetSum(const uint32_t i, const uint32_t j) = 0;
};

class OnlineJudgeInteractor : public IInteractor {
	std::istream& ist;
	std::ostream& ost;
public:
	OnlineJudgeInteractor(std::istream& ist, std::ostream& ost): ist(ist), ost(ost) {
	}

    // TODO: Implement online judje interaction operations here
	virtual uint32_t GetSum(const uint32_t i, const uint32_t j) override {
		ost << "? " << (i + 1) << " " << (j + 1) << Endl;
        uint32_t s;
        ist >> s;
        return s;
	}
};

class LocalTestInteractor : public IInteractor {
	const vector_uint32_t values;
    std::ostream* const interactorLog;

public:
	LocalTestInteractor(const vector_uint32_t& values, std::ostream* const interactorLog)
        : values(values)
        , interactorLog(interactorLog) {
        if (interactorLog) {
            // TODO: dump initial information in order to be capable to use it in OnlineJudgeInteractor
            (*interactorLog) << values.size() << Endl;
        }
	}

	virtual uint32_t GetSum(const uint32_t i, const uint32_t j) override {
        const uint32_t s = values[i] + values[j];
        if (interactorLog) {
            // TODO: dump answer information in order to be capable to use it in OnlineJudgeInteractor
            (*interactorLog) << s << Endl;
        }
        return s;
	}
};

class Solver {
	IInteractor& Interactor;

public:
	Solver(IInteractor& interactor): Interactor(interactor) {
	}

    vector_uint32_t GetAnswer(const size_t n) {
        // TODO: insert solution implementation here
        vector_uint32_t ans(n);

        const uint32_t s01 = Interactor.GetSum(0, 1);
        const uint32_t s12 = Interactor.GetSum(1, 2);
        const uint32_t s20 = Interactor.GetSum(2, 0);

        const uint32_t s012 = (s01 + s12 + s20) / 2;
        ans[0] = s012 - s12;
        ans[1] = s012 - s20;
        ans[2] = s012 - s01;

        for (uint32_t i = 3; i < n; i++) {
            const uint32_t s = Interactor.GetSum(i - 1, i);
            ans[i] = s - ans[i - 1];
        }

        return ans;
    }
};

bool Solve(std::istream& ist, std::ostream& ost, const bool multipleTestMode, const bool useLocalTestInteractor, std::ostream* const interactorLog)
{
    // TODO: read initial input information, if needed
    size_t n;
	ist >> n;

	if (multipleTestMode && !ist)
		return false;

    std::unique_ptr<IInteractor> interactor;

    if (useLocalTestInteractor) {
	    if (multipleTestMode && !ist)
		    return false;

        // TODO: read hidden information for interactor
        vector_uint32_t a(n);
        ist >> a;

	    if (multipleTestMode && !ist)
		    return false;

	    interactor.reset(new LocalTestInteractor(a, interactorLog));
    } else {
        interactor.reset(new OnlineJudgeInteractor(ist, ost));
    }
    LOCAL_ASSERT(interactor.get());

	//
	LOCAL_PRINT() << Endl << "Next test" << Endl;
	Solver solver(*interactor);
	const vector_uint32_t ans = solver.GetAnswer(n);

    // TODO: output answer in a proper form
	ost << "! " << ans << Endl;

	return multipleTestMode;
}


void RunSolve(std::istream& ist, std::ostream& ost, const bool useLocalTestInteractor, std::ostream* const interactorLog)
{
#if !defined(ONLINE_JUDGE)
    const bool multipleTestMode = true;
	while(Solve(ist, ost, multipleTestMode, useLocalTestInteractor, interactorLog)) {};
#else
    Solve(ist, ost, false, false, nullptr);
#endif
}

int main(int argc, const char *argv[])
{
    bool useLocalTestInteractor = false;
    if (argc >= 2) {
        if (std::string(argv[1]) == "-t") {
            useLocalTestInteractor = true;
            LOCAL_PRINT() << "Using local interactor" << Endl;
        }
    }

    std::unique_ptr<std::ofstream> interactorLog;
    if (useLocalTestInteractor && argc >= 3) {
        const char* const logFileName = argv[2];
        LOCAL_PRINT() << "Using file '" << logFileName << "' for interactor input log saving" << Endl;
        interactorLog.reset(new std::ofstream(logFileName));
    }

	RunSolve(std::cin, std::cout, useLocalTestInteractor, interactorLog.get());
}