A better version(still some bugs exists)